fixed version of the attachment
;; open this file with command
;; emacs --no-splash -q -mm how_to_write_a_context_export_backend_v01.el
;; In "emacs-lisp" dropdown menu above, select "evaluate buffer"
;; then, a first Ctrl-c Ctrl-c will compile
;; finally, a second Ctrl-c Ctrl-c will bring you a pdf viewer
;; you can then read this document
;; ETAPE 0 ---------------------------------------------------------------------
;; Minimal cryptic config to use ConTeXt from emacs
(cua-mode t)
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
(require 'ox)
(setq ConTeXt-Mark-version "IV")
(use-package tex :ensure auctex)
(use-package context)
(setq TeX-view-program-selection '((output-pdf "PDF Viewer")))
(if (eq system-type 'gnu/linux)
(setq TeX-view-program-list '(("PDF Viewer" "okular %o"))))
(if (eq system-type 'windows-nt)
(setq TeX-view-program-list '(("PDF Viewer" "AcroRd32 %o"))))
(setq TeX-default-mode 'context-mode)
(add-hook 'ConTeXt-mode-hook
(lambda()
(setq TeX-command-default "ConTeXt Full")))
;; ETAPE 1 ---------------------------------------------------------------------
;; Create 2 new empty buffers: 1 for org input, 1 for tex output
;; Display them
(delete-other-windows)
(defun clean_before_demo (buffername)
(if (get-buffer buffername)
(kill-buffer buffername))
(generate-new-buffer buffername))
(setq demo_name_org "demo_file.org")
(setq demo_name_tex "demo_file.tex")
(clean_before_demo demo_name_org)
(clean_before_demo demo_name_tex)
(with-current-buffer demo_name_org (org-mode))
(display-buffer demo_name_org
'(display-buffer-in-side-window . ((side . right)
(slot . 0)
(window-width . 80))))
(with-current-buffer demo_name_tex (context-mode))
(display-buffer demo_name_tex
'(display-buffer-in-side-window . ((side . right)
(slot . 1)
(window-width . 80))))
;; ETAPE 2 ---------------------------------------------------------------------
;; Write basic content to have org input, and define a style file
(with-current-buffer demo_name_org (insert
"#+TITLE: Démonstration
#+CONTEXT_ENV: my-env
#+LANGUAGE: fr
* Formatage de texte
:PROPERTIES:
:CUSTOM_ID: sec:formatage texte
:END:
Pour mettre en évidence, il est possible de *mettre en gras*.
Il est possible aussi de /mettre en italique/.
* Images
:PROPERTIES:
:CUSTOM_ID: sec:images
:END:
Du texte avant.
#+CAPTION: Ceci est un glacier.
#+NAME: fig:glacier
#+ATTR_ORG: :width 100
[[./glacier.jpg]]
Du texte après.
* Liens et références
:PROPERTIES:
:CUSTOM_ID: sec:liens_et_references
:END:
Une référence à l'image [[fig:glacier]] en espérance que cela fonctionne.
Une second vers la section [[#sec:formatage texte]].
#+INCLUDE: \"include.org\"
"))
(clean_before_demo "include.org")
(with-current-buffer "include.org" (insert
"* Include
:PROPERTIES:
:CUSTOM_ID: sec:include
:END:
Et voici une seconde référence vers l'image [[fig:glacier]].
"))
(with-current-buffer "include.org"
(write-file "include.org"))
(clean_before_demo "my-env.tex")
(with-current-buffer "my-env.tex" (insert
"\\setuphead [section] [color=darkred,style=\\bfa]
\\setuptolerance [tolerant]
\\setupinteraction [state=start]
\\placebookmarks [chapter,section,subsection] [chapter,section]
\\setupinteractionscreen [option=bookmark]
\\setupwhitespace [medium]
\\setupbodyfont [palatino,12pt]
"))
(with-current-buffer "my-env.tex"
(write-file "my-env.tex"))
;; ETAPE 3 ---------------------------------------------------------------------
;; Define our export backend
(org-export-define-backend 'ox-mycontext
; for each kind of item, we are going to allocate a specific function
'((template . ox-mycontext-template)
(headline . ox-mycontext-headline)
(section . ox-mycontext-section)
(paragraph . ox-mycontext-paragraph)
(plain-text . ox-mycontext-plain-text)
(bold . ox-mycontext-bold)
(italic . ox-mycontext-italic)
(link . ox-mycontext-link))
; and we will need tp define specific option at global level
:options-alist '((:context-env "CONTEXT_ENV" nil nil newline)
(:language "LANGUAGE" nil nil newline)))
(defun ox-mycontext-template (contents info)
(let* ((context-env (mapconcat #'org-element-normalize-string
(list (plist-get info :context-env))))
(language (replace-regexp-in-string
"\n$" ""
(car (list (plist-get info :language))) )))
(concat "\\environment " context-env
"\\mainlanguage [" language "]\n\n"
"\\starttext\n\n"
contents
"\n"
"\\stoptext")))
(defun ox-mycontext-headline (headline contents info)
"Transcode a HEADLINE element from Org to ConTeXt.
CONTENTS holds the contents of the HEADLINE. INFO is a plist
holding contextual information."
contents)
(defun ox-mycontext-section (section contents info)
(let*
((parent (org-export-get-parent-element section))
(section_mode (symbol-name (org-element-property :mode section))))
(pcase section_mode
("first-section" (concat "%\n% FIRST SECTION\n%\n"))
("section"
(concat "%<S section org ======================================\n"
"\\startsection\n"
" [title={" (org-element-property :raw-value parent) "},\n"
" reference={" (org-element-property :CUSTOM_ID parent) "},\n"
" ]\n"
contents
"\\stopsection\n"
"%====================================== section org S>")))))
(defun ox-mycontext-paragraph (paragraph contents info)
(concat "%<P paragraphe org\n" contents "%P>"))
(defun ox-mycontext-plain-text (text info)
(when (member (org-element-type (org-element-property :parent text))
'(bold italic paragraph link))
text))
(defun ox-mycontext-bold (bold contents info)
(concat "\\bold{" contents "}"))
(defun ox-mycontext-italic (italic contents info)
(concat "\\italic{" contents "}"))
(defun ox-mycontext-link (link contents info)
(let*
((parent_attr_org
(org-export-read-attribute :attr_org
(org-export-get-parent-element link)))
(parent_caption
(car (org-export-get-caption (org-export-get-parent-element link))))
(parent_name (org-element-property :name
(org-export-get-parent-element link)))
(elem_prop_type (org-element-property :type link))
(elem_prop_path (org-element-property :path link))
)
(concat
(pcase elem_prop_type
("custom-id" (concat "\\in[" elem_prop_path "]")) ; or \\at{page}[]
("fuzzy" (concat "\\in[" elem_prop_path "]"))
("file" (concat "\\startplacefigure\n"
" [title={" parent_caption "},\n"
" reference={" parent_name "},\n"
" ]\n"
"\\externalfigure[" elem_prop_path "]"
"[width={"
(format "%s" (/ (string-to-number
(plist-get parent_attr_org :width ))
100.0 )) "\\textwidth}]"
"\n\\stopplacefigure"))))))
;; ETAPE 4 ---------------------------------------------------------------------
;; Define a command and apply to get the tex output buffer
(defun ox-mycontext-export ()
(interactive)
(org-export-to-buffer 'ox-mycontext demo_name_tex))
(with-current-buffer demo_name_org
(ox-mycontext-export))
(with-current-buffer demo_name_org
(write-file demo_name_org))
(with-current-buffer demo_name_tex
(write-file demo_name_tex))