Múltiples modos principales en un búfer (p. Ej., Modo python y modo LaTeX)

7

Usando el paquete LaTeX pythontex I, uno puede insertar el código python en el documento de látex que se ejecuta (e imprime en su archivo de látex si lo desea) si ejecuta látex. Utilizo auctex para editar archivos de látex, sin embargo, editar el código de python dentro del documento de látex es un poco doloroso ya que el búfer está en modo de látex y no en modo de pitón, por lo que no hay ayuda para la sangría adecuada del código de python y sin resaltado de sintaxis .

Entonces, ¿hay alguna forma razonable de mezclar el modo python con el modo latex? Por ejemplo, ¿que el búfer salta automáticamente al modo python si el punto está dentro de un código python cortado? ¿Qué debo agregar a mi archivo .emacs para que funcione? ¿Alguna otra idea?

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usepackage{pythontex}

\begin{document}

\begin{pycode}
print('test1')
def f( ):
    print('test2')

f()
\end{pycode}   

\pyc{f()}
\end{document}

Tenga en cuenta que pythontextiene múltiples entornos y comandos que pueden contener pythoncode, por ejemplo pycodeo pyverbatimcomo entornos \pyco \pycomo comandos.

estudiante
fuente
1
Esto es algo que es fácil de hacer con los org-modebloques fuente (también genera TeX), pero esto agrega otra capa de indirección sobre LaTeX, y a veces hace que sea difícil afectar el código TeX que se genera.
wvxvw
2
El paquete polymode emacs puede hacer esto. Probablemente tenga que escribir un nuevo backend, pero se supone que es fácil.
Ista
@Ista: ¿Cómo se verían las partes relevantes para el polimodo (al igual que en la respuesta de JeanPierre para el modo mmm)?
estudiante
@student: no uso pythontex, y no tengo ningún interés en configurarlo solo para responder a esta pregunta, así que lo mejor que puedo hacer es señalarle la documentación del polymode
Ista
Ha habido una breve discusión en los comentarios de otra pregunta con el resultado de que esta pregunta debería tener un título más general. Eso hace que la excelente respuesta aceptada de esta pregunta sea más accesible.
Tobias

Respuestas:

9

MMM-mode(múltiples modos principales) parece exactamente lo que estás buscando. Se menciona en la wiki de emacs . Debe definir una clase de submodo para mezclar LaTeX y python, especificando que las partes de Python están delimitadas por las pycodeetiquetas LaTeX. Agregar lo siguiente a su archivo init debería hacerlo:

(require 'mmm-auto)
(mmm-add-classes
 '((latex-python
    :submode python-mode
    :face mmm-default-submode-face
    :front "\\\\begin{pycode}\n"
    :back "\\\\end{pycode}\n")))

(setq mmm-global-mode 'maybe)
(mmm-add-mode-ext-class 'latex-mode nil 'latex-python)

Las palabras clave :fronty :backespecifican expresiones regulares para delimitadores. Las últimas dos líneas solicitan que mmm-modecon la latex-pythonclase se active por defecto en todos los buffers cuyo modo principal es latex-mode.

Consulte la documentación para otras opciones (activándola manualmente, según el nombre del archivo o con variables de archivo).

Hay dos formas de especificar varios pares de delimitadores. Primero, se pueden unir varias clases en un grupo . A continuación, en lugar de definir la latex-pythonclase, la definimos como un grupo que contiene las dos clases latex-python-envsy latex-python-cmds(que reconoce los comandos \pyc{…}y \py{…}LaTeX).

En segundo lugar, cada clase puede especificar varios pares de delimitadores: la clase a latex-python-envscontinuación reconocerá ambos pycodey pyverbatimLaTeX envs ( ~1en se :backrefiere al valor que coincide en el primer grupo entre paréntesis :front).

(mmm-add-group 'latex-python
 '((latex-python-envs
    :submode python-mode
    :face mmm-default-submode-face
    :front "\\\\begin{\\(pycode\\|pyverbatim\\)}\n"
    :back "\\\\end{~1}\n"
    :save-matches 1)

   (latex-python-cmds
    :submode python-mode
    :face mmm-default-submode-face
    :front "\\\\pyc?{"
    :back "}")))

Para que los delimitadores sean reconocidos necesita mmm-parse-buffer( C-c % C-b) (o mmm-parse-region, mmm-parse-blockes decir, algunas líneas alrededor del punto). Si está acostumbrado a insertar envios de LaTeX a través de LaTeX-insert-environment( C-c C-e), podría ser conveniente aconsejarle que se ejecute mmm-parse-blockcuando esté hecho, para que MMM reconozca de inmediato las etiquetas recién insertadas:

(advice-add 'LaTeX-insert-environment ':after 
    '(lambda (env) (mmm-parse-block 2)))
Jean Pierre
fuente
Gracias. ¿Cómo puedo agregar más entornos y comandos que pueden contener código python (por ejemplo \pyco pyverbatim)? ¿Hay alguna manera de hacer que el modo mmm detecte automáticamente si inserto un pycodeentorno?
estudiante
Me acabo de dar cuenta de que TAB no funciona como se esperaba. Por ejemplo: \begin{pycode} + ENTRAR + luego inserte un forbucle, por ejemplo, for i in range(0,10):+ ENTRAR + print(i)+ ENTRAR + \end{pycode}. ¿El ENTER después de la forlínea sangra esta declaración pero no print(i)funciona para usted?
estudiante
@student MMM necesita que se le pida que vuelva a analizar y vea ambos delimitadores para que el submodo esté vigente, vea la respuesta actualizada. Avísame si todavía estás en problemas.
JeanPierre
Gracias por la adicion. Con respecto a la sangría que probé nuevamente usando sus sugerencias y el problema descrito se solucionó. Sin embargo, existen problemas de sangría adicionales: en primer lugar, si inserta un pycodeentorno, el modo látex lo intenta automáticamente y tiene que usar TAB explícitamente para corregir esto, se produce otro problema, si usa pycode dentro de otro entorno. Hice un screencast para aclarar lo que quiero decir: expirebox.com/download/e348355feabb8bb5d8c8399b97bccdb8.html
estudiante
¿El método que sugirió anteriormente para incluir múltiples entornos también funciona si desea hacer coincidir también los comandos \pycy \py?
estudiante