Il y a quelque temps, à Quora, j'ai répondu à la question:
comment suivre les notes de cours en mathématiques sur LaTeX . Là, j'ai expliqué mon flux de travail de prise de notes dans LaTeX en utilisant Vim et Inkscape (pour les dessins). Mais depuis, beaucoup de choses ont changé, je veux donc publier plusieurs articles de blog avec une description du nouveau processus. Ceci est le premier des articles.
J'ai commencé à utiliser LaTeX pour prendre des notes au deuxième semestre d'un cours de mathématiques, et depuis lors, j'ai écrit plus de 1700 pages. Voici quelques exemples de ce à quoi ressemble le résumé:



Ces notes, y compris les dessins, sont prises directement lors de la conférence et ne sont pas modifiées par la suite. Pour rédiger efficacement des résumés dans LaTeX, quatre règles doivent être suivies:
- L'écriture de texte et de formules dans LaTeX devrait être aussi rapide qu'un professeur écrivant au tableau: le délai est inacceptable.
- Les illustrations de dessin doivent être presque aussi rapides que celles du professeur.
- La gestion des notes, c'est-à-dire l'ajout de notes, l'organisation de toutes les notes, les deux dernières conférences, la recherche de notes, etc., devrait être rapide et facile.
- Il devrait être possible d'annoter des documents pdf en utilisant LaTeX si je veux écrire une note avec un document pdf.
Cet article concerne le premier point: prendre des notes sur LaTeX.
Vim et LaTeX
Pour écrire du texte et des formules mathématiques sur LaTeX, j'utilise Vim. Il s'agit d'un puissant éditeur de texte à usage général, hautement extensible. Je l'utilise pour écrire du code, LaTeX, du texte Markdown ... en général, tous les textes. Il a une courbe d'apprentissage assez abrupte, mais si vous maîtrisez la base, il est déjà difficile de revenir à l'éditeur sans les touches de raccourci habituelles. Voici à quoi ressemble mon écran lorsque je modifie un document LaTeX:

À gauche se trouve Vim, et à droite se trouve le visualiseur
Zathura PDF, qui prend également en charge les raccourcis clavier de style Vim. Je travaille dans Ubuntu avec le
gestionnaire de fenêtres
bspwm . En tant que plugin LaTeX installé
vimtex . Il fournit la coloration syntaxique, la table des matières, le synctex, etc. En utilisant le
plug-in vim, je l'ai configuré comme suit:
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'
Les deux dernières lignes ajustent le déguisement. Il s'agit d'une fonction dans laquelle le code LaTeX est remplacé ou devient invisible lorsque le curseur n'est pas sur cette ligne. Si vous masquez
\ [
,
\]
,
$
, alors ils ne sont pas si visibles, ce qui donne une meilleure vue d'ensemble du document. Cette fonction remplace également
\bigcap
par
∩
,
\in
par
∈
, etc., comme indiqué dans l'animation:

Avec ce paramètre, vous pouvez accomplir la tâche: écrire sur LaTeX aussi vite qu'un professeur écrit au tableau. Des extraits entrent en jeu ici.
Extraits
Qu'est-ce qu'un extrait?
Un extrait est un court morceau de texte réutilisable appelé par un autre texte. Par exemple, lorsque vous tapez signe et appuyez sur Tab, le signe verbal se transforme en signature:

Les extraits peuvent être dynamiques: lorsque je tape
today
et appuie sur
Tab
, le mot
today
est remplacé par la date actuelle, et la
box
-
Tab
devient un champ qui grossit automatiquement.


Vous pouvez même utiliser un extrait dans un autre:

Création d'extraits de code avec UltiSnips
Pour contrôler les extraits, j'utilise le plugin
UltiSnips . Voici sa configuration:
Plug 'sirver/ultisnips' let g:UltiSnipsExpandTrigger = '<tab>' let g:UltiSnipsJumpForwardTrigger = '<tab>' let g:UltiSnipsJumpBackwardTrigger = '<s-tab>'
Code pour le
sign
extrait:
snippet sign "Signature" Yours sincerely, Gilles Castel endsnippet
Pour les extraits dynamiques, vous pouvez mettre le code entre les guillemets, ce code sera exécuté lorsque l'extrait sera étendu. Ici, j'ai utilisé bash pour formater la date actuelle:
date + %F
snippet today "Date" `date +%F` endsnippet
Dans le bloc
`!p ... `
, vous pouvez écrire en Python. Regardez le code de l'extrait de
box
:
snippet box "Box" `!p snip.rv = '┌' + '─' * (len(t[1]) + 2) + '┐'` │ $1 │ `!p snip.rv = '└' + '─' * (len(t[1]) + 2) + '┘'` $0 endsnippet
Au lieu de ce code, la valeur de la variable
snip.rv
sera insérée dans le document. À l'intérieur des blocs, vous avez accès à l'état actuel de l'extrait de code, par exemple,
t[1]
correspond à l'emplacement du premier onglet,
fn
nom du fichier actuel, etc.
Extraits LaTeX
Les extraits de code accélèrent considérablement le travail, en particulier certains des extraits de code les plus complexes. Commençons par le plus simple.
L'environnement
Pour insérer un environnement, entrez simplement
beg
au début de la ligne. Ensuite, le nom de l'environnement, qui se reflète dans la commande
\end{}
. Appuyer sur
Tab
place le curseur à l'intérieur.

Le code est le suivant:
snippet beg "begin{} / end{}" bA \begin{$1} $0 \end{$1} endsnippet
Le symbole
b
signifie qu'un tel extrait ne fonctionne qu'au début d'une ligne,
A
signifie une expansion automatique, c'est-à-dire que vous n'avez pas besoin d'appuyer sur
Tab
. Les onglets où vous allez en appuyant sur
Tab
et
Shift
+
Tab
sont désignés par
$1
,
$2
, ... et ce dernier est noté
$0
.
Formules en ligne et d'affichage
Les deux extraits de
mk
plus couramment utilisés sont
mk
et
dm
, qui déclenchent le mode mathématique. Le premier pour les formules en ligne, le second pour les formules affichées.

Extrait de formule intelligente: il sait quand insérer un espace après le signe dollar. Lorsque je commence à taper un mot immédiatement après la fermeture de $, cela ajoute un espace. Mais si je tape un autre caractère, il n'ajoute pas d'espace, comme dans le cas de '$ p $ -value'.

Le code de cet extrait est:
snippet mk "Math" wA $${1}$`!p if t[2] and t[2][0] not in [',', '.', '?', '-', ' ']: snip.rv = ' ' else: snip.rv = '' `$2 endsnippet
W
à la fin de la première ligne signifie que l'extrait se développe uniquement aux limites des mots. Par exemple,
hellomk
ne fonctionnera pas et
hello mk
fonctionnera.
L'extrait pour les formules affichées est plus simple, mais aussi très pratique. Il fait toujours terminer les équations par un point.

<snippet dm "Math" wA \[ $1 .\] $0 endsnippet
Caractères en indice et en exposant
Un autre extrait utile concerne les index. Il change
a1
en
a_1
et
a_12
en
a_{12}
.

Le code de cet extrait utilise une expression régulière comme déclencheur. Il développe le fragment lorsque vous entrez un caractère suivi d'un chiffre codé comme
[A-Za-z]\d
, ou d'un caractère suivi de
_
et de deux chiffres:
[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
Lorsque vous combinez des parties d'une expression régulière dans un groupe à l'aide de parenthèses, par exemple
(\d\d)
, vous pouvez les utiliser dans l'extension d'extrait via
match.group(i)
en Python.
Pour les caractères en exposant, j'utilise
td
, qui se transforme en
^{}
. Bien que pour les plus courants (carré, cube et plusieurs autres), des extraits de code distincts soient prévus, tels que
sr
,
cb
et
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
Fraction
L'un des extraits les plus pratiques fonctionne avec des fractions. Il fait les remplacements suivants:
//
→
\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)}{}

Pour le premier, un code simple:
snippet // "Fraction" iA \\frac{$1}{$2}$0 endsnippet
Les deuxième et troisième substitutions se produisent à l'aide d'expressions régulières correspondant aux expressions
3/
,
4ac/
,
6\pi^2/
,
a_2/
, etc.
snippet '((\d+)|(\d*)(\\)?([A-Za-z]+)((\^|_)(\{\d+\}|\d))*)/' "Fraction" wrA \\frac{`!p snip.rv = match.group(1)`}{$1}$0 endsnippet
Comme vous pouvez le voir, les expressions régulières peuvent devenir assez longues, mais voici un diagramme qui devrait tout expliquer:

Dans les quatrième et cinquième cas, l'extrait de code essaie de trouver le support correspondant. Étant donné que le moteur d'expression régulière UltiSnips ne sait pas comment procéder, j'ai dû utiliser Python:
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
Enfin, je veux partager un extrait qui transforme la sélection actuelle en une fraction. Sélectionnez le texte, appuyez sur
Tab
, tapez
/
et encore
Tab
.

Le code utilise la variable
${VISUAL}
, qui reflète votre choix.
snippet / "Fraction" iA \\frac{${VISUAL}}{$1}$0 endsnippet
Sympy et Mathematica
Un autre extrait sympa mais moins utilisé exécute
sympy pour évaluer les expressions mathématiques. Par exemple:
sympy
Tab
développe en
sympy | sympy
sympy | sympy
et
sympy 1 + 1 sympy
Tab
devient
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
Pour Mathematica, quelque chose de similaire est également possible:

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
Extraits Postfix
Il me semble utile de mentionner également des extraits de suffixe qui insèrent le texte approprié après avoir entré certains caractères. Par exemple,
phat
→
\hat{p}
et
zbar
→
\overline{z}
. Un extrait similaire insère un vecteur, par exemple,
v,.
→
\vec{v}
et
v.,
→
\vec{v}
. L'ordre du point et du point-virgule n'a pas d'importance, de sorte que je puisse les cliquer en même temps. Ces extraits font vraiment gagner du temps, car vous les saisissez à la même vitesse qu'un professeur écrit au tableau.

Notez que les préfixes de
bar
et de
hat
fonctionnent toujours, uniquement avec une priorité inférieure. Le code de ces extraits est:
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
Autres extraits
J'ai encore une centaine d'extraits couramment utilisés. Tous sont disponibles
ici . La plupart d'entre eux sont assez simples. Par exemple,
!>
Se transforme en
\mapsto
,
->
devient
\to
, etc.

fun
transforme en
f: \R \to \R :
,
!>
→
\mapsto
,
cc
→
\subset
.

lim
devient
\lim_{n \to \infty}
,
sum
→
\sum_{n = 1}^{\infty}
,
ooo
→
\infty
.


Extraits spécifiques au cours
En plus de ceux fréquemment utilisés, j'ai également des extraits spécifiques. Ils sont chargés en une seule ligne dans
.vimrc
:
set rtp+=~/current_course
Ici
current_course
est un
lien symbolique vers le cours actuel (plus à ce sujet dans un autre article). Dans ce dossier se trouve le fichier
~/current_course/UltiSnips/tex.snippets
, où j'ajoute des extraits de cours. Par exemple, pour la mécanique quantique, il existe des extraits pour enregistrer les états quantiques des appliques et des cétos.
<a|
→
\bra{a}
<q|
→
\bra{\psi}
|a>
→
\ket{a}
|q>
→
\ket{\psi}
\braket{a}{b}
→
\braket{a}{b}
Comme la mécanique quantique utilise souvent
\psi
, j'ai automatiquement remplacé tous les
q
dans braket par
\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
Contexte
Lors de la rédaction de ces extraits, vous devez déterminer s'ils peuvent être trouvés en texte brut. Par exemple, selon mon dictionnaire, il y a environ 72 mots en anglais et 2 000 mots en néerlandais avec sr. Ainsi, lorsque je tape
disregard
,
sr
passe à
^2
, et nous obtenons
di^2egard
.
La solution à ce problème consiste à ajouter du contexte aux extraits de code. La coloration syntaxique de Vim détermine si UltiSnips doit utiliser un extrait de code, selon que vous êtes en mode formule ou texte. Je suis venu avec cette option:
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
Vous pouvez maintenant ajouter le
context "math()"
aux extraits de code que vous souhaitez appliquer uniquement dans un contexte mathématique.
context "math()" snippet sr "^2" iA ^2 endsnippet
Notez que le contexte mathématique est une chose subtile. Parfois, en mode formule, nous écrivons également du texte en utilisant
\text{...}
. Dans ce cas, nous ne voulons pas utiliser d'extraits. Cependant, dans le cas suivant:
\[ \text{$...$} \]
, ils
doivent être appliqués. C'est pourquoi le code du contexte
math
n'est pas si simple. L'animation suivante illustre ces subtilités.

Correction orthographique à la volée
Bien que les formules soient une partie importante du résumé, j'imprime la plupart du temps en anglais. Environ 80 mots par minute, mes compétences de frappe sont assez bonnes, mais je fais beaucoup de fautes de frappe. C'est pourquoi j'ai ajouté une liaison à Vim qui corrige les fautes d'orthographe sans interférer avec le travail. Lorsque j'appuie
Ctrl+L
pendant la saisie, l'erreur d'orthographe précédente est corrigée. Cela ressemble à ceci:

Mes paramètres pour la vérification orthographique:
setlocal spell set spelllang=nl,en_gb inoremap <Cl> <cg>u<Esc>[s1z=`]a<cg>u
Ici, allez à l'erreur d'orthographe précédente
[s
, puis sélectionnez la première option
1z=
et retournez
`]a
. Les commandes
<cg>u
au milieu vous permettent d'annuler rapidement la correction.
En conclusion
Grâce aux extraits de Vim, écrire du code LaTeX n'est plus ennuyeux, mais plutôt un plaisir. En combinaison avec l'orthographe à la volée, cela vous permet de décrire rapidement et facilement des conférences sur les mathématiques. Dans le
prochain article, je parlerai d’autres sujets, comme le dessin d’illustrations numériques et leur intégration dans un document LaTeX.