diff --git a/.github/workflows/gen-pdf.yaml b/.github/workflows/gen-pdf.yaml new file mode 100644 index 0000000..6ff3289 --- /dev/null +++ b/.github/workflows/gen-pdf.yaml @@ -0,0 +1,33 @@ +--- +name: Generate PDF using Pandoc (Docker) + +on: + push: + branches: + - master + workflow_dispatch: null + +jobs: + create_pdf: + runs-on: ubuntu-latest + container: + image: pandoc/latex:3 + steps: + - uses: actions/checkout@v7 + + - uses: docker://pandoc/latex:3 + timeout-minutes: 10 + with: + entrypoint: './pandoc-docker.sh' + + - id: short_sha + env: + GITHUB_SHA: ${{ github.sha }} + run: echo "short_sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT + + - uses: softprops/action-gh-release@v3 + with: + tag_name: version-${{ steps.short_sha.outputs.short_sha }} + draft: false + files: | + *.pdf diff --git a/content/asm_2.md b/content/asm_2.md index 7df69dc..38ee08d 100644 --- a/content/asm_2.md +++ b/content/asm_2.md @@ -3,6 +3,7 @@ Some days ago I wrote the first post about [Introduction to assembly](asm_1.md) which, to my surprise, caused great interest: ![newscombinator](./assets/newscombinator-screenshot.png) + ![reddit](./assets/reddit-screenshot.png) It motivated me to continue describing my journey through learning assembly programming for Linux x86_64. During these days I got great feedback from people all over the Internet. There were many words of gratitude, but, what is more important to me, there was also much adequate advice and very useful criticism. Especially, I want to say thank you for the great feedback to: @@ -59,7 +60,7 @@ You can find a detailed description of registers in the [Intel software develope There are 16 registers of 64 bits size, from `rax` to `r15`. Each register also has smaller parts with their own names. For example, as we may see in the table above, the lower 32 bits of the `rax` register are called `eax`. Similarly, the lower 16 bits of the `eax` register are called `ax`. Finally, the lower 8 bits of the `ax` register are called `al`, while the higher 8 bits are called `ah`. We can visualize this as: -![rax](./assets/rax.svg) +![rax](./assets/rax.png) The general purpose registers are used in many different cases, like performing arithmetic and logical operations, transferring data, memory address calculation operations, passing parameters to functions and system calls, and many more. When going through these chapters, we will see how to use the general purpose registers to perform different operations. @@ -312,15 +313,15 @@ These two instructions at the beginning of each function are called [function pr Now that we know the rough meaning of the stack frame and the usage of the `rbp`, `rsp`, and `rip` registers, let's try to understand what happens when we call a function. Let's look at the stack before the `call foo` is executed. Our stack looks like this: -![stack-before-call](./assets/stack-before-call.svg) +![stack-before-call](./assets/stack-before-call.png) After executing the `call` instruction, the return address (or address of the next instruction) is pushed to the stack. So our stack layout during the call looks like this: -![stack-during-call](./assets/stack-during-call.svg) +![stack-during-call](./assets/stack-during-call.png) At the beginning of every new function, we must preserve the current value of the `rbp` register by pushing it onto the stack. This value acts as a base pointer of the previous function. In other words, the value of the `rbp` at the beginning of each function represents the address of the bottom (or the base) of the caller's stack. Since we are in a new function, it needs a new stack frame and, as a result, a new base. At this point, the stack layout looks like this: -![stack-preserve-bp](./assets/stack-preserve-bp.svg) +![stack-preserve-bp](./assets/stack-preserve-bp.png) The next step is to put the current value of the stack pointer (`rsp`) into the `rbp` register. This marks the beginning of the new stack frame for our function `foo`. With the stack frame ready, we can start managing function parameters and local variables. @@ -334,7 +335,7 @@ Let's read once again the sentence from the paragraph above: What was the address stored in the `rbp` register? Our stack pointer! So after running the last `mov` instruction in the function `foo`, our stack frame looks like this: -![stack](./assets/stack.svg) +![stack](./assets/stack.png) That is the whole point of the `rbp` register. It plays the role of an anchor or a base point in the function. Using the positive offsets, we can access the return address and parameters pushed onto the stack by the caller. On the other hand, negative offsets allow us to access local variables of the current function. diff --git a/content/asm_3.md b/content/asm_3.md index ff7f0c5..111e89b 100644 --- a/content/asm_3.md +++ b/content/asm_3.md @@ -82,11 +82,11 @@ __double(int): After the first two lines of the `__double` function, the stack frame for this function is set and looks like this: -![asm-3-stack-fram-of__double-1](./assets/asm-3-stack-of__double-1.svg) +![asm-3-stack-fram-of__double-1](./assets/asm-3-stack-of__double-1.png) The third instruction of the `__double` function places its first parameter to the stack with an offset of `-20`. Next, the value `2`, representing the local variable two, is also stored on the stack with an offset of `-4`. At this point, the stack frame of our function looks like this: -![asm-3-stack-fram-of__double-2](./assets/asm-3-stack-of__double-2.svg) +![asm-3-stack-fram-of__double-2](./assets/asm-3-stack-of__double-2.png) Finally, we put the value from the stack at offset `-20` (the value of the function's parameter) into the `eax` register and multiply it by `2`, which is located on the stack at offset `-4`. The result of the multiplication is then stored in the `eax` register. This simple example shows how the stack is used to access both parameters and local variables of a function. @@ -353,7 +353,7 @@ Before calculating the sum of two numbers from the command-line arguments, we ne According to the table above, the command-line arguments are located on the stack like this: -![asm-3-args-on-stack](./assets/asm-3-args-on-stack.svg) +![asm-3-args-on-stack](./assets/asm-3-args-on-stack.png) As we can see, the number of command-line arguments passed to the program is stored at the top of the stack, with the `rsp` register pointing to it. Fetching this value from the stack gives us the number of arguments. Additionally, we already know the `cmp` instruction, which allows us to compare two values. Using this knowledge, we can perform the first check in our program — verifying that the program got two arguments from the command-line or printing an error message otherwise: diff --git a/content/assets/asm-3-args-on-stack.png b/content/assets/asm-3-args-on-stack.png new file mode 100644 index 0000000..64ce8ea Binary files /dev/null and b/content/assets/asm-3-args-on-stack.png differ diff --git a/content/assets/asm-3-stack-of__double-1.png b/content/assets/asm-3-stack-of__double-1.png new file mode 100644 index 0000000..20777e8 Binary files /dev/null and b/content/assets/asm-3-stack-of__double-1.png differ diff --git a/content/assets/asm-3-stack-of__double-2.png b/content/assets/asm-3-stack-of__double-2.png new file mode 100644 index 0000000..78233be Binary files /dev/null and b/content/assets/asm-3-stack-of__double-2.png differ diff --git a/content/assets/rax.png b/content/assets/rax.png new file mode 100644 index 0000000..01d832b Binary files /dev/null and b/content/assets/rax.png differ diff --git a/content/assets/stack-before-call.png b/content/assets/stack-before-call.png new file mode 100644 index 0000000..559b4a6 Binary files /dev/null and b/content/assets/stack-before-call.png differ diff --git a/content/assets/stack-during-call.png b/content/assets/stack-during-call.png new file mode 100644 index 0000000..198c78b Binary files /dev/null and b/content/assets/stack-during-call.png differ diff --git a/content/assets/stack-preserve-bp.png b/content/assets/stack-preserve-bp.png new file mode 100644 index 0000000..db09d7e Binary files /dev/null and b/content/assets/stack-preserve-bp.png differ diff --git a/content/assets/stack.png b/content/assets/stack.png new file mode 100644 index 0000000..bcee89f Binary files /dev/null and b/content/assets/stack.png differ diff --git a/include.tex b/include.tex new file mode 100644 index 0000000..31268a2 --- /dev/null +++ b/include.tex @@ -0,0 +1,36 @@ +\usepackage{enumitem} +\ifcsundef{c@none}{\newcounter{none}}{} +\setlistdepth{9} + +\setlist[itemize,1]{label=$\bullet$} +\setlist[itemize,2]{label=$\bullet$} +\setlist[itemize,3]{label=$\bullet$} +\setlist[itemize,4]{label=$\bullet$} +\setlist[itemize,5]{label=$\bullet$} +\setlist[itemize,6]{label=$\bullet$} +\setlist[itemize,7]{label=$\bullet$} +\setlist[itemize,8]{label=$\bullet$} +\setlist[itemize,9]{label=$\bullet$} +\renewlist{itemize}{itemize}{9} + +\setlist[enumerate,1]{label=$\arabic*.$} +\setlist[enumerate,2]{label=$\alph*.$} +\setlist[enumerate,3]{label=$\roman*.$} +\setlist[enumerate,4]{label=$\arabic*.$} +\setlist[enumerate,5]{label=$\alpha*$} +\setlist[enumerate,6]{label=$\roman*.$} +\setlist[enumerate,7]{label=$\arabic*.$} +\setlist[enumerate,8]{label=$\alph*.$} +\setlist[enumerate,9]{label=$\roman*.$} +\renewlist{enumerate}{enumerate}{9} + +\usepackage{float} +\makeatletter +\let\origfigure\figure +\let\endorigfigure\endfigure +\renewenvironment{figure}[1][2]{% + \expandafter\origfigure\expandafter[H]% +}{% + \endorigfigure +} +\makeatother diff --git a/pandoc-docker.sh b/pandoc-docker.sh new file mode 100755 index 0000000..2aa45ea --- /dev/null +++ b/pandoc-docker.sh @@ -0,0 +1,30 @@ +#! /bin/sh + +# Install dependencies for successful PDF generation +for i in 1 2 3 4 5; do + tlmgr update --self && break + echo "tlmgr attempt $i failed, retrying in 5s..." + sleep 5 +done + +for i in 1 2 3 4 5; do + tlmgr install collection-fontsrecommended ctex enumitem float \ + greek-fontenc koma-script polyglossia realscripts xltxtra && break + echo "tlmgr install attempt $i failed, retrying in 5s..." + sleep 5 +done + +# Generate PDF using pandoc +for filename in pandoc-*yaml; do + # Create variable for language based on filename + language=$(echo "${filename}" | cut -d'.' -f1 | cut -d'-' -f2-3) + + # Attempt to create the PDF + echo "Generating ${language} PDF..." + if pandoc -d "${filename}"; then + echo "Success! The ${language} PDF has been successfully created!" + else + echo "Failure! The ${language} PDF failed to be created!" + exit 1 + fi +done diff --git a/pandoc-en-US.yaml b/pandoc-en-US.yaml new file mode 100644 index 0000000..e6e76b7 --- /dev/null +++ b/pandoc-en-US.yaml @@ -0,0 +1,37 @@ +--- +metadata: + title: Introduction to the Assembly Programming Language + author: Alex Kuleshov + category: "License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License" + keywords: + - "assembly" + - "introduction" +standalone: true +variables: + documentclass: scrbook + lang: en-US + links-as-notes: true + lot: false + lof: false + margin-top: 1.27cm + margin-left: .635cm + margin-right: .635cm + margin-bottom: 1.27cm +table-of-contents: true +toc-depth: 2 +file-scope: true +from: markdown+rebase_relative_paths +include-in-header: include.tex +verbosity: ERROR +pdf-engine: xelatex +template: unicode.latex +input-files: + - ./content/asm_1.md + - ./content/asm_2.md + - ./content/asm_3.md + - ./content/asm_4.md + - ./content/asm_5.md + - ./content/asm_6.md + - ./content/asm_7.md +output-file: introduction-to-assembly.pdf +... diff --git a/pandoc.sh b/pandoc.sh new file mode 100755 index 0000000..2f5d5b1 --- /dev/null +++ b/pandoc.sh @@ -0,0 +1,35 @@ +#! /bin/bash + +# Generate PDF using pandoc +generate_pdfs() { + for filename in pandoc-*yaml; do + # Create variable for language based on filename + IFS=- read _ language <<< "${filename}" + language=${language/.yaml/} + + # Attempt to create the PDF + echo "Generating ${language} PDF..." + if pandoc -d "${filename}"; then + echo "Success! The ${language} PDF has been successfully created!" + else + echo "Failure! The ${language} PDF failed to be created!" + exit 1 + fi + done +} + +# Check for dependencies +check_dependencies () { + for dependency in "${dependencies[@]}" + do + if ! [ -x "$(command -v $dependency)" ]; then + echo "Error: $dependency is not installed." >&2 + exit 1 + fi + done +} + +dependencies=("pandoc" "tex") + +check_dependencies +generate_pdfs diff --git a/unicode.latex b/unicode.latex new file mode 100644 index 0000000..00e6d4c --- /dev/null +++ b/unicode.latex @@ -0,0 +1,646 @@ +% Options for packages loaded elsewhere +\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref} +\PassOptionsToPackage{hyphens}{url} +$if(colorlinks)$ +\PassOptionsToPackage{dvipsnames,svgnames,x11names}{xcolor} +$endif$ +$if(CJKmainfont)$ +\PassOptionsToPackage{space}{xeCJK} +$endif$ +% +\documentclass[ +$if(fontsize)$ + $fontsize$, +$endif$ +$if(papersize)$ + $papersize$paper, +$endif$ +$if(beamer)$ + ignorenonframetext, +$if(handout)$ + handout, +$endif$ +$if(aspectratio)$ + aspectratio=$aspectratio$, +$endif$ +$if(babel-lang)$ + $babel-lang$, +$endif$ +$endif$ +$for(classoption)$ + $classoption$$sep$, +$endfor$ +]{$documentclass$} +$if(beamer)$ +$if(background-image)$ +\usebackgroundtemplate{% + \includegraphics[width=\paperwidth]{$background-image$}% +} +% In beamer background-image does not work well when other images are used, so this is the workaround +\pgfdeclareimage[width=\paperwidth,height=\paperheight]{background}{$background-image$} +\usebackgroundtemplate{\pgfuseimage{background}} +$endif$ +\usepackage{pgfpages} +\setbeamertemplate{caption}[numbered] +\setbeamertemplate{caption label separator}{: } +\setbeamercolor{caption name}{fg=normal text.fg} +\beamertemplatenavigationsymbols$if(navigation)$$navigation$$else$empty$endif$ +$for(beameroption)$ +\setbeameroption{$beameroption$} +$endfor$ +% Prevent slide breaks in the middle of a paragraph +\widowpenalties 1 10000 +\raggedbottom +$if(section-titles)$ +\setbeamertemplate{part page}{ + \centering + \begin{beamercolorbox}[sep=16pt,center]{part title} + \usebeamerfont{part title}\insertpart\par + \end{beamercolorbox} +} +\setbeamertemplate{section page}{ + \centering + \begin{beamercolorbox}[sep=12pt,center]{part title} + \usebeamerfont{section title}\insertsection\par + \end{beamercolorbox} +} +\setbeamertemplate{subsection page}{ + \centering + \begin{beamercolorbox}[sep=8pt,center]{part title} + \usebeamerfont{subsection title}\insertsubsection\par + \end{beamercolorbox} +} +\AtBeginPart{ + \frame{\partpage} +} +\AtBeginSection{ + \ifbibliography + \else + \frame{\sectionpage} + \fi +} +\AtBeginSubsection{ + \frame{\subsectionpage} +} +$endif$ +$endif$ +$if(beamerarticle)$ +\usepackage{beamerarticle} % needs to be loaded first +$endif$ +\usepackage{amsmath,amssymb} +$if(linestretch)$ +\usepackage{setspace} +$endif$ +\usepackage{iftex} +\ifPDFTeX + \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc} + \usepackage[utf8]{inputenc} + \usepackage{textcomp} % provide euro and other symbols +\else % if luatex or xetex +$if(mathspec)$ + \ifXeTeX + \usepackage{mathspec} % this also loads fontspec + \else + \usepackage{unicode-math} % this also loads fontspec + \fi +$else$ + \usepackage{unicode-math} % this also loads fontspec +$endif$ + \defaultfontfeatures{Scale=MatchLowercase}$-- must come before Beamer theme + \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} +\fi +$if(fontfamily)$ +$else$ +$-- Set default font before Beamer theme so the theme can override it +\usepackage{lmodern} +$endif$ +$-- Set Beamer theme before user font settings so they can override theme +$if(beamer)$ +$if(theme)$ +\usetheme[$for(themeoptions)$$themeoptions$$sep$,$endfor$]{$theme$} +$endif$ +$if(colortheme)$ +\usecolortheme{$colortheme$} +$endif$ +$if(fonttheme)$ +\usefonttheme{$fonttheme$} +$endif$ +$if(mainfont)$ +\usefonttheme{serif} % use mainfont rather than sansfont for slide text +$endif$ +$if(innertheme)$ +\useinnertheme{$innertheme$} +$endif$ +$if(outertheme)$ +\useoutertheme{$outertheme$} +$endif$ +$endif$ +$-- User font settings (must come after default font and Beamer theme) +$if(fontfamily)$ +\usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$} +$endif$ +\ifPDFTeX\else + % xetex/luatex font selection +$if(mainfont)$ + $if(mainfontfallback)$ + \ifLuaTeX + \usepackage{luaotfload} + \directlua{luaotfload.add_fallback("mainfontfallback",{ + $for(mainfontfallback)$"$mainfontfallback$"$sep$,$endfor$ + })} + \fi + $endif$ + \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$$if(mainfontfallback)$,RawFeature={fallback=mainfontfallback}$endif$]{$mainfont$} +$endif$ +$if(sansfont)$ + $if(sansfontfallback)$ + \ifLuaTeX + \usepackage{luaotfload} + \directlua{luaotfload.add_fallback("sansfontfallback",{ + $for(sansfontfallback)$"$sansfontfallback$"$sep$,$endfor$ + })} + \fi + $endif$ + \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$$if(sansfontfallback)$,RawFeature={fallback=sansfontfallback}$endif$]{$sansfont$} +$endif$ +$if(monofont)$ + $if(monofontfallback)$ + \ifLuaTeX + \usepackage{luaotfload} + \directlua{luaotfload.add_fallback("monofontfallback",{ + $for(monofontfallback)$"$monofontfallback$"$sep$,$endfor$ + })} + \fi + $endif$ + \setmonofont[$for(monofontoptions)$$monofontoptions$$sep$,$endfor$$if(monofontfallback)$,RawFeature={fallback=monofontfallback}$endif$]{$monofont$} +$endif$ +$for(fontfamilies)$ + \newfontfamily{$fontfamilies.name$}[$for(fontfamilies.options)$$fontfamilies.options$$sep$,$endfor$]{$fontfamilies.font$} +$endfor$ +$if(mathfont)$ +$if(mathspec)$ + \ifXeTeX + \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} + \else + \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} + \fi +$else$ + \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} +$endif$ +$endif$ +$if(CJKmainfont)$ + \ifXeTeX + \usepackage{xeCJK} + \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} + $if(CJKsansfont)$ + \setCJKsansfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKsansfont$} + $endif$ + $if(CJKmonofont)$ + \setCJKmonofont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmonofont$} + $endif$ + \fi +$endif$ +$if(luatexjapresetoptions)$ + \ifLuaTeX + \usepackage[$for(luatexjapresetoptions)$$luatexjapresetoptions$$sep$,$endfor$]{luatexja-preset} + \fi +$endif$ +$if(CJKmainfont)$ + \ifLuaTeX + \usepackage[$for(luatexjafontspecoptions)$$luatexjafontspecoptions$$sep$,$endfor$]{luatexja-fontspec} + \setmainjfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} + \fi +$endif$ +\fi +$if(zero-width-non-joiner)$ +%% Support for zero-width non-joiner characters. +\makeatletter +\def\zerowidthnonjoiner{% + % Prevent ligatures and adjust kerning, but still support hyphenating. + \texorpdfstring{% + \TextOrMath{\nobreak\discretionary{-}{}{\kern.03em}% + \ifvmode\else\nobreak\hskip\z@skip\fi}{}% + }{}% +} +\makeatother +\ifPDFTeX + \DeclareUnicodeCharacter{200C}{\zerowidthnonjoiner} +\else + \catcode`^^^^200c=\active + \protected\def ^^^^200c{\zerowidthnonjoiner} +\fi +%% End of ZWNJ support +$endif$ +% Use upquote if available, for straight quotes in verbatim environments +\IfFileExists{upquote.sty}{\usepackage{upquote}}{} +\IfFileExists{microtype.sty}{% use microtype if available + \usepackage[$for(microtypeoptions)$$microtypeoptions$$sep$,$endfor$]{microtype} + \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts +}{} +$if(indent)$ +$else$ +\makeatletter +\@ifundefined{KOMAClassName}{% if non-KOMA class + \IfFileExists{parskip.sty}{% + \usepackage{parskip} + }{% else + \setlength{\parindent}{0pt} + \setlength{\parskip}{6pt plus 2pt minus 1pt}} +}{% if KOMA class + \KOMAoptions{parskip=half}} +\makeatother +$endif$ +$if(verbatim-in-note)$ +\usepackage{fancyvrb} +$endif$ +\usepackage{xcolor} +$if(geometry)$ +$if(beamer)$ +\geometry{$for(geometry)$$geometry$$sep$,$endfor$} +$else$ +\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} +$endif$ +$endif$ +$if(beamer)$ +\newif\ifbibliography +$endif$ +$if(listings)$ +\usepackage{listings} +\newcommand{\passthrough}[1]{#1} +\lstset{defaultdialect=[5.3]Lua} +\lstset{defaultdialect=[x86masm]Assembler} +$endif$ +$if(lhs)$ +\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} +$endif$ +$if(highlighting-macros)$ +$highlighting-macros$ +$endif$ +$if(tables)$ +\usepackage{longtable,booktabs,array} +$if(multirow)$ +\usepackage{multirow} +$endif$ +\usepackage{calc} % for calculating minipage widths +$if(beamer)$ +\usepackage{caption} +% Make caption package work with longtable +\makeatletter +\def\fnum@table{\tablename~\thetable} +\makeatother +$else$ +% Correct order of tables after \paragraph or \subparagraph +\usepackage{etoolbox} +\makeatletter +\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} +\makeatother +% Allow footnotes in longtable head/foot +\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} +\makesavenoteenv{longtable} +$endif$ +$endif$ +$if(graphics)$ +\usepackage{graphicx} +\makeatletter +\newsavebox\pandoc@box +\newcommand*\pandocbounded[1]{% scales image to fit in text height/width + \sbox\pandoc@box{#1}% + \Gscale@div\@tempa{\textheight}{\dimexpr\ht\pandoc@box+\dp\pandoc@box\relax}% + \Gscale@div\@tempb{\linewidth}{\wd\pandoc@box}% + \ifdim\@tempb\p@<\@tempa\p@\let\@tempa\@tempb\fi% select the smaller of both + \ifdim\@tempa\p@<\p@\scalebox{\@tempa}{\usebox\pandoc@box}% + \else\usebox{\pandoc@box}% + \fi% +} +% Set default figure placement to htbp +\def\fps@figure{htbp} +\makeatother +$endif$ +$if(svg)$ +\usepackage{svg} +$endif$ +$if(strikeout)$ +$-- also used for underline +\ifLuaTeX + \usepackage{luacolor} + \usepackage[soul]{lua-ul} +\else + \usepackage{soul} +$if(beamer)$ + \makeatletter + \let\HL\hl + \renewcommand\hl{% fix for beamer highlighting + \let\set@color\beamerorig@set@color + \let\reset@color\beamerorig@reset@color + \HL} + \makeatother +$endif$ +$if(CJKmainfont)$ + \ifXeTeX + % soul's \st doesn't work for CJK: + \usepackage{xeCJKfntef} + \renewcommand{\st}[1]{\sout{#1}} + \fi +$endif$ +\fi +$endif$ +\setlength{\emergencystretch}{3em} % prevent overfull lines +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} +$if(numbersections)$ +\setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$} +$else$ +\setcounter{secnumdepth}{-\maxdimen} % remove section numbering +$endif$ +$if(subfigure)$ +\usepackage{subcaption} +$endif$ +$if(beamer)$ +$else$ +$if(block-headings)$ +% Make \paragraph and \subparagraph free-standing +\makeatletter +\ifx\paragraph\undefined\else + \let\oldparagraph\paragraph + \renewcommand{\paragraph}{ + \@ifstar + \xxxParagraphStar + \xxxParagraphNoStar + } + \newcommand{\xxxParagraphStar}[1]{\oldparagraph*{#1}\mbox{}} + \newcommand{\xxxParagraphNoStar}[1]{\oldparagraph{#1}\mbox{}} +\fi +\ifx\subparagraph\undefined\else + \let\oldsubparagraph\subparagraph + \renewcommand{\subparagraph}{ + \@ifstar + \xxxSubParagraphStar + \xxxSubParagraphNoStar + } + \newcommand{\xxxSubParagraphStar}[1]{\oldsubparagraph*{#1}\mbox{}} + \newcommand{\xxxSubParagraphNoStar}[1]{\oldsubparagraph{#1}\mbox{}} +\fi +\makeatother +$endif$ +$endif$ +$if(pagestyle)$ +\pagestyle{$pagestyle$} +$endif$ +$if(csl-refs)$ +% definitions for citeproc citations +\NewDocumentCommand\citeproctext{}{} +\NewDocumentCommand\citeproc{mm}{% + \begingroup\def\citeproctext{#2}\cite{#1}\endgroup} +\makeatletter + % allow citations to break across lines + \let\@cite@ofmt\@firstofone + % avoid brackets around text for \cite: + \def\@biblabel#1{} + \def\@cite#1#2{{#1\if@tempswa , #2\fi}} +\makeatother +\newlength{\cslhangindent} +\setlength{\cslhangindent}{1.5em} +\newlength{\csllabelwidth} +\setlength{\csllabelwidth}{3em} +\newenvironment{CSLReferences}[2] % #1 hanging-indent, #2 entry-spacing + {\begin{list}{}{% + \setlength{\itemindent}{0pt} + \setlength{\leftmargin}{0pt} + \setlength{\parsep}{0pt} + % turn on hanging indent if param 1 is 1 + \ifodd #1 + \setlength{\leftmargin}{\cslhangindent} + \setlength{\itemindent}{-1\cslhangindent} + \fi + % set entry spacing + \setlength{\itemsep}{#2\baselineskip}}} + {\end{list}} +\usepackage{calc} +\newcommand{\CSLBlock}[1]{\hfill\break\parbox[t]{\linewidth}{\strut\ignorespaces#1\strut}} +\newcommand{\CSLLeftMargin}[1]{\parbox[t]{\csllabelwidth}{\strut#1\strut}} +\newcommand{\CSLRightInline}[1]{\parbox[t]{\linewidth - \csllabelwidth}{\strut#1\strut}} +\newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1} +$endif$ +$if(lang)$ +\ifLuaTeX +\usepackage[bidi=basic]{babel} +\else +\usepackage[bidi=default]{babel} +\fi +$if(babel-lang)$ +\babelprovide[main,import]{$babel-lang$} +$if(mainfont)$ +\ifPDFTeX +\else +\babelfont{rm}[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$$if(mainfontfallback)$,RawFeature={fallback=mainfontfallback}$endif$]{$mainfont$} +\fi +$endif$ +$endif$ +$for(babel-otherlangs)$ +\babelprovide[import]{$babel-otherlangs$} +$endfor$ +$for(babelfonts/pairs)$ +\babelfont[$babelfonts.key$]{rm}{$babelfonts.value$} +$endfor$ +% get rid of language-specific shorthands (see #6817): +\let\LanguageShortHands\languageshorthands +\def\languageshorthands#1{} +$if(selnolig-langs)$ +\ifLuaTeX + \usepackage[$for(selnolig-langs)$$it$$sep$,$endfor$]{selnolig} % disable illegal ligatures +\fi +$endif$ +$endif$ +$for(header-includes)$ +$header-includes$ +$endfor$ +$if(dir)$ +\ifPDFTeX + \TeXXeTstate=1 + \newcommand{\RL}[1]{\beginR #1\endR} + \newcommand{\LR}[1]{\beginL #1\endL} + \newenvironment{RTL}{\beginR}{\endR} + \newenvironment{LTR}{\beginL}{\endL} +\fi +$endif$ +$if(natbib)$ +\usepackage[$natbiboptions$]{natbib} +\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$} +$endif$ +$if(biblatex)$ +\usepackage[$if(biblio-style)$style=$biblio-style$,$endif$$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$]{biblatex} +$for(bibliography)$ +\addbibresource{$bibliography$} +$endfor$ +$endif$ +$if(nocite-ids)$ +\nocite{$for(nocite-ids)$$it$$sep$, $endfor$} +$endif$ +$if(csquotes)$ +\usepackage{csquotes} +$endif$ +\usepackage{bookmark} +\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available +\urlstyle{$if(urlstyle)$$urlstyle$$else$same$endif$} +$if(links-as-notes)$ +% Make links footnotes instead of hotlinks: +\DeclareRobustCommand{\href}[2]{#2\footnote{\url{#1}}} +$endif$ +$if(verbatim-in-note)$ +\VerbatimFootnotes % allow verbatim text in footnotes +$endif$ +\hypersetup{ +$if(title-meta)$ + pdftitle={$title-meta$}, +$endif$ +$if(author-meta)$ + pdfauthor={$author-meta$}, +$endif$ +$if(lang)$ + pdflang={$lang$}, +$endif$ +$if(subject)$ + pdfsubject={$subject$}, +$endif$ +$if(keywords)$ + pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$}, +$endif$ +$if(colorlinks)$ + colorlinks=true, + linkcolor={$if(linkcolor)$$linkcolor$$else$Maroon$endif$}, + filecolor={$if(filecolor)$$filecolor$$else$Maroon$endif$}, + citecolor={$if(citecolor)$$citecolor$$else$Blue$endif$}, + urlcolor={$if(urlcolor)$$urlcolor$$else$Blue$endif$}, +$else$ +$if(boxlinks)$ +$else$ + hidelinks, +$endif$ +$endif$ + pdfcreator={LaTeX via pandoc}} + +$if(title)$ +\title{$title$$if(thanks)$\thanks{$thanks$}$endif$} +$endif$ +$if(subtitle)$ +$if(beamer)$ +$else$ +\usepackage{etoolbox} +\makeatletter +\providecommand{\subtitle}[1]{% add subtitle to \maketitle + \apptocmd{\@title}{\par {\large #1 \par}}{}{} +} +\makeatother +$endif$ +\subtitle{$subtitle$} +$endif$ +\author{$for(author)$$author$$sep$ \and $endfor$} +\date{$date$} +$if(beamer)$ +$if(institute)$ +\institute{$for(institute)$$institute$$sep$ \and $endfor$} +$endif$ +$if(titlegraphic)$ +\titlegraphic{\includegraphics$if(titlegraphicoptions)$[$for(titlegraphicoptions)$$titlegraphicoptions$$sep$, $endfor$]$endif${$titlegraphic$}} +$endif$ +$if(logo)$ +\logo{\includegraphics{$logo$}} +$endif$ +$endif$ + +\begin{document} +$if(has-frontmatter)$ +\frontmatter +$endif$ +$if(title)$ +$if(beamer)$ +\frame{\titlepage} +$else$ +\maketitle +$endif$ +$if(abstract)$ +\begin{abstract} +$abstract$ +\end{abstract} +$endif$ +$endif$ + +$for(include-before)$ +$include-before$ + +$endfor$ +$if(toc)$ +$if(toc-title)$ +\renewcommand*\contentsname{$toc-title$} +$endif$ +$if(beamer)$ +\begin{frame}[allowframebreaks] +$if(toc-title)$ + \frametitle{$toc-title$} +$endif$ + \setcounter{tocdepth}{$toc-depth$} + \tableofcontents +\end{frame} +$else$ +{ +$if(colorlinks)$ +\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$$endif$} +$endif$ +\setcounter{tocdepth}{$toc-depth$} +\tableofcontents +} +$endif$ +$endif$ +$if(lof)$ +\listoffigures +$endif$ +$if(lot)$ +\listoftables +$endif$ +$if(linestretch)$ +\setstretch{$linestretch$} +$endif$ +$if(has-frontmatter)$ +\mainmatter +$endif$ +$body$ + +$if(has-frontmatter)$ +\backmatter +$endif$ +$if(natbib)$ +$if(bibliography)$ +$if(biblio-title)$ +$if(has-chapters)$ +\renewcommand\bibname{$biblio-title$} +$else$ +\renewcommand\refname{$biblio-title$} +$endif$ +$endif$ +$if(beamer)$ +\begin{frame}[allowframebreaks]{$biblio-title$} + \bibliographytrue +$endif$ + \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} +$if(beamer)$ +\end{frame} +$endif$ + +$endif$ +$endif$ +$if(biblatex)$ +$if(beamer)$ +\begin{frame}[allowframebreaks]{$biblio-title$} + \bibliographytrue + \printbibliography[heading=none] +\end{frame} +$else$ +\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ +$endif$ + +$endif$ +$for(include-after)$ +$include-after$ + +$endfor$ +\end{document}