Reduce duplication in latex functions
This commit is contained in:
parent
df2a90c9b8
commit
1feb3becc3
1 changed files with 62 additions and 90 deletions
152
anki-editor.el
152
anki-editor.el
|
@ -64,19 +64,6 @@
|
||||||
(require 'ox)
|
(require 'ox)
|
||||||
(require 'ox-html)
|
(require 'ox-html)
|
||||||
|
|
||||||
(defconst anki-editor-prop-note-type "ANKI_NOTE_TYPE")
|
|
||||||
(defconst anki-editor-prop-note-id "ANKI_NOTE_ID")
|
|
||||||
(defconst anki-editor-prop-exporter "ANKI_EXPORTER")
|
|
||||||
(defconst anki-editor-prop-deck "ANKI_DECK")
|
|
||||||
(defconst anki-editor-prop-tags "ANKI_TAGS")
|
|
||||||
(defconst anki-editor-prop-tags-plus (concat anki-editor-prop-tags "+"))
|
|
||||||
(defconst anki-editor-prop-failure-reason "ANKI_FAILURE_REASON")
|
|
||||||
(defconst anki-editor-buffer-html-output "*AnkiEditor HTML Output*")
|
|
||||||
(defconst anki-editor-org-tag-regexp "^\\([[:alnum:]_@#%]+\\)+$")
|
|
||||||
(defconst anki-editor-exporter-raw "raw")
|
|
||||||
(defconst anki-editor-exporter-default "default")
|
|
||||||
(defconst anki-editor-api-version 5)
|
|
||||||
|
|
||||||
(defgroup anki-editor nil
|
(defgroup anki-editor nil
|
||||||
"Customizations for anki-editor."
|
"Customizations for anki-editor."
|
||||||
:group 'org)
|
:group 'org)
|
||||||
|
@ -117,6 +104,8 @@ form entries."
|
||||||
|
|
||||||
;;; AnkiConnect
|
;;; AnkiConnect
|
||||||
|
|
||||||
|
(defconst anki-editor-api-version 5)
|
||||||
|
|
||||||
(cl-defun anki-editor--fetch (url
|
(cl-defun anki-editor--fetch (url
|
||||||
&rest settings
|
&rest settings
|
||||||
&key type data success error parser
|
&key type data success error parser
|
||||||
|
@ -246,95 +235,68 @@ The result is the path to the newly stored media file."
|
||||||
media-file-name))
|
media-file-name))
|
||||||
|
|
||||||
|
|
||||||
;;; Org Export Backend
|
;;; Org export backend
|
||||||
|
|
||||||
(defconst anki-editor--ox-anki-html-backend
|
(defconst anki-editor--ox-anki-html-backend
|
||||||
(if anki-editor-use-math-jax
|
(org-export-create-backend
|
||||||
(org-export-create-backend
|
:parent 'html
|
||||||
:parent 'html
|
:transcoders '((latex-fragment . anki-editor--ox-latex)
|
||||||
:transcoders '((latex-fragment . anki-editor--ox-latex-for-mathjax)
|
(latex-environment . anki-editor--ox-latex))))
|
||||||
(latex-environment . anki-editor--ox-latex-for-mathjax)))
|
|
||||||
(org-export-create-backend
|
|
||||||
:parent 'html
|
|
||||||
:transcoders '((latex-fragment . anki-editor--ox-latex)
|
|
||||||
(latex-environment . anki-editor--ox-latex)))))
|
|
||||||
|
|
||||||
(defconst anki-editor--ox-export-ext-plist
|
(defconst anki-editor--ox-export-ext-plist
|
||||||
'(:with-toc nil :anki-editor-mode t))
|
'(:with-toc nil :anki-editor-mode t))
|
||||||
|
|
||||||
(defun anki-editor--translate-latex-delimiters (latex-code)
|
(cl-macrolet ((with-table (table)
|
||||||
(catch 'done
|
`(cl-loop for delims in ,table
|
||||||
(let ((delimiter-map (list (list (cons (format "^%s" (regexp-quote "$$")) "[$$]")
|
collect
|
||||||
(cons (format "%s$" (regexp-quote "$$")) "[/$$]"))
|
(list (concat "^" (regexp-quote (cl-first delims)))
|
||||||
(list (cons (format "^%s" (regexp-quote "$")) "[$]")
|
(cl-second delims)
|
||||||
(cons (format "%s$" (regexp-quote "$")) "[/$]"))
|
(concat (regexp-quote (cl-third delims)) "$")
|
||||||
(list (cons (format "^%s" (regexp-quote "\\(")) "[$]")
|
(cl-fourth delims)))))
|
||||||
(cons (format "%s$" (regexp-quote "\\)")) "[/$]"))
|
|
||||||
(list (cons (format "^%s" (regexp-quote "\\[")) "[$$]")
|
|
||||||
(cons (format "%s$" (regexp-quote "\\]")) "[/$$]"))))
|
|
||||||
(matched nil))
|
|
||||||
(save-match-data
|
|
||||||
(dolist (pair delimiter-map)
|
|
||||||
(dolist (delimiter pair)
|
|
||||||
(when (setq matched (string-match (car delimiter) latex-code))
|
|
||||||
(setq latex-code (replace-match (cdr delimiter) t t latex-code))))
|
|
||||||
(when matched (throw 'done latex-code)))))
|
|
||||||
latex-code))
|
|
||||||
|
|
||||||
(defun anki-editor--translate-latex-delimiters-to-anki-mathjax-delimiters (latex-code)
|
(defconst anki-editor--native-latex-delimiters
|
||||||
(catch 'done
|
(with-table '(("$$" "[$$]"
|
||||||
(let ((delimiter-map (list (list (cons (format "^%s" (regexp-quote "$$")) "\\[")
|
"$$" "[/$$]")
|
||||||
(cons (format "%s$" (regexp-quote "$$")) "\\]"))
|
("$" "[$]"
|
||||||
(list (cons (format "^%s" (regexp-quote "$")) "\\(")
|
"$" "[/$]")
|
||||||
(cons (format "%s$" (regexp-quote "$")) "\\)"))))
|
("\\(" "[$]"
|
||||||
(matched nil))
|
"\\)" "[/$]")
|
||||||
(save-match-data
|
("\\[" "[$$]"
|
||||||
(dolist (pair delimiter-map)
|
"\\]" "[/$$]"))))
|
||||||
(dolist (delimiter pair)
|
|
||||||
(when (setq matched (string-match (car delimiter) latex-code))
|
|
||||||
(setq latex-code (replace-match (cdr delimiter) t t latex-code))))
|
|
||||||
(when matched (throw 'done latex-code)))))
|
|
||||||
latex-code))
|
|
||||||
|
|
||||||
(defun anki-editor--wrap-latex (content)
|
(defconst anki-editor--mathjax-delimiters
|
||||||
"Wrap CONTENT with Anki-style latex markers."
|
(with-table '(("$$" "\\["
|
||||||
(format "<p><div>[latex]</div>%s<div>[/latex]</div></p>" content))
|
"$$" "\\]")
|
||||||
|
("$" "\\("
|
||||||
|
"$" "\\)")))))
|
||||||
|
|
||||||
(defun anki-editor--wrap-latex-for-mathjax (content)
|
(defun anki-editor--translate-latex-fragment (latex-code)
|
||||||
"Wrap CONTENT for Anki's native MathJax support."
|
(let ((table (if anki-editor-use-math-jax
|
||||||
(format "<p>%s</p>" content))
|
anki-editor--mathjax-delimiters
|
||||||
|
anki-editor--native-latex-delimiters)))
|
||||||
|
(cl-loop for delims in table
|
||||||
|
for matches = (string-match (cl-first delims) latex-code)
|
||||||
|
when matches
|
||||||
|
do
|
||||||
|
(setq latex-code (replace-match (cl-second delims) t t latex-code))
|
||||||
|
(string-match (cl-third delims) latex-code)
|
||||||
|
(setq latex-code (replace-match (cl-fourth delims) t t latex-code))
|
||||||
|
until matches
|
||||||
|
finally return latex-code)))
|
||||||
|
|
||||||
(defun anki-editor--wrap-div (content)
|
(defun anki-editor--translate-latex-env (latex-code)
|
||||||
(format "<div>%s</div>" content))
|
(setq latex-code (replace-regexp-in-string "\n" "<br>" (org-html-encode-plain-text latex-code)))
|
||||||
|
(if anki-editor-use-math-jax
|
||||||
|
(concat "\\[<br>" latex-code "\\]")
|
||||||
|
(concat "[latex]<br>" latex-code "[/latex]")))
|
||||||
|
|
||||||
(defun anki-editor--ox-latex (latex _contents _info)
|
(defun anki-editor--ox-latex (latex _contents _info)
|
||||||
"Transcode LATEX from Org to HTML.
|
"Transcode LATEX from Org to HTML.
|
||||||
CONTENTS is nil. INFO is a plist holding contextual information."
|
CONTENTS is nil. INFO is a plist holding contextual information."
|
||||||
(let ((code (org-remove-indentation (org-element-property :value latex))))
|
(let ((code (org-remove-indentation (org-element-property :value latex))))
|
||||||
(setq code
|
(setq code (cl-ecase (org-element-type latex)
|
||||||
(pcase (org-element-type latex)
|
(latex-fragment (anki-editor--translate-latex-fragment code))
|
||||||
('latex-fragment (anki-editor--translate-latex-delimiters code))
|
(latex-environment (anki-editor--translate-latex-env code))))
|
||||||
('latex-environment (anki-editor--wrap-latex
|
|
||||||
(mapconcat #'anki-editor--wrap-div
|
|
||||||
(split-string (org-html-encode-plain-text code) "\n")
|
|
||||||
"")))))
|
|
||||||
|
|
||||||
(if anki-editor-break-consecutive-braces-in-latex
|
|
||||||
(replace-regexp-in-string "}}" "} } " code)
|
|
||||||
code)))
|
|
||||||
|
|
||||||
(defun anki-editor--ox-latex-for-mathjax (latex _contents _info)
|
|
||||||
"Transcode LATEX from Org to HTML.
|
|
||||||
CONTENTS is nil. INFO is a plist holding contextual information."
|
|
||||||
(let ((code (org-remove-indentation (org-element-property :value latex))))
|
|
||||||
(setq code
|
|
||||||
(pcase (org-element-type latex)
|
|
||||||
('latex-fragment (anki-editor--translate-latex-delimiters-to-anki-mathjax-delimiters code))
|
|
||||||
('latex-environment (anki-editor--wrap-latex-for-mathjax
|
|
||||||
(mapconcat #'anki-editor--wrap-div
|
|
||||||
(split-string (org-html-encode-plain-text code) "\n")
|
|
||||||
"")))))
|
|
||||||
|
|
||||||
(if anki-editor-break-consecutive-braces-in-latex
|
(if anki-editor-break-consecutive-braces-in-latex
|
||||||
(replace-regexp-in-string "}}" "} } " code)
|
(replace-regexp-in-string "}}" "} } " code)
|
||||||
code)))
|
code)))
|
||||||
|
@ -342,7 +304,6 @@ CONTENTS is nil. INFO is a plist holding contextual information."
|
||||||
(defun anki-editor--ox-html-link (oldfun link desc info)
|
(defun anki-editor--ox-html-link (oldfun link desc info)
|
||||||
"When LINK is a link to local file, transcodes it to html and stores the target file to Anki, otherwise calls OLDFUN for help.
|
"When LINK is a link to local file, transcodes it to html and stores the target file to Anki, otherwise calls OLDFUN for help.
|
||||||
The implementation is borrowed and simplified from ox-html."
|
The implementation is borrowed and simplified from ox-html."
|
||||||
|
|
||||||
(or (catch 'giveup
|
(or (catch 'giveup
|
||||||
(unless (plist-get info :anki-editor-mode)
|
(unless (plist-get info :anki-editor-mode)
|
||||||
(throw 'giveup nil))
|
(throw 'giveup nil))
|
||||||
|
@ -405,7 +366,18 @@ The implementation is borrowed and simplified from ox-html."
|
||||||
(funcall oldfun link desc info)))
|
(funcall oldfun link desc info)))
|
||||||
|
|
||||||
|
|
||||||
;;; Core Functions
|
;;; Core primitives
|
||||||
|
|
||||||
|
(defconst anki-editor-prop-note-type "ANKI_NOTE_TYPE")
|
||||||
|
(defconst anki-editor-prop-note-id "ANKI_NOTE_ID")
|
||||||
|
(defconst anki-editor-prop-exporter "ANKI_EXPORTER")
|
||||||
|
(defconst anki-editor-prop-deck "ANKI_DECK")
|
||||||
|
(defconst anki-editor-prop-tags "ANKI_TAGS")
|
||||||
|
(defconst anki-editor-prop-tags-plus (concat anki-editor-prop-tags "+"))
|
||||||
|
(defconst anki-editor-prop-failure-reason "ANKI_FAILURE_REASON")
|
||||||
|
(defconst anki-editor-org-tag-regexp "^\\([[:alnum:]_@#%]+\\)+$")
|
||||||
|
(defconst anki-editor-exporter-raw "raw")
|
||||||
|
(defconst anki-editor-exporter-default "default")
|
||||||
|
|
||||||
(cl-defstruct anki-editor-note
|
(cl-defstruct anki-editor-note
|
||||||
id model deck fields tags)
|
id model deck fields tags)
|
||||||
|
@ -812,7 +784,7 @@ same as how it is used by `M-RET'(org-insert-heading)."
|
||||||
(interactive)
|
(interactive)
|
||||||
(org-export-to-buffer
|
(org-export-to-buffer
|
||||||
anki-editor--ox-anki-html-backend
|
anki-editor--ox-anki-html-backend
|
||||||
anki-editor-buffer-html-output nil t nil t anki-editor--ox-export-ext-plist #'html-mode))
|
"*AnkiEditor HTML Output*" nil t nil t anki-editor--ox-export-ext-plist #'html-mode))
|
||||||
|
|
||||||
(defun anki-editor-convert-region-to-html ()
|
(defun anki-editor-convert-region-to-html ()
|
||||||
"Convert and replace region to HTML."
|
"Convert and replace region to HTML."
|
||||||
|
|
Loading…
Reference in a new issue