Então, aqui está uma coisa que eu inventei, mas ainda não é perfeita. Existem dois problemas principais:
catdvi
não pode ser feito para usar subscritos e sobrescritos Unicode; em vez disso, coloca caracteres de tamanho normal na linha abaixo e acima, o que faz com que os bits inline do LaTeX pareçam ruins. Há também problemas relacionados, tais como a prestação de \frac{}{}
, \binom{}{}
e em linha semelhante, onde eles aparecem na mesma linha e completamente desintegrar-se em torno do texto.
O código multilinha do LaTeX é notavelmente melhor, mas às vezes catdvi
adiciona linhas em branco extras (é difícil saber se é para removê-las, mas eu poderia pós-processar a saída para remover as linhas em branco).
Abaixo está o código que usei e alguns exemplos gerados:
(defmacro by-backend (&rest body)
`(cl-case (when (boundp 'backend)
(org-export-backend-name backend))
,@body))
(defun my/org-latex-headers ()
(mapcar
(lambda (record) (plist-get (cl-second record) :value))
(cl-remove-if-not
(lambda (record)
(let* ((data (cl-second record))
(key (plist-get data :key)))
(or (string-equal key "LATEX_HEADER")
(string-equal key "LATEX_HEADER_EXTRA"))))
(org-element-map (org-element-parse-buffer) 'keyword 'identity))))
(defun my/org-latex-template-with-header (body)
(org-latex-template
body
`(:title ""
:exported-data ,(make-hash-table)
:language "latex"
:latex-classes ,org-latex-classes
:latex-class "article"
:latex-header ,(mapconcat 'identity (my/org-latex-headers) "\n"))))
(defun my/latex-to-ascii (latex &optional multiline)
(let* ((catdvi-buf (get-buffer-create "*catdvi-buf*"))
(tmpname (make-temp-file "catdvi" nil ".tex"))
(dviname (format "%s.dvi" (file-name-sans-extension tmpname)))
(template (my/org-latex-template-with-header latex)))
(with-current-buffer catdvi-buf (erase-buffer))
(with-temp-file tmpname
(insert template)
tmpname)
(call-process (executable-find "texi2dvi")
nil (get-buffer-create "*texi2dvi-buf*") nil
"-o" dviname tmpname)
(if multiline
(progn
(call-process (executable-find "catdvi") nil (list catdvi-buf nil) nil
"-e" "0" dviname)
(replace-regexp-in-string
;; removes page numbering and page break
"[\f\v\t\n ]*1[\f\n\t \\.]*\\'" ""
(with-current-buffer catdvi-buf (buffer-string))))
(progn
(call-process (executable-find "catdvi") nil (list catdvi-buf nil) nil
"-s" "-e" "0" dviname)
(org-trim
(replace-regexp-in-string
;; removes page numbering and page break
"1[\f\n\t \\.]*\\'" ""
(with-current-buffer catdvi-buf (buffer-string))))))))
(defun my/org-ascii-latex-fragment (orig latex-fragment contents info)
(when (plist-get info :with-latex)
(my/latex-to-ascii
(org-element-property :value latex-fragment))))
(defun my/org-ascii-latex-environment (orig latex-environment contents info)
(message "my/org-ascii-latex-environment")
(when (plist-get info :with-latex)
(org-ascii--justify-element
(my/latex-to-ascii
(org-remove-indentation (org-element-property :value latex-environment)) t)
latex-environment info)))
(advice-add 'org-ascii-latex-fragment :around 'my/org-ascii-latex-fragment)
(advice-add 'org-ascii-latex-environment :around 'my/org-ascii-latex-environment)
Observe que você também precisará compilar a catdvi
partir de fontes. Também há um pequeno problema em compilá-lo: algum arquivo C usa uma variável definida em um arquivo de cabeçalho dependente (normalmente instalado separadamente) sem um const
, enquanto o cabeçalho precisa ser um const
(facilmente corrigido apenas adicionando o bit de declaração necessário). texi2dvi
deve estar disponível para instalação a partir do gerenciador de pacotes.
Alternativas para o LaTeX embutido:
Eu estava pensando em usar o TeX
método de entrada, que pode usar caracteres subscritos e sobrescritos Unicode, no entanto, isso exigiria a análise e o pré-processamento do código LaTeX para alimentá-lo no TeX
método de entrada.
Outra alternativa é tentar usar a análise do AUCTeX para descobrir subscritos e sobrescritos, mas ambos exigem muito esforço ... No momento, é mais fácil usar catdvi
fórmulas embutidas e depois corrigir manualmente os subscritos / sobrescritos.
(defun my/prepare-tex-ime (input)
(cl-loop for paren in '("[]{}") do
(setq input (replace-regexp-in-string
(format "\\\\%s" paren) paren input)))
input)
(defun my/tex-ime-translate (input)
(with-temp-buffer
(set-input-method 'TeX)
(setq quail-current-key "")
(cl-loop for c across input do
(setq last-command-event c)
(call-interactively 'quail-self-insert-command))
(buffer-string)))
Exemplos:
** Problem 1
Prove that
#+HEADER: :exports results
#+HEADER: :results (by-backend (pdf "latex") (t "raw"))
#+BEGIN_SRC latex
\begin{align*}
L = \{w \in \{a, b, c, d\}^* \;|\; w=dv, v \in \{a, b, c\}^*,
\#_a(w) \cdot \#_c(w) < \#_b(w) \}
\end{align*}
#+END_SRC
is not regular.
Traduz para
1.1 Problem 1
─────────────
Prove that
∗ ∗
L = {w ∈ {a,b,c,d} | w = dv,v ∈ {a,b,c} ,# (w)·# (w) < # (w)}
a c b
is not regular.