Mehrere Hauptmodi in einem Puffer (z. B. Python-Modus und LaTeX-Modus)

7

Mit dem LaTeX-Paket pythontex I kann man Python-Code in das Latex-Dokument einfügen, das ausgeführt (und auf Wunsch in Ihre Latex-Datei gedruckt) wird, wenn Sie Latex ausführen. Ich verwende Auctex zum Bearbeiten von Latexdateien. Das Bearbeiten des Python-Codes im Latex-Dokument ist jedoch etwas schmerzhaft, da sich der Puffer im Latex-Modus und nicht im Python-Modus befindet. Daher gibt es keine Hilfe für das korrekte Einrücken des Python-Codes und keine Syntaxhervorhebung .

Gibt es also eine vernünftige Möglichkeit, den Python-Modus mit dem Latex-Modus zu mischen? Zum Beispiel, dass der Puffer automatisch in den Python-Modus springt, wenn sich der Punkt in einem Python-Code befindet, der abgeschnitten wurde? Was muss ich meiner .emacs-Datei hinzufügen, damit sie funktioniert? Irgendwelche anderen Ideen?

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

\begin{document}

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

f()
\end{pycode}   

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

Beachten Sie, dass pythontexmehrere Umgebungen und Befehle hat , die pythoncode enthalten kann, zum Beispiel pycodeoder pyverbatimals Umgebungen oder \pycoder \pyals Befehle.

Schüler
quelle
1
Dies ist mit Quellblöcken einfach zu org-modebewerkstelligen (es wird auch TeX generiert), fügt jedoch zusätzlich zu LaTeX eine weitere Indirektionsebene hinzu und macht es manchmal schwierig, den generierten TeX-Code zu beeinflussen.
wvxvw
2
Das Polymode-Emacs-Paket kann dies tun. Sie müssen wahrscheinlich ein neues Backend schreiben, aber das soll einfach sein.
Ista
@Ista: Wie würden die relevanten Teile für Polymode aussehen (genau wie in JeanPierres Antwort für den mmm-Modus)?
Student
@student: Ich verwende kein Pythontex und habe kein Interesse daran, es nur zur Beantwortung dieser Frage einzurichten. Das Beste, was ich tun kann, ist, Sie auf die Polymode-Dokumentation unter github.com/vspinu/polymode/
Ista
In den Kommentaren einer anderen Frage gab es eine kurze Diskussion mit dem Ergebnis, dass diese Frage eine allgemeinere Überschrift erhalten sollte. Das macht die ausgezeichnete akzeptierte Antwort auf diese Frage zugänglicher.
Tobias

Antworten:

9

MMM-mode(mehrere Hauptmodi) scheint genau das zu sein, wonach Sie suchen. Es wird im Emacs-Wiki erwähnt . Sie müssen eine Submode-Klasse definieren, um LaTeX und Python zu mischen. Geben Sie dabei an, dass Python-Teile durch die pycodeLaTeX-Tags begrenzt werden. Das Hinzufügen von Folgendem zu Ihrer Init-Datei sollte dies tun:

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

Die Schlüsselwörter :frontund :backgeben reguläre Ausdrücke für Trennzeichen an. In den letzten beiden Zeilen wird darum gebeten, dass mmm-modedie latex-pythonKlasse standardmäßig in allen Puffern aktiviert wird, deren Hauptmodus ist latex-mode.

Weitere Optionen finden Sie in der Dokumentation (manuelles Aktivieren, basierend auf dem Dateinamen oder mit Dateivariablen).

Es gibt zwei Möglichkeiten, mehrere Trennzeichenpaare anzugeben. Erstens können mehrere Klassen in einer Gruppe verbunden werden . Anstatt die latex-pythonKlasse zu definieren, definieren wir sie unten als eine Gruppe, die die beiden Klassen enthält latex-python-envsund latex-python-cmds(selbst die Befehle \pyc{…}und \py{…}LaTeX erkennt ).

Zweitens kann jede Klasse mehr verschiedenen delimiter Paare angeben: Klasse latex-python-envsunterhalb beide erkennen pycodeund pyverbatimLaTeX ENVs ( ~1in :backin der ersten eingeklammerten Gruppe abgestimmt auf den Wert bezieht sich auf :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 "}")))

Damit Trennzeichen erkannt werden, müssen Sie mmm-parse-buffer( C-c % C-b) (oder mmm-parse-regionoder mmm-parse-blockdh ein paar Linien um den Punkt). Wenn Sie es gewohnt sind, LaTeX envs durch LaTeX-insert-environment( C-c C-e) einzufügen, kann es zweckmäßig sein, die Ausführung nach Abschluss zu empfehlenmmm-parse-block , damit MMM die gerade eingefügten Tags sofort erkennt:

(advice-add 'LaTeX-insert-environment ':after 
    '(lambda (env) (mmm-parse-block 2)))
Jean Pierre
quelle
Vielen Dank. Wie kann ich weitere Umgebungen und Befehle hinzufügen, die Python-Code enthalten können (z. B. \pycoder pyverbatim) ? Gibt es eine Möglichkeit, den mmm-Modus automatisch zu erkennen, wenn ich eine pycodeUmgebung einfüge ?
Student
Ich habe gerade festgestellt, dass TAB nicht wie erwartet funktioniert. Zum Beispiel: \begin{pycode} + ENTER + dann eine forSchleife einfügen , zB for i in range(0,10):+ ENTER + print(i)+ ENTER + \end{pycode}. Die EINGABETASTE nach der forZeile rückt diese Anweisung ein, print(i)funktioniert dies jedoch nicht für Sie?
Student
@student MMM muss aufgefordert werden, beide Trennzeichen zu überprüfen und anzuzeigen, damit der Submodus wirksam wird. Siehe aktualisierte Antwort. Lassen Sie mich wissen, wenn Sie immer noch in Schwierigkeiten sind.
JeanPierre
Danke für den Zusatz. In Bezug auf die Einrückung habe ich erneut anhand Ihrer Hinweise getestet und das beschriebene Problem wurde behoben. Es gibt jedoch weitere Einrückungsprobleme: Wenn Sie eine pycodeUmgebung einfügen , beabsichtigt der Latex-Modus diese automatisch und Sie müssen TAB explizit verwenden, um dies zu korrigieren. Ein anderes Problem tritt auf, wenn Sie Pycode in einer anderen Umgebung verwenden. Ich habe einen Screencast gemacht, um klar zu machen, was ich meine: expirebox.com/download/e348355feabb8bb5d8c8399b97bccdb8.html
Student
Funktioniert die oben vorgeschlagene Methode, mehrere Umgebungen einzuschließen, auch, wenn Sie auch die Befehle \pycund \pyabgleichen möchten ?
Student