Comment j'écris des notes mathématiques sur LaTeX dans Vim

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.

Source: https://habr.com/ru/post/fr445066/


All Articles