Fórmulas en exportación de texto plano

8

Estoy tratando de encontrar una manera de exportar un documento Org con muchas fórmulas en texto plano, pero los resultados no son excelentes hasta ahora.

Lo que probé:

  1. pandoc - Básicamente, mantiene todas las matemáticas en LaTeX sin cambios, ni siquiera elimina el ambiente makrers.
  2. detex - no reemplaza los símbolos griegos (simplemente los elimina), hay artefactos en las fórmulas producidas (quedan símbolos de alineación, etc.)
  3. tex2mail - se ve divertido y muy difícil de leer, deja artefactos, marcadores ambientales, etc.
  4. catdvi - es el mejor hasta ahora, sin embargo, solo necesito que se ejecute en los fragmentos de LaTeX en el archivo Org, el resto del archivo se ve muy mal (sangría, títulos, etc.).
  5. hevea- Este programa es utilizado por texi2dvipara generar salida de texto. Realmente no funciona, la salida se ve muy extraña / algunas letras griegas se traducen a Unicode, otras no, la alineación es incorrecta ...

Probablemente podría escribir un backend especial para exportar primero todos los fragmentos de LaTeX a DVI y luego ejecutarlos catdvi, pero antes de llegar a él, ¿tal vez hay una manera más sencilla de hacerlo?

wvxvw
fuente
Si solo pudiéramos exportar el archivo con las matemáticas previsualizadas en modo org, eso haría el trabajo. Pero no sé si es fácil de hacer o no.
DJJ
@DJJ Estoy trabajando para asesorar a las funciones de back-end ASCII que manejan la exportación, espero tener algunos resultados por la noche.
wvxvw
¿Puedes aclarar cuál es tu salida deseada? No estoy seguro de cómo mejorarías en LaTeX para representar fórmulas en texto plano. ¿Qué hace catdvirealmente?
Tyler
@ Tyler catdvigenera Unicode + ASCII-art para representar gráficos DVI. Esto no es una mejora en LaTeX, pero es necesario para las personas que no pueden leer la fuente LaTeX / PDF o DVI no están disponibles en ese entorno (por ejemplo, cuando interactúan con un terminal de texto o envían correos electrónicos de solo texto).
wvxvw
@wvxvw Esa sería una característica bastante interesante. Que la fuerza esté con usted.
DJJ

Respuestas:

2

Entonces, aquí hay algo que se me ocurrió, pero aún no es perfecto. Hay dos problemas principales:

  1. catdvino se puede hacer que use subíndices y superíndices Unicode, en su lugar, coloca caracteres de tamaño normal en la línea de abajo y arriba, lo que hace que los bits LaTeX en línea se vean mal. También hay problemas relacionados, como la representación de \frac{}{}, \binom{}{}y en línea similar, donde aparecen en la misma línea y se desintegran completamente en el texto circundante.

  2. El código LaTeX multilínea es notablemente mejor, pero a veces catdviagrega líneas en blanco adicionales (es difícil saber si eliminarlas, pero podría procesar posteriormente la salida para eliminar las líneas en blanco).

A continuación se muestra el código que utilicé y algunos ejemplos generados:

(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)

Tenga en cuenta que también necesitará compilar catdvidesde las fuentes. También hay un pequeño problema al compilarlo: algunos archivos C usan una variable definida en un archivo de encabezado dependiente (normalmente instalado por separado) sin un const, mientras que el encabezado necesita que sea un const(fácilmente arreglado simplemente agregando el bit de declaración necesario). texi2dvidebe estar disponible para instalar desde el administrador de paquetes.


Alternativas para LaTeX en línea:

Estaba pensando en usar TeXel método de entrada, que puede usar caracteres de subíndice y superíndice Unicode, sin embargo, esto requeriría analizar y preprocesar el código LaTeX para alimentarlo al TeXmétodo de entrada.

Otra alternativa es tratar de usar el análisis AUCTeX para descifrar subíndices y superíndices, pero ambos exigen demasiado esfuerzo ... Es más fácil en este momento usar catdvifórmulas en línea y luego arreglar los subíndices / superíndices a mano.

(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)))

Ejemplos:

** 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.

Se traduce como

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.
wvxvw
fuente