Bagaimana saya menulis catatan matematika di LaTeX di Vim

Beberapa waktu lalu di Quora saya menjawab pertanyaan: bagaimana mengikuti catatan kuliah dalam matematika di LaTeX . Di sana saya menjelaskan alur kerja pembuatan catatan saya di LaTeX menggunakan Vim dan Inkscape (untuk gambar). Tapi sejak itu, banyak yang berubah, jadi saya ingin menerbitkan beberapa posting blog dengan deskripsi proses baru. Ini adalah artikel pertama.

Saya mulai menggunakan LaTeX untuk membuat catatan pada semester kedua kursus matematika, dan sejak itu saya telah menulis lebih dari 1700 halaman. Berikut adalah beberapa contoh bagaimana ringkasan itu terlihat:







Catatan ini, termasuk gambar, dibuat langsung di kuliah dan tidak diedit selanjutnya. Untuk menulis abstrak secara efisien di LaTeX, empat aturan harus diikuti:

  • Menulis teks dan formula dalam LaTeX harus secepat seorang dosen menulis di papan tulis: keterlambatan tidak dapat diterima.
  • Menggambar ilustrasi harus hampir secepat dosen.
  • Mengelola catatan, yaitu menambahkan catatan, mengatur semua catatan, dua kuliah terakhir, mencari catatan, dll., Harus cepat dan mudah.
  • Seharusnya dimungkinkan untuk membubuhi keterangan dokumen pdf menggunakan LaTeX jika saya ingin menulis catatan dengan dokumen pdf.

Artikel ini adalah tentang poin pertama: mencatat di LaTeX.

Vim dan LaTeX


Untuk menulis teks dan rumus matematika di LaTeX, saya menggunakan Vim. Ini adalah editor teks tujuan umum yang kuat, sangat dapat dikembangkan. Saya menggunakannya untuk menulis kode, LaTeX, teks penurunan harga ... secara umum, teks apa pun. Dia memiliki kurva belajar yang agak curam, tetapi jika Anda telah menguasai pangkalan, sudah sulit untuk kembali ke editor tanpa tombol pintas yang biasa. Seperti inilah tampilan layar saya ketika saya mengedit dokumen LaTeX:



Di sebelah kiri adalah Vim, dan di sebelah kanan adalah penampil PDF Zathura , yang juga mendukung pintasan keyboard gaya Vim. Saya bekerja di Ubuntu dengan window manager bspwm . Sebagai plugin, LaTeX memasang vimtex . Ini menyediakan penyorotan sintaks, daftar isi, sintaksis, dll. Menggunakan vim-plug, saya mengkonfigurasinya sebagai berikut:

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'


Dua baris terakhir menyesuaikan penyamaran. Ini adalah fungsi di mana kode LaTeX diganti atau menjadi tidak terlihat ketika kursor tidak pada baris ini. Jika Anda menyembunyikan \ [ , \] , $ , maka mereka tidak begitu mencolok, yang memberikan gambaran dokumen yang lebih baik. Fungsi ini juga menggantikan \bigcap dengan , \in dengan , dll., Seperti yang ditunjukkan dalam animasi:



Dengan pengaturan ini Anda dapat mencapai tugas: menulis di LaTeX secepat dosen menulis di papan tulis. Cuplikan ikut bermain di sini.

Cuplikan


Apa itu cuplikan?


Cuplikan adalah potongan pendek teks yang dapat digunakan kembali yang dipanggil oleh teks lain. Misalnya, saat mengetik tanda dan menekan Tab, tanda kata berubah menjadi tanda tangan:



Cuplikan dapat menjadi dinamis: saat saya mengetik today dan menekan Tab , kata today ini diganti dengan tanggal saat ini, dan box - Tab menjadi bidang yang secara otomatis bertambah ukurannya.





Anda bahkan dapat menggunakan satu cuplikan di dalam cuplikan lainnya:



Membuat Cuplikan dengan UltiSnips


Untuk mengontrol cuplikan, saya menggunakan plugin UltiSnips . Ini konfigurasinya:

 Plug 'sirver/ultisnips' let g:UltiSnipsExpandTrigger = '<tab>' let g:UltiSnipsJumpForwardTrigger = '<tab>' let g:UltiSnipsJumpBackwardTrigger = '<s-tab>' 

Kode untuk sign snippet:

 snippet sign "Signature" Yours sincerely, Gilles Castel endsnippet 

Untuk cuplikan dinamis, Anda dapat menempatkan kode di antara tanda kutip ,, kode ini akan dijalankan ketika cuplikan diperluas. Di sini saya menggunakan bash untuk memformat tanggal saat ini: date + %F

 snippet today "Date" `date +%F` endsnippet 

Di dalam blok `!p ... ` , Anda dapat menulis dengan Python. Lihatlah kode untuk cuplikan box :

 snippet box "Box" `!p snip.rv = '┌' + '─' * (len(t[1]) + 2) + '┐'` │ $1 │ `!p snip.rv = '└' + '─' * (len(t[1]) + 2) + '┘'` $0 endsnippet 

Alih-alih kode ini, nilai variabel snip.rv akan dimasukkan ke dalam dokumen. Di dalam blok, Anda memiliki akses ke status potongan saat ini, misalnya, t[1] sesuai dengan tempat tab pertama, fn nama file saat ini, dll.

Cuplikan LaTeX


Cuplikan secara signifikan mempercepat pekerjaan, terutama beberapa cuplikan yang lebih kompleks. Mari kita mulai dengan yang paling sederhana.

Lingkungan


Untuk menyisipkan suatu lingkungan, cukup masukkan beg pada awal baris. Kemudian nama lingkungan, yang tercermin dalam perintah \end{} . Menekan Tab menempatkan kursor di dalam.



Kode tersebut adalah sebagai berikut:

 snippet beg "begin{} / end{}" bA \begin{$1} $0 \end{$1} endsnippet 

Simbol b berarti bahwa potongan seperti itu hanya berfungsi pada awal baris, A berarti ekspansi otomatis, yaitu, Anda tidak perlu menekan Tab . Tab tempat Anda pergi dengan menekan Tab dan Shift + Tab dinotasikan sebagai $1 , $2 , ... dan yang terakhir dinotasikan $0 .

Susun dan tampilkan rumus


Dua snippet yang paling sering digunakan adalah mk dan dm , yang memicu mode matematika. Yang pertama untuk formula sebaris, yang kedua untuk yang ditampilkan.



Cuplikan rumus pintar: Dia tahu kapan harus memasukkan spasi setelah tanda dolar. Ketika saya mulai mengetik kata segera setelah $ penutupan, itu menambah spasi. Tetapi jika saya mengetik karakter lain, maka itu tidak menambah spasi, seperti dalam kasus '$ p $ -value'.



Kode untuk cuplikan ini adalah:

 snippet mk "Math" wA $${1}$`!p if t[2] and t[2][0] not in [',', '.', '?', '-', ' ']: snip.rv = ' ' else: snip.rv = '' `$2 endsnippet 

W pada akhir baris pertama berarti bahwa cuplikan hanya mengembang pada batas kata. Karena itu, misalnya, hellomk tidak akan berfungsi, dan hello mk akan bekerja.

Cuplikan untuk rumus yang ditampilkan lebih sederhana, tetapi juga cukup nyaman. Itu selalu membuat persamaan berakhir dengan titik.



 <snippet dm "Math" wA \[ $1 .\] $0 endsnippet 

Karakter subskrip dan superskrip


Cuplikan berguna lainnya adalah untuk indeks. Itu berubah a1 ke a_1 dan a_12 ke a_{12} .



Kode untuk cuplikan ini menggunakan ekspresi reguler sebagai pemicu. Itu memperluas fragmen ketika Anda memasukkan karakter diikuti oleh digit yang disandikan sebagai [A-Za-z]\d , atau karakter diikuti oleh _ dan dua digit: [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 

Saat Anda menggabungkan bagian dari ekspresi reguler ke grup menggunakan tanda kurung, misalnya, (\d\d) , Anda bisa menggunakannya dalam ekstensi snippet melalui match.group(i) dengan Python.

Untuk karakter superskrip, saya menggunakan td , yang berubah menjadi ^{} . Meskipun untuk yang paling umum (kotak, kubus, dan beberapa lainnya), cuplikan terpisah dimaksudkan, seperti sr , cb , dan 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 

Pecahan


Salah satu cuplikan paling nyaman bekerja dengan pecahan. Dia membuat penggantian berikut:

//\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)}{}



Untuk yang pertama, kode sederhana:

 snippet // "Fraction" iA \\frac{$1}{$2}$0 endsnippet 

4ac/ kedua dan ketiga terjadi dengan bantuan ekspresi reguler yang sesuai dengan ekspresi 3/ , 4ac/ , 6\pi^2/ , a_2/ , dll.

 snippet '((\d+)|(\d*)(\\)?([A-Za-z]+)((\^|_)(\{\d+\}|\d))*)/' "Fraction" wrA \\frac{`!p snip.rv = match.group(1)`}{$1}$0 endsnippet 

Seperti yang Anda lihat, ekspresi reguler bisa menjadi sangat panjang, tetapi di sini adalah diagram yang harus menjelaskan semuanya:



Dalam kasus keempat dan kelima, cuplikan mencoba menemukan braket yang sesuai. Karena mesin regex UltiSnips tidak tahu bagaimana melakukan ini, saya harus menggunakan 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 

Akhirnya, saya ingin membagikan cuplikan yang mengubah pilihan saat ini menjadi sebagian kecil. Pilih teks, tekan Tab , ketik / dan lagi Tab .



Kode menggunakan variabel ${VISUAL} , yang mencerminkan pilihan Anda.

 snippet / "Fraction" iA \\frac{${VISUAL}}{$1}$0 endsnippet 

Sympy dan Mathematica


Potongan keren lainnya yang kurang digunakan menjalankan sympy untuk mengevaluasi ekspresi matematika. Sebagai contoh: sympy Tab memperluas ke sympy | sympy sympy | sympy , dan sympy 1 + 1 sympy Tab berubah menjadi 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 

Untuk Mathematica, sesuatu yang serupa juga dimungkinkan:



 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 

Cuplikan Postfix


Menurut saya layak juga menyebutkan potongan postfix yang menyisipkan teks yang sesuai setelah memasukkan karakter tertentu. Misalnya, phat\hat{p} dan zbar\overline{z} . Cuplikan serupa memasukkan vektor, misalnya, v,.\vec{v} dan v.,\vec{v} . Urutan periode dan titik koma tidak menjadi masalah, sehingga saya dapat mengkliknya secara bersamaan. Cuplikan ini sangat menghemat waktu, karena Anda memasukkannya dengan kecepatan yang sama seperti yang ditulis dosen di papan tulis.



Perhatikan bahwa awalan bar dan hat masih berfungsi, hanya dengan prioritas yang lebih rendah. Kode untuk cuplikan ini adalah:

 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 

Cuplikan lainnya


Saya masih memiliki sekitar seratus potongan yang biasa digunakan. Semuanya tersedia di sini . Kebanyakan dari mereka cukup sederhana. Misalnya, !> Berubah menjadi \mapsto , -> menjadi \to , dll.



fun transforms menjadi f: \R \to \R : , !>\mapsto , cc\subset .



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





Cuplikan khusus kursus


Selain yang sering digunakan, saya juga punya cuplikan khusus. Mereka dimuat sebagai satu baris di .vimrc :

 set rtp+=~/current_course 

Di sini current_course adalah tautan simbolik ke kursus saat ini (lebih lanjut tentang ini di artikel lain). Dalam folder ini adalah file ~/current_course/UltiSnips/tex.snippets , di mana saya menambahkan potongan saja. Misalnya, untuk mekanika kuantum, ada cuplikan untuk merekam status quantum sconce dan keto.

<a|\bra{a}
<q|\bra{\psi}
|a>\ket{a}
|q>\ket{\psi}
\braket{a}{b}\braket{a}{b}

Karena mekanika kuantum sering menggunakan \psi , saya secara otomatis mengganti semua q di braket dengan \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 

Konteks


Saat menulis cuplikan ini, Anda harus mempertimbangkan apakah itu dapat ditemukan dalam teks biasa. Misalnya, menurut kamus saya, ada sekitar 72 kata dalam bahasa Inggris, dan 2.000 kata dalam bahasa Belanda dengan sr. Jadi, ketika saya mengetik disregard , sr berubah menjadi ^2 , dan kami mendapatkan di^2egard .

Solusi untuk masalah ini adalah menambahkan konteks ke cuplikan. Penyorotan sintaksis Vim menentukan apakah UltiSnips harus menggunakan potongan, tergantung pada apakah Anda berada dalam mode rumus atau teks. Saya datang dengan opsi ini:

 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 

Sekarang Anda dapat menambahkan context "math()" ke cuplikan yang ingin Anda terapkan hanya dalam konteks matematika.

 context "math()" snippet sr "^2" iA ^2 endsnippet 

Perhatikan bahwa konteks matematika adalah hal yang halus. Terkadang dalam mode formula kami juga menulis teks menggunakan \text{...} . Dalam hal ini, kami tidak ingin menggunakan snippet. Namun, dalam kasus berikut: \[ \text{$...$} \] , mereka harus diterapkan. Inilah sebabnya mengapa kode untuk konteks math tidak begitu sederhana. Animasi berikut menggambarkan seluk-beluk ini.



Koreksi ejaan dengan cepat


Meskipun formula adalah bagian penting dari abstrak, saya mencetak sebagian besar waktu dalam bahasa Inggris. Sekitar 80 kata per menit, kemampuan mengetik saya cukup bagus, tetapi saya membuat banyak kesalahan ketik. Itu sebabnya saya menambahkan ikatan ke Vim yang memperbaiki kesalahan ejaan tanpa mengganggu pekerjaan. Ketika saya Ctrl+L selama input, kesalahan ejaan sebelumnya diperbaiki. Ini terlihat seperti ini:



Pengaturan saya untuk memeriksa ejaan:

 setlocal spell set spelllang=nl,en_gb inoremap <Cl> <cg>u<Esc>[s1z=`]a<cg>u 

Di sini, buka kesalahan ejaan sebelumnya [s , lalu pilih opsi pertama 1z= dan kembalikan `]a . Perintah <cg>u di tengah memungkinkan Anda untuk dengan cepat membatalkan koreksi.

Kesimpulannya


Berkat cuplikan Vim, menulis kode LaTeX tidak lagi menjengkelkan, melainkan menyenangkan. Dalam kombinasi dengan ejaan saat itu, ini memungkinkan Anda untuk dengan mudah dan cepat menguraikan kuliah tentang matematika. Pada artikel berikutnya, saya akan berbicara tentang topik lain, seperti menggambar ilustrasi secara digital dan menyematkannya dalam dokumen LaTeX.

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


All Articles