كيف أكتب ملاحظات الرياضيات على LaTeX في Vim

منذ بعض الوقت في Quora أجبت على السؤال: كيفية مواكبة ملاحظات المحاضرة في الرياضيات على LaTeX . شرحت هناك سير عمل تدوين الملاحظات في LaTeX باستخدام Vim و Inkscape (للرسومات). لكن منذ ذلك الحين ، تغير الكثير ، لذلك أريد نشر العديد من منشورات المدونة مع وصف للعملية الجديدة. هذا هو أول المقالات.

لقد بدأت باستخدام LaTeX لتدوين الملاحظات في الفصل الدراسي الثاني من دورة الرياضيات ، ومنذ ذلك الحين كتبت أكثر من 1700 صفحة. فيما يلي بعض الأمثلة على شكل الملخص:







يتم عمل هذه الملاحظات ، بما في ذلك الرسومات ، مباشرة في المحاضرة ولا يتم تحريرها لاحقًا. لكتابة الملخصات بكفاءة في LaTeX ، يجب اتباع أربع قواعد:

  • يجب أن تكون كتابة النص والصيغ في LaTeX بنفس سرعة كتابة المحاضر على السبورة: التأخير غير مقبول.
  • يجب أن تكون الرسوم التوضيحية الرسم بنفس سرعة المحاضر.
  • يجب أن تكون إدارة الملاحظات ، أي إضافة ملاحظات ، وترتيب جميع الملاحظات ، آخر محاضرتين ، وملاحظات البحث ، وما إلى ذلك ، سريعة وسهلة.
  • يجب أن يكون من الممكن تعليق مستندات pdf باستخدام LaTeX إذا أردت كتابة ملاحظة مع مستند pdf.

هذه المقالة حول النقطة الأولى: تدوين الملاحظات على LaTeX.

فيم و لاتكس


لكتابة النص والصيغ الرياضية على LaTeX ، يمكنني استخدام Vim. هذا هو محرر نصوص قوي للأغراض العامة ، قابل للتوسيع بدرجة كبيرة. أنا استخدامها لكتابة التعليمات البرمجية ، والنص اللاتكس ، تخفيض السعر ... بشكل عام ، أي النصوص. لديه منحنى تعليمي حاد ، لكن إذا كنت تتقن القاعدة ، فمن الصعب بالفعل العودة إلى المحرر دون استخدام المفاتيح الساخنة المعتادة. هذا ما تبدو عليه شاشتي عندما أقوم بتحرير مستند LaTeX:



على اليسار هو Vim ، وعلى اليمين هو عارض Zathura PDF ، والذي يدعم أيضًا اختصارات لوحة المفاتيح على غرار Vim. أنا أعمل في أوبونتو مع مدير نافذة bspwm . كما المساعد تثبيت اللثي vimtex . يوفر تسليط الضوء على بناء الجملة ، وجدول المحتويات ، synctex ، إلخ. باستخدام vim-plug ، قمت بتكوينه على النحو التالي:

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'


آخر سطرين ضبط المقنعة. هذه وظيفة يتم فيها استبدال رمز LaTeX أو يصبح غير مرئي عندما يكون المؤشر غير موجود على هذا الخط. إذا قمت بإخفاء \ [ ، \] ، $ ، فلن تكون واضحة للغاية ، مما يعطي نظرة عامة أفضل على المستند. تستبدل هذه الوظيفة أيضًا \bigcap بـ ، \in بـ ، إلخ ، كما هو موضح في الرسوم المتحركة:



باستخدام هذا الإعداد ، يمكنك تحقيق المهمة: الكتابة على LaTeX بأسرع ما يكتبه المحاضر على السبورة. القصاصات تدخل حيز اللعب هنا.

قصاصات


ما هو المقتطف؟


المقتطف عبارة عن جزء قصير من النص القابل لإعادة الاستخدام والذي يسمى بنص آخر. على سبيل المثال ، عند كتابة علامة وضغط Tab ، تتحول علامة الكلمة إلى توقيع:



يمكن أن تكون المقتطفات ديناميكية: عندما أكتب today واضغط على Tab ، يتم استبدال الكلمة today بالتاريخ الحالي ، ويصبح box - Tab حقلًا يزداد حجمه تلقائيًا.





يمكنك حتى استخدام مقتطف واحد داخل آخر:



إنشاء قصاصات مع UltiSnips


للتحكم في المقتطفات ، يمكنني استخدام المكون الإضافي UltiSnips . هنا هو التكوين:

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

رمز sign المقتطف:

 snippet sign "Signature" Yours sincerely, Gilles Castel endsnippet 

بالنسبة إلى المقتطفات الديناميكية ، يمكنك وضع الكود بين backquotes ، ، وسيتم تشغيل هذا الكود عند تمديد المقتطف. أنا هنا استخدم bash لتنسيق التاريخ الحالي: date + %F

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

داخل كتلة `!p ... ` ، يمكنك الكتابة في بيثون. انظر إلى رمز مقتطف box :

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

بدلاً من هذا الرمز ، سيتم إدراج قيمة المتغير snip.rv في المستند. داخل الكتل ، يمكنك الوصول إلى الحالة الحالية للقصاص ، على سبيل المثال ، t[1] يتوافق مع مكان علامة التبويب الأولى ، fn اسم الملف الحالي ، إلخ.

قصاصات LaTeX


المقتطفات تسريع العمل بشكل كبير ، وخاصة بعض المقتطفات الأكثر تعقيدًا. لنبدأ مع أبسط.

البيئة


لإدخال بيئة ، فقط أدخل beg في بداية السطر. ثم اسم البيئة ، والتي تنعكس في الأمر \end{} . الضغط على Tab يضع المؤشر في الداخل.



الكود كما يلي:

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

يعني الرمز b أن مثل هذا المقتطف يعمل فقط في بداية السطر ، يعني A التوسع التلقائي ، أي أنك لست بحاجة إلى الضغط على Tab . تتم الإشارة إلى علامات التبويب التي تذهب إليها عن طريق الضغط على Tab و Shift + Tab على أنها $1 ، $2 ، ... والرمز الأخير هو $0 .

مضمنة وعرض الصيغ


القصاصات الأكثر استخدامًا هما mk و dm ، مما يؤدي إلى تشغيل وضع الرياضيات. الأول للصيغ المضمّنة ، والثاني للصيغ المعروضة.



مقتطف الصيغة الذكية: يعرف متى يتم إدخال مسافة بعد علامة الدولار. عندما أبدأ بكتابة كلمة مباشرة بعد إغلاق $ ، فإنها تضيف مسافة. لكن إذا كتبت حرفًا آخر ، فلن تضيف مسافة ، كما في حالة "قيمة $ p $-value".



الكود الخاص بهذه المقتطف هو:

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

W في نهاية السطر الأول أن المقتطف يتسع فقط عند حدود الكلمات. لذلك ، على سبيل المثال ، لن تعمل hellomk ، hellomk hello mk .

مقتطف الصيغ المعروضة أبسط ، ولكنه مريح للغاية أيضًا. يجعل دائمًا المعادلات تنتهي بنقطة.



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

أحرف منخفضة ومرتقبة


مقتطف مفيد آخر هو للفهارس. يغير a1 إلى a_1 و a_{12} إلى a_{12} .



تستخدم الشفرة الخاصة بهذه المقتطف تعبيرًا عاديًا كمشغل. يقوم بتوسيع الجزء عند إدخال حرف متبوعًا برقم مشفر كـ [A-Za-z]\d ، أو حرف يتبعه _ ورقمان: [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 

عندما تقوم بدمج أجزاء من تعبير عادي في مجموعة باستخدام أقواس ، على سبيل المثال ، (\d\d) ، يمكنك استخدامها في ملحق المقتطف عبر match.group(i) في Python.

بالنسبة للأحرف الفائقة ، يمكنني استخدام td ، والذي يتحول إلى ^{} . على الرغم من أنه الأكثر شيوعًا (المربعة ، المكعب ، وعدة أخرى) ، فإن القصاصات المنفصلة مخصصة ، مثل sr و cb و 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 

الكسور


واحدة من أكثر المقتطفات ملاءمة تعمل مع الكسور. يقوم بالبدائل التالية:

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



لأول ، رمز بسيط:

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

يحدث 4ac/ الثاني والثالث بمساعدة التعبيرات العادية المقابلة للتعبيرات 3/ ، 4ac/ ، 6\pi^2/ ، a_2/ ، إلخ.

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

كما ترون ، يمكن أن تصبح التعبيرات العادية طويلة جدًا ، ولكن فيما يلي رسم بياني يوضح كل شيء:



في الحالتين الرابعة والخامسة ، يحاول القصاص العثور على القوس المقابل. نظرًا لأن محرك UltiSnips regex لا يعرف كيفية القيام بذلك ، كان علي استخدام 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 

أخيرًا ، أريد مشاركة قصاصة تحول التحديد الحالي إلى كسر. حدد النص ، واضغط على Tab ، واكتب / ثم اضغط على Tab مرة أخرى.



يستخدم الكود المتغير ${VISUAL} ، والذي يعكس اختيارك.

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

سيمبي ورياضيات


يعمل مقتطف رائع آخر أقل استخدامًا على تشغيل sympy لتقييم تعبيرات الرياضيات. على سبيل المثال: Tab sympy Tab تتوسع إلى sympy | sympy sympy | sympy ، و sympy 1 + 1 sympy Tab يتحول إلى 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 

بالنسبة إلى Mathematica ، هناك شيء مماثل ممكن أيضًا:



 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


يبدو لي أن أذكر أيضًا قصاصات postfix التي تدرج النص المناسب بعد إدخال أحرف معينة. على سبيل المثال ، phat\hat{p} و zbar\overline{z} . إدراج مقتطف مشابه متجهًا ، على سبيل المثال ، v,.\vec{v} و v.,\vec{v} . لا يهم ترتيب الفترة والفاصلة المنقوطة ، لذلك يمكنني النقر عليها في نفس الوقت. هذه المقتطفات توفر الوقت حقًا ، لأنك تدخلها بنفس السرعة التي يكتبها المحاضر على السبورة.



لاحظ أن بادئات bar hat لا تزال تعمل ، مع أولوية أقل. رمز هذه المقتطفات هو:

 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 

قصاصات أخرى


لا يزال لدي حوالي مائة قصاصة شائعة الاستخدام. كل منهم متاح هنا . معظمهم بسيط جدا. على سبيل المثال ، !> يتحول إلى \mapsto ، -> يصبح \to ، إلخ.



تتحول fun إلى f: \R \to \R : ، !>\mapsto ، cc\subset .



يصبح lim \lim_{n \to \infty} ، sum\sum_{n = 1}^{\infty} ، ooo\infty .





قصاصات الدورة التدريبية المحددة


بالإضافة إلى تلك المستخدمة بشكل متكرر ، لدي أيضًا قصاصات محددة. يتم تحميلها كسطر واحد في .vimrc :

 set rtp+=~/current_course 

تعد current_course هنا رابطًا رمزيًا للدورة التدريبية الحالية (المزيد حول هذا الموضوع في مقال آخر). في هذا المجلد ، يوجد الملف ~/current_course/UltiSnips/tex.snippets ، حيث أضيف قصاصات الدورة التدريبية. على سبيل المثال ، بالنسبة لميكانيكا الكم ، هناك قصاصات لتسجيل حالات الكم من الشمعدانات والكيتو.

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

نظرًا لأن ميكانيكا الكم تستخدم غالبًا \psi ، استبدلت تلقائيًا كل q في braket بـ \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 

السياق


عند كتابة هذه المقتطفات ، يجب أن تفكر فيما إذا كان يمكن العثور عليها في نص عادي. على سبيل المثال ، وفقًا لقاموسي ، هناك حوالي 72 كلمة باللغة الإنجليزية ، و 2000 كلمة باللغة الهولندية مع sr. وبالتالي ، عندما أكتب disregard ، تتغير sr إلى ^2 ، ونحصل على di^2egard .

يكمن حل هذه المشكلة في إضافة سياق إلى المقتطفات. يحدد تمييز بناء جملة Vim ما إذا كان يجب على UltiSnips استخدام مقتطف ، اعتمادًا على ما إذا كنت في صيغة أو صيغة نصية. خطرت هذا الخيار:

 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 

يمكنك الآن إضافة context "math()" إلى تلك المقتطفات التي تريد تطبيقها فقط في سياق رياضي.

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

لاحظ أن السياق الرياضي هو شيء خفي. أحيانًا في صيغة الصيغة ، نكتب أيضًا نصًا باستخدام \text{...} . في هذه الحالة ، لا نريد استخدام المقتطفات. ومع ذلك ، في الحالة التالية: \[ \text{$...$} \] ، يجب تطبيقها. هذا هو السبب في أن رمز سياق math ليس بهذه البساطة. الرسوم المتحركة التالية توضح هذه التفاصيل الدقيقة.



تصحيح الإملاء على الطاير


على الرغم من أن الصيغ جزء مهم من الملخص ، إلا أنني أطبع معظم الوقت باللغة الإنجليزية. حوالي 80 كلمة في الدقيقة ، مهاراتي في الكتابة جيدة ، لكنني أصنع الكثير من الأخطاء المطبعية. لهذا السبب أضفت ارتباطًا إلى Vim يصحح الأخطاء الإملائية دون التدخل في العمل. عندما أقوم Ctrl+L أثناء الإدخال ، يتم تصحيح خطأ الإملاء السابق. يبدو مثل هذا:



الإعدادات الخاصة بي للتدقيق الإملائي:

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

هنا ، انتقل إلى الخطأ [s الأخطاء) الإملائي السابق ، ثم حدد الخيار الأول 1z= ثم ارجع. تتيح لك أوامر <cg>u في الوسط التراجع عن التصحيح بسرعة.

في الختام


بفضل مقتطفات Vim ، لم تعد كتابة رمز LaTeX مزعجًا ، بل هي متعة. في تركيبة مع الإملاء أثناء الطيران ، يتيح لك ذلك تحديد محاضرات الرياضيات بشكل مريح وسريع. في المقالة التالية ، سأتحدث عن مواضيع أخرى ، مثل رسم الرسوم التوضيحية رقميًا وإدراجها في مستند LaTeX.

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


All Articles