Vor einiger Zeit habe ich bei Quora die Frage beantwortet: 
Wie kann ich 
mit den Vorlesungsskripten in Mathematik auf LaTeX Schritt halten? Dort erklĂ€rte ich meinen Notizen-Workflow in LaTeX mit Vim und Inkscape (fĂŒr Zeichnungen). Aber seitdem hat sich viel geĂ€ndert, deshalb möchte ich mehrere Blog-BeitrĂ€ge mit einer Beschreibung des neuen Prozesses veröffentlichen. Dies ist der erste Artikel.
Ich habe im zweiten Semester eines Mathematikkurses angefangen, mit LaTeX Notizen zu machen, und seitdem habe ich ĂŒber 1700 Seiten geschrieben. Hier einige Beispiele, wie die Zusammenfassung aussieht:



Diese Notizen, einschlieĂlich Zeichnungen, werden direkt in der Vorlesung erstellt und anschlieĂend nicht bearbeitet. Um Abstracts effizient in LaTeX zu schreiben, mĂŒssen vier Regeln befolgt werden:
- Das Schreiben von Text und Formeln in LaTeX sollte so schnell sein wie das Schreiben eines Dozenten an die Tafel: Die Verzögerung ist nicht akzeptabel.
 
- Das Zeichnen von Illustrationen sollte fast so schnell sein wie das des Dozenten.
 
- Das Verwalten von Notizen, dh das HinzufĂŒgen von Notizen, das Anordnen aller Notizen, die letzten beiden Vorlesungen, das Suchen von Notizen usw. sollte schnell und einfach sein.
 
- Es sollte möglich sein, PDF-Dokumente mit LaTeX zu kommentieren, wenn ich eine Notiz mit einem PDF-Dokument schreiben möchte.
In diesem Artikel geht es um den ersten Punkt: Notizen zu LaTeX machen.
Vim und LaTeX
Um Text und mathematische Formeln auf LaTeX zu schreiben, verwende ich Vim. Dies ist ein leistungsstarker Allzweck-Texteditor, der in hohem MaĂe erweiterbar ist. Ich benutze es, um Code, LaTeX, Markdown-Text ... im Allgemeinen alle Texte zu schreiben. Er hat eine ziemlich steile Lernkurve, aber wenn Sie die Basis beherrschen, ist es bereits schwierig, ohne die ĂŒblichen Tastenkombinationen zum Editor zurĂŒckzukehren. So sieht mein Bildschirm aus, wenn ich ein LaTeX-Dokument bearbeite:

Auf der linken Seite befindet sich Vim und auf der rechten Seite der 
Zathura PDF-Viewer, der auch TastaturkĂŒrzel im Vim-Stil unterstĂŒtzt. Ich arbeite in Ubuntu mit dem 
bspwm Window Manager. Als Plugin hat LaTeX 
vimtex installiert. Es bietet Syntaxhervorhebung, Inhaltsverzeichnis, Synctex usw. Mit dem 
vim-plug habe ich es wie folgt konfiguriert:
Plug 'lervag/vimtex'
let g:tex_flavor='latex'
let g:vimtex_view_method='zathura'
let g:vimtex_quickfix_mode=0
set conceallevel=1
let g:tex_conceal='abdmg'Die letzten beiden Zeilen passen die Verkleidung an. Dies ist eine Funktion, bei der der LaTeX-Code ersetzt wird oder unsichtbar wird, wenn sich der Cursor nicht in dieser Zeile befindet. Wenn Sie 
\ [ , 
\] , 
$ ausblenden, sind sie nicht so auffĂ€llig, wodurch Sie einen besseren Ăberblick ĂŒber das Dokument erhalten. Diese Funktion ersetzt auch 
\bigcap durch 
â© , 
\in durch 
â usw., wie in der Animation gezeigt:

Mit dieser Einstellung können Sie die Aufgabe erfĂŒllen: Schreiben Sie auf LaTeX so schnell, wie ein Dozent an die Tafel schreibt. Hier kommen Schnipsel ins Spiel.
Schnipsel
Was ist ein Ausschnitt?
Ein Snippet ist ein kurzes StĂŒck wiederverwendbaren Textes, das von einem anderen Text aufgerufen wird. Wenn Sie beispielsweise ein Zeichen eingeben und die Tabulatortaste drĂŒcken, wird das Wortzeichen zu einer Signatur:

Snippets können dynamisch sein: Wenn ich 
today tippe und die 
Tab drĂŒcke, wird das Wort 
today durch das aktuelle Datum ersetzt, und das 
box Tab wird zu einem Feld, dessen GröĂe automatisch zunimmt.


Sie können sogar ein Snippet in einem anderen verwenden:

Erstellen von Snippets mit UltiSnips
Um Snippets zu steuern, verwende ich das 
UltiSnips- Plugin. Hier ist seine Konfiguration:
 Plug 'sirver/ultisnips' let g:UltiSnipsExpandTrigger = '<tab>' let g:UltiSnipsJumpForwardTrigger = '<tab>' let g:UltiSnipsJumpBackwardTrigger = '<s-tab>' 
Code fĂŒr das Snippet- 
sign :
 snippet sign "Signature" Yours sincerely, Gilles Castel endsnippet 
Bei dynamischen Snippets können Sie den Code zwischen die AnfĂŒhrungszeichen setzen. Dieser Code wird ausgefĂŒhrt, wenn das Snippet erweitert wird. Hier habe ich bash verwendet, um das aktuelle Datum zu formatieren: 
date + %F snippet today "Date" `date +%F` endsnippet 
Innerhalb des 
`!p ... ` -Blocks können Sie in Python schreiben. Schauen Sie sich den Code fĂŒr das 
box Snippet an:
 snippet box "Box" `!p snip.rv = 'â' + 'â' * (len(t[1]) + 2) + 'â'` â $1 â `!p snip.rv = 'â' + 'â' * (len(t[1]) + 2) + 'â'` $0 endsnippet 
Anstelle dieses Codes wird der Wert der Variablen 
snip.rv in das Dokument eingefĂŒgt. Innerhalb der Blöcke haben Sie Zugriff auf den aktuellen Status des Snippets. Beispiel: 
t[1] entspricht der Position der ersten Registerkarte, 
fn aktuellen Dateinamen usw.
LaTeX-Snippets
Snippets beschleunigen die Arbeit erheblich, insbesondere einige der komplexeren Snippets. Beginnen wir mit dem einfachsten.
Die Umwelt
Um eine Umgebung einzufĂŒgen, geben Sie am Anfang der Zeile 
beg . Dann der Name der Umgebung, der sich im Befehl 
\end{} widerspiegelt. Durch DrĂŒcken der 
Tab der Cursor eingefĂŒgt.

Der Code lautet wie folgt:
 snippet beg "begin{} / end{}" bA \begin{$1} $0 \end{$1} endsnippet 
Das Symbol 
b bedeutet, dass ein solches Snippet nur am Anfang einer Zeile funktioniert. 
A bedeutet automatische Erweiterung, dh Sie mĂŒssen nicht die 
Tab drĂŒcken. Tabs, auf die Sie durch DrĂŒcken von 
Tab und 
Shift + 
Tab werden als 
$1 , 
$2 , ... und letzteres als 
$0 .
Inline- und Anzeigeformeln
Die beiden am hÀufigsten verwendeten Snippets sind 
mk und 
dm , die den Mathematikmodus auslösen. Die erste fĂŒr Inline-Formeln, die zweite fĂŒr angezeigte.

Intelligentes Formel-Snippet: Er weiĂ, wann ein Leerzeichen nach dem Dollarzeichen eingefĂŒgt werden muss. Wenn ich unmittelbar nach dem SchlieĂen von $ mit der Eingabe eines Wortes beginne, wird ein Leerzeichen hinzugefĂŒgt. Wenn ich jedoch ein anderes Zeichen eingebe, wird kein Leerzeichen hinzugefĂŒgt, wie im Fall von '$ p $ -Wert'.

Der Code fĂŒr dieses Snippet lautet:
 snippet mk "Math" wA $${1}$`!p if t[2] and t[2][0] not in [',', '.', '?', '-', ' ']: snip.rv = ' ' else: snip.rv = '' `$2 endsnippet 
W am Ende der ersten Zeile bedeutet, dass sich das Snippet nur an Wortgrenzen ausdehnt. Daher 
hellomk beispielsweise 
hellomk nicht und 
hello mk funktioniert nicht.
Das Snippet fĂŒr die angezeigten Formeln ist einfacher, aber auch sehr praktisch. Die Gleichungen enden immer mit einem Punkt.

 <snippet dm "Math" wA \[ $1 .\] $0 endsnippet 
Tiefgestellte und hochgestellte Zeichen
Ein weiteres nĂŒtzliches Snippet ist fĂŒr Indizes. Es Ă€ndert 
a1 in 
a_1 und 
a_12 in 
a_{12} .

Der Code fĂŒr dieses Snippet verwendet einen regulĂ€ren Ausdruck als Auslöser. Es erweitert das Fragment, wenn Sie ein Zeichen gefolgt von einer als 
[A-Za-z]\d codierten Ziffer oder ein Zeichen gefolgt von 
_ und zwei Ziffern eingeben: 
[A-Za-z]_\d\d .
 snippet '([A-Za-z])(\d)' "auto subscript" wrA `!p snip.rv = match.group(1)`_`!p snip.rv = match.group(2)` endsnippet snippet '([A-Za-z])_(\d\d)' "auto subscript2" wrA `!p snip.rv = match.group(1)`_{`!p snip.rv = match.group(2)`} endsnippet 
Wenn Sie Teile eines regulÀren Ausdrucks in Klammern zu einer Gruppe zusammenfassen, z. B. 
(\d\d) , können Sie sie in der Snippet-Erweiterung ĂŒber 
match.group(i) in Python verwenden.
FĂŒr hochgestellte Zeichen verwende ich 
td , das sich in 
^{} verwandelt. Obwohl fĂŒr die hĂ€ufigsten (Quadrat, WĂŒrfel und mehrere andere) separate Snippets vorgesehen sind, wie z. B. 
sr , 
cb und 
comp .

 snippet sr "^2" iA ^2 endsnippet snippet cb "^3" iA ^3 endsnippet snippet compl "complement" iA ^{c} endsnippet snippet td "superscript" iA ^{$1}$0 endsnippet 
Bruchteil
Eines der bequemsten Snippets arbeitet mit BrĂŒchen. Er macht folgende Ersetzungen:
// â 
\frac{}{}3/ â 
\frac{3}{}4\pi^2/ â 
\frac{4\pi^2}{}(1 + 2 + 3)/ â 
\frac{1 + 2 + 3}{}(1+(2+3)/) â 
(1 + \frac{2+3}{})(1 + (2+3))/ â 
\frac{1 + (2+3)}{}
Zum ersten ein einfacher Code:
 snippet // "Fraction" iA \\frac{$1}{$2}$0 endsnippet 
Die zweite und dritte Substitution erfolgen mit Hilfe von regulĂ€ren AusdrĂŒcken, die den AusdrĂŒcken 
3/ , 
4ac/ , 
6\pi^2/ , 
a_2/ usw. entsprechen.
 snippet '((\d+)|(\d*)(\\)?([A-Za-z]+)((\^|_)(\{\d+\}|\d))*)/' "Fraction" wrA \\frac{`!p snip.rv = match.group(1)`}{$1}$0 endsnippet 
Wie Sie sehen können, können regulĂ€re AusdrĂŒcke ziemlich lang werden, aber hier ist ein Diagramm, das alles erklĂ€ren sollte:

Im vierten und fĂŒnften Fall versucht das Snippet, die entsprechende Klammer zu finden. Da die Regex-Engine von UltiSnips nicht weiĂ, wie das geht, musste ich Python verwenden:
 priority 1000 snippet '^.*\)/' "() Fraction" wrA `!p stripped = match.string[:-1] depth = 0 i = len(stripped) - 1 while True: if stripped[i] == ')': depth += 1 if stripped[i] == '(': depth -= 1 if depth == 0: break; i -= 1 snip.rv = stripped[0:i] + "\\frac{" + stripped[i+1:-1] + "}" `{$1}$0 endsnippet 
SchlieĂlich möchte ich ein Snippet freigeben, das die aktuelle Auswahl in einen Bruchteil verwandelt. WĂ€hlen Sie den Text aus, drĂŒcken Sie die 
Tab , geben Sie 
/ und erneut die 
Tab .

Der Code verwendet die Variable 
${VISUAL} , die Ihre Auswahl widerspiegelt.
 snippet / "Fraction" iA \\frac{${VISUAL}}{$1}$0 endsnippet 
Sympy und Mathematica
Ein anderes cooles, aber weniger verwendetes Snippet fĂŒhrt 
Sympy aus , um mathematische AusdrĂŒcke auszuwerten. Beispiel: 
sympy Tab zu 
sympy | sympy sympy | sympy und 
sympy 1 + 1 sympy Tab wird zu 
2 .

 snippet sympy "sympy block " w sympy $1 sympy$0 endsnippet priority 10000 snippet 'sympy(.*)sympy' "evaluate sympy" wr `!p from sympy import * x, y, z, t = symbols('xyz t') k, m, n = symbols('km n', integer=True) f, g, h = symbols('fg h', cls=Function) init_printing() snip.rv = eval('latex(' + match.group(1).replace('\\', '') \ .replace('^', '**') \ .replace('{', '(') \ .replace('}', ')') + ')') ` endsnippet 
FĂŒr Mathematica ist auch etwas Ăhnliches möglich:

 priority 1000 snippet math "mathematica block" w math $1 math$0 endsnippet priority 10000 snippet 'math(.*)math' "evaluate mathematica" wr `!p import subprocess code = 'ToString[' + match.group(1) + ', TeXForm]' snip.rv = subprocess.check_output(['wolframscript', '-code', code]) ` endsnippet 
Postfix-Snippets
Es scheint mir erwĂ€hnenswert, auch Postfix-Snippets zu erwĂ€hnen, die nach Eingabe bestimmter Zeichen den entsprechenden Text einfĂŒgen. Zum Beispiel 
phat â 
\hat{p} und 
zbar â 
\overline{z} . Ein Ă€hnliches Snippet fĂŒgt einen Vektor ein, zum Beispiel 
v,. â 
\vec{v} und 
v., â 
\vec{v} . Die Reihenfolge von Punkt und Semikolon spielt keine Rolle, so dass ich sie gleichzeitig anklicken kann. Diese Schnipsel sparen wirklich Zeit, da Sie sie mit der gleichen Geschwindigkeit eingeben, mit der ein Dozent an die Tafel schreibt.

Beachten Sie, dass die 
bar und HutprĂ€fixe weiterhin funktionieren, nur mit einer niedrigeren PrioritĂ€t. Der Code fĂŒr diese Snippets lautet:
 priority 10 snippet "bar" "bar" riA \overline{$1}$0 endsnippet priority 100 snippet "([a-zA-Z])bar" "bar" riA \overline{`!p snip.rv=match.group(1)`} endsnippet 
 priority 10 snippet "hat" "hat" riA \hat{$1}$0 endsnippet priority 100 snippet "([a-zA-Z])hat" "hat" riA \hat{`!p snip.rv=match.group(1)`} endsnippet 
 snippet "(\\?\w+)(,\.|\.,)" "Vector postfix" riA \vec{`!p snip.rv=match.group(1)`} endsnippet 
Andere Schnipsel
Ich habe immer noch ungefÀhr hundert hÀufig verwendete Schnipsel. Alle von ihnen sind 
hier verfĂŒgbar. Die meisten von ihnen sind ziemlich einfach. Zum Beispiel 
!> Wird zu 
\mapsto , 
-> wird zu 
\to usw.

fun verwandelt sich in 
f: \R \to \R : , 
!> â 
\mapsto , 
cc â 
\subset .

lim wird zu 
\lim_{n \to \infty} , 
sum â 
\sum_{n = 1}^{\infty} , 
ooo â 
\infty .


Kursspezifische Schnipsel
Neben hÀufig verwendeten habe ich auch spezielle Schnipsel. Sie werden als einzelne Zeile in 
.vimrc :
 set rtp+=~/current_course 
Hier ist 
current_course ein 
symbolischer Link zum aktuellen Kurs (mehr dazu in einem anderen Artikel). In diesem Ordner befindet sich die Datei 
~/current_course/UltiSnips/tex.snippets , in der ich 
~/current_course/UltiSnips/tex.snippets hinzufĂŒge. FĂŒr die Quantenmechanik gibt es beispielsweise Ausschnitte zum Aufzeichnen der QuantenzustĂ€nde von Wandlampen und Ketos.
<a| â 
\bra{a}<q| â 
\bra{\psi}|a> â 
\ket{a}|q> â 
\ket{\psi}\braket{a}{b} â 
\braket{a}{b}Da die Quantenmechanik hÀufig 
\psi , habe ich automatisch alle 
q in Klammern durch 
\psi .

 snippet "\<(.*?)\|" "bra" riA \bra{`!p snip.rv = match.group(1).replace('q', f'\psi').replace('f', f'\phi')`} endsnippet snippet "\|(.*?)\>" "ket" riA \ket{`!p snip.rv = match.group(1).replace('q', f'\psi').replace('f', f'\phi')`} endsnippet snippet "(.*)\\bra{(.*?)}([^\|]*?)\>" "braket" riA `!p snip.rv = match.group(1)`\braket{`!p snip.rv = match.group(2)`}{`!p snip.rv = match.group(3).replace('q', f'\psi').replace('f', f'\phi')`} endsnippet 
Kontext
Wenn Sie diese Schnipsel schreiben, sollten Sie berĂŒcksichtigen, ob sie im Klartext zu finden sind. Zum Beispiel gibt es laut meinem Wörterbuch ungefĂ€hr 72 Wörter auf Englisch und 2.000 Wörter auf NiederlĂ€ndisch mit sr. Wenn ich also 
disregard di^2egard , Àndert sich 
sr zu 
^2 und wir erhalten 
di^2egard .
Die Lösung fĂŒr dieses Problem besteht darin, Snippets Kontext hinzuzufĂŒgen. Die Syntaxhervorhebung von Vim bestimmt, ob UltiSnips ein Snippet verwenden soll, je nachdem, ob Sie sich im Formel- oder Textmodus befinden. Ich habe mir diese Option ausgedacht:
 global !p texMathZones = ['texMathZone'+x for x in ['A', 'AS', 'B', 'BS', 'C', 'CS', 'D', 'DS', 'E', 'ES', 'F', 'FS', 'G', 'GS', 'H', 'HS', 'I', 'IS', 'J', 'JS', 'K', 'KS', 'L', 'LS', 'DS', 'V', 'W', 'X', 'Y', 'Z']] texIgnoreMathZones = ['texMathText'] texMathZoneIds = vim.eval('map('+str(texMathZones)+", 'hlID(v:val)')") texIgnoreMathZoneIds = vim.eval('map('+str(texIgnoreMathZones)+", 'hlID(v:val)')") ignore = texIgnoreMathZoneIds[0] def math(): synstackids = vim.eval("synstack(line('.'), col('.') - (col('.')>=2 ? 1 : 0))") try: first = next( i for i in reversed(synstackids) if i in texIgnoreMathZoneIds or i in texMathZoneIds ) return first != ignore except StopIteration: return False endglobal 
Jetzt können Sie den Snippets, die Sie nur in einem mathematischen Kontext anwenden möchten, den 
context "math()" hinzufĂŒgen.
 context "math()" snippet sr "^2" iA ^2 endsnippet 
Beachten Sie, dass der mathematische Kontext eine subtile Sache ist. Manchmal schreiben wir im Formelmodus auch Text mit 
\text{...} . In diesem Fall möchten wir keine Snippets verwenden. Im folgenden Fall: 
\[ \text{$...$} \] mĂŒssen sie jedoch angewendet werden. Aus diesem Grund ist der Code fĂŒr den 
math Kontext nicht so einfach. Die folgende Animation veranschaulicht diese Feinheiten.

Rechtschreibkorrektur im laufenden Betrieb
Obwohl Formeln ein wichtiger Bestandteil des Abstracts sind, drucke ich die meiste Zeit auf Englisch. UngefĂ€hr 80 Wörter pro Minute, meine SchreibfĂ€higkeiten sind ziemlich gut, aber ich mache viele Tippfehler. Aus diesem Grund habe ich Vim eine Bindung hinzugefĂŒgt, die Rechtschreibfehler korrigiert, ohne die Arbeit zu beeintrĂ€chtigen. Wenn ich wĂ€hrend der Eingabe 
Ctrl+L , wird der vorherige Rechtschreibfehler korrigiert. Es sieht so aus:

Meine Einstellungen fĂŒr die RechtschreibprĂŒfung:
 setlocal spell set spelllang=nl,en_gb inoremap <Cl> <cg>u<Esc>[s1z=`]a<cg>u 
Gehen Sie hier zu den vorherigen Rechtschreibfehlern, wÀhlen Sie dann die erste Option 
1z= und geben Sie 
`]a . Mit den Befehlen 
<cg>u in der Mitte können Sie die Korrektur schnell rĂŒckgĂ€ngig machen.
AbschlieĂend
Dank Vim-Snippets ist das Schreiben von LaTeX-Code nicht mehr Ă€rgerlich, sondern ein VergnĂŒgen. In Kombination mit der Rechtschreibung im laufenden Betrieb können Sie so Vorlesungen ĂŒber Mathematik bequem und schnell skizzieren. Im 
nÀchsten Artikel werde ich auf andere Themen eingehen, z. B. das digitale Zeichnen von Illustrationen und das Einbetten in ein LaTeX-Dokument.