* back-end - access to :mode attribute for section and symbol-name
@ 2024-01-15 13:15 Garulfo
2024-01-16 18:39 ` Ihor Radchenko
0 siblings, 1 reply; 2+ messages in thread
From: Garulfo @ 2024-01-15 13:15 UTC (permalink / raw)
To: emacs-orgmode
[-- Attachment #1.1: Type: text/plain, Size: 770 bytes --]
Hi all,
I try to learn how to start a new back-end for ConTeXt
(https://wiki.contextgarden.net).
There is already a version based on ox-latex.el
(https://github.com/Jason-S-Ross/ox-context/)
but in order to contribute I wanted to learn the basics.
I started a first elisp script (attached).
For "ox-mycontext-section", I try to access the attribute ":mode" of the
section
in order to make the difference between "first-section" and "section".
I had to use "symbol-name" :
(let*
((section_mode (symbol-name (org-element-property :mode section))))
Questions :
1/ Is it the "org-mode" way to do ?
2/ What should I read to understand why "symbol-name" is needed, whereas
usually "org-element-property" just return the appropriate string.
Thanks
[-- Attachment #1.2: Type: text/html, Size: 1602 bytes --]
[-- Attachment #2: orgmode_export_backend_for_conTeXt_trial_v01.el --]
[-- Type: text/plain, Size: 7986 bytes --]
;; 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))
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: back-end - access to :mode attribute for section and symbol-name
2024-01-15 13:15 back-end - access to :mode attribute for section and symbol-name Garulfo
@ 2024-01-16 18:39 ` Ihor Radchenko
0 siblings, 0 replies; 2+ messages in thread
From: Ihor Radchenko @ 2024-01-16 18:39 UTC (permalink / raw)
To: Garulfo; +Cc: emacs-orgmode
Garulfo <garulfo@azules.eu> writes:
> For "ox-mycontext-section", I try to access the attribute ":mode" of the
> section
> in order to make the difference between "first-section" and "section".
>
> I had to use "symbol-name" :
>
> (let*
> ((section_mode (symbol-name (org-element-property :mode section))))
>
> Questions :
> 1/ Is it the "org-mode" way to do ?
:mode is an internal property set by the parser. I do not recommend
using it in your code.
Instead, you can check if a section is the first section like
(if (eq 'org-data (org-element-type (org-element-property :parent section)))
"First section"
"Ordinary section inside a heading")
or shorter (on the development version of Org mode)
(if (org-element-type-p (org-element-parent section) 'org-data)
"First section"
"Ordinary section inside a heading")
> 2/ What should I read to understand why "symbol-name" is needed, whereas
> usually "org-element-property" just return the appropriate string.
:mode property is set to the parser mode used to parse a given syntax
node. Its value is not a string but a symbol.
> (section_mode (symbol-name (org-element-property :mode section))))
> (pcase section_mode
> ("first-section" (concat "%\n% FIRST SECTION\n%\n"))
'first-section symbol is not equal to "first-section" string. You would
need
('first-section ...)
to match symbol without converting it to string manually.
--
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-01-16 18:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-15 13:15 back-end - access to :mode attribute for section and symbol-name Garulfo
2024-01-16 18:39 ` Ihor Radchenko
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).