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.