From b3da58a3352dd7d9f9b977695f8f7b3f48d1bcc2 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Thu, 16 Nov 2023 17:39:48 +0100 Subject: introduce a new default beamer template --- common.mk | 8 +- pandoc/center-img.lua | 20 -- pandoc/defaults/slides-metadata.yml | 1 + pandoc/filters/center-img.lua | 20 ++ pandoc/filters/include-files.lua | 120 ++++++++ pandoc/filters/minted.lua | 454 ++++++++++++++++++++++++++++ pandoc/include-files.lua | 120 -------- pandoc/minted.lua | 454 ---------------------------- pandoc/templates/beamer.tex | 584 ++++++++++++++++++++++++++++++++++++ templates/slides.md | 15 +- 10 files changed, 1194 insertions(+), 602 deletions(-) delete mode 100644 pandoc/center-img.lua create mode 100644 pandoc/filters/center-img.lua create mode 100644 pandoc/filters/include-files.lua create mode 100644 pandoc/filters/minted.lua delete mode 100644 pandoc/include-files.lua delete mode 100644 pandoc/minted.lua create mode 100644 pandoc/templates/beamer.tex diff --git a/common.mk b/common.mk index 14c96a0a..a7a8535b 100644 --- a/common.mk +++ b/common.mk @@ -6,15 +6,17 @@ MAKEFILE_DIR ?= $(dir $(MAKEFILE_PATH)) IMGS := $(wildcard img/*) LATEX_BASE := $(MAKEFILE_DIR)latex -PANDOC_DIR := $(MAKEFILE_DIR)pandoc COMMON_IMAGES := $(LATEX_BASE)/images +PANDOC_DIR := $(MAKEFILE_DIR)pandoc +PANDOC_FILTER_DIR := $(PANDOC_DIR)/filters +PANDOC_TEMPLATE_DIR := $(PANDOC_DIR)/templates PANDOC_CITE_OPTIONS := --citeproc --csl=$(PANDOC_DIR)/din-1505-2-numeric-alphabetical.csl -PANDOC_FILTER_OPTIONS := --lua-filter "$(PANDOC_DIR)/center-img.lua" --lua-filter "$(PANDOC_DIR)/include-files.lua" +PANDOC_FILTER_OPTIONS := --lua-filter "$(PANDOC_FILTER_DIR)/center-img.lua" --lua-filter "$(PANDOC_FILTER_DIR)/include-files.lua" COMMON_PANDOC_OPTIONS := --pdf-engine=lualatex --resource-path="$(COMMON_IMAGES):." $(PANDOC_CITE_OPTIONS) $(PANDOC_FILTER_OPTIONS) PANDOC := pandoc $(COMMON_PANDOC_OPTIONS) -SLIDES_OPTIONS := --slide-level 2 -t beamer --pdf-engine-opt=--shell-escape --metadata-file=$(PANDOC_DIR)/defaults/slides-metadata.yml +SLIDES_OPTIONS := --slide-level 2 -t beamer --pdf-engine-opt=--shell-escape --metadata-file=$(PANDOC_DIR)/defaults/slides-metadata.yml --template=$(PANDOC_TEMPLATE_DIR)/beamer.tex RUBBER_OPTS := --into .build -m lualatex:pdf --shell-escape -I "$(LATEX_BASE)" diff --git a/pandoc/center-img.lua b/pandoc/center-img.lua deleted file mode 100644 index 18782725..00000000 --- a/pandoc/center-img.lua +++ /dev/null @@ -1,20 +0,0 @@ --- Based on: --- https://pandoc.org/lua-filters.html#center-images-in-latex-and-html-output --- Licensed under MIT License found at: --- https://github.com/TomBener/pandoc-templates/blob/05aba224519d8a2b037108948bde0d820860b786/LICENSE - --- Filter images with this function if the target format is LaTeX. -if FORMAT:match('beamer') then - function Image(elem) - -- Surround all images with the 'center' class with image-centering raw LaTeX. - if elem.classes[1] == "center" then - return { - pandoc.RawInline('latex', '\\hfill\\break{\\centering'), - elem, - pandoc.RawInline('latex', '\\par}') - } - else - return elem - end - end -end diff --git a/pandoc/defaults/slides-metadata.yml b/pandoc/defaults/slides-metadata.yml index 026faebe..74593625 100644 --- a/pandoc/defaults/slides-metadata.yml +++ b/pandoc/defaults/slides-metadata.yml @@ -3,5 +3,6 @@ author: Florian Fischer lang: de theme: metropolis aspectratio: 169 +classoption: table --- diff --git a/pandoc/filters/center-img.lua b/pandoc/filters/center-img.lua new file mode 100644 index 00000000..18782725 --- /dev/null +++ b/pandoc/filters/center-img.lua @@ -0,0 +1,20 @@ +-- Based on: +-- https://pandoc.org/lua-filters.html#center-images-in-latex-and-html-output +-- Licensed under MIT License found at: +-- https://github.com/TomBener/pandoc-templates/blob/05aba224519d8a2b037108948bde0d820860b786/LICENSE + +-- Filter images with this function if the target format is LaTeX. +if FORMAT:match('beamer') then + function Image(elem) + -- Surround all images with the 'center' class with image-centering raw LaTeX. + if elem.classes[1] == "center" then + return { + pandoc.RawInline('latex', '\\hfill\\break{\\centering'), + elem, + pandoc.RawInline('latex', '\\par}') + } + else + return elem + end + end +end diff --git a/pandoc/filters/include-files.lua b/pandoc/filters/include-files.lua new file mode 100644 index 00000000..f9f208e9 --- /dev/null +++ b/pandoc/filters/include-files.lua @@ -0,0 +1,120 @@ +--- include-files.lua – filter to include Markdown files +--- +--- Copyright: © 2019–2021 Albert Krewinkel +--- License: MIT – see LICENSE file for details + +-- Module pandoc.path is required and was added in version 2.12 +PANDOC_VERSION:must_be_at_least '2.12' + +local List = require 'pandoc.List' +local path = require 'pandoc.path' +local system = require 'pandoc.system' + +--- Get include auto mode +local include_auto = false +function get_vars (meta) + if meta['include-auto'] then + include_auto = true + end +end + +--- Keep last heading level found +local last_heading_level = 0 +function update_last_level(header) + last_heading_level = header.level +end + +--- Update contents of included file +local function update_contents(blocks, shift_by, include_path) + local update_contents_filter = { + -- Shift headings in block list by given number + Header = function (header) + if shift_by then + header.level = header.level + shift_by + end + return header + end, + -- If image paths are relative then prepend include file path + Image = function (image) + if path.is_relative(image.src) then + image.src = path.normalize(path.join({include_path, image.src})) + end + return image + end, + -- Update path for include-code-files.lua filter style CodeBlocks + CodeBlock = function (cb) + if cb.attributes.include and path.is_relative(cb.attributes.include) then + cb.attributes.include = + path.normalize(path.join({include_path, cb.attributes.include})) + end + return cb + end + } + + return pandoc.walk_block(pandoc.Div(blocks), update_contents_filter).content +end + +--- Filter function for code blocks +local transclude +function transclude (cb) + -- ignore code blocks which are not of class "include". + if not cb.classes:includes 'include' then + return + end + + -- Markdown is used if this is nil. + local format = cb.attributes['format'] + + -- Attributes shift headings + local shift_heading_level_by = 0 + local shift_input = cb.attributes['shift-heading-level-by'] + if shift_input then + shift_heading_level_by = tonumber(shift_input) + else + if include_auto then + -- Auto shift headings + shift_heading_level_by = last_heading_level + end + end + + --- keep track of level before recusion + local buffer_last_heading_level = last_heading_level + + local blocks = List:new() + for line in cb.text:gmatch('[^\n]+') do + if line:sub(1,2) ~= '//' then + local fh = io.open(line) + if not fh then + io.stderr:write("Cannot open file " .. line .. " | Skipping includes\n") + else + -- read file as the given format with global reader options + local contents = pandoc.read( + fh:read '*a', + format, + PANDOC_READER_OPTIONS + ).blocks + last_heading_level = 0 + -- recursive transclusion + contents = system.with_working_directory( + path.directory(line), + function () + return pandoc.walk_block( + pandoc.Div(contents), + { Header = update_last_level, CodeBlock = transclude } + ) + end).content + --- reset to level before recursion + last_heading_level = buffer_last_heading_level + blocks:extend(update_contents(contents, shift_heading_level_by, + path.directory(line))) + fh:close() + end + end + end + return blocks +end + +return { + { Meta = get_vars }, + { Header = update_last_level, CodeBlock = transclude } +} diff --git a/pandoc/filters/minted.lua b/pandoc/filters/minted.lua new file mode 100644 index 00000000..68db5f0b --- /dev/null +++ b/pandoc/filters/minted.lua @@ -0,0 +1,454 @@ +--[[ +minted -- enable the minted environment for code listings in beamer and latex. + +MIT License + +Copyright (c) 2019 Stephen McDowell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +]] + +-------------------------------------------------------------------------------- +-- Quick documentation. See full documentation here: -- +-- https://github.com/pandoc/lua-filters/blob/master/minted -- +-------------------------------------------------------------------------------- +--[[ +Brief overview of metadata keys that you can use in your document: + +minted: + no_default_autogobble: , *DISCOURAGED* + no_mintinline: + default_block_language: + default_inline_language: + block_attributes: + - attr_1 + - attr_2 + - ... + inline_attributes: + - attr_1 + - attr_2 + - ... + +In words, underneath the `minted` metadata key, you have the following options: + +### `no_default_autogobble` (boolean) + +By default this filter will always use `autogobble` with minted, which will +automatically trim common preceding whitespace. This is important because +code blocks nested under a list or other block elements _will_ have common +preceding whitespace that you _will_ want trimmed. + +### `no_mintinline` (boolean) + +Globally prevent this filter from emitting `\mintinline` calls for inline +Code elements, emitting `\texttt` instead. Possibly useful in saving +compile time for large documents that do not seek to have syntax +highlighting on inline code elements. + +### `default_block_language` (string) + +The default pygments lexer class to use for code blocks. By default this +is `"text"`, meaning no syntax highlighting. This is a fallback value, code +blocks that explicitly specify a lexer will not use it. + +### `default_inline_language` (string) + +Same as `default_block_language`, only for inline code (typed in single +backticks). The default is also `"text"`, and changing is discouraged. + +### `block_attributes` (list of strings) + +Any default attributes to apply to _all_ code blocks. These may be +overridden on a per-code-block basis. See section 5.3 of the +[minted documentation][minted_docs] for available options. + +### `inline_attributes` (list of strings) + +Any default attributes to apply to _all_ inline code. These may be +overridden on a per-code basis. See section 5.3 of the +[minted documentation][minted_docs] for available options. + +[minted_docs]: http://mirrors.ctan.org/macros/latex/contrib/minted/minted.pdf +]] + +local List = require('pandoc.List') + +-------------------------------------------------------------------------------- +-- Potential metadata elements to override. -- +-------------------------------------------------------------------------------- +local minted_no_mintinline = false +local minted_default_block_language = "text" +local minted_default_inline_language = "text" +local minted_block_attributes = {} +local minted_inline_attributes = {} + +-------------------------------------------------------------------------------- +-- Constants used to differentiate Code and CodeBlock elements. -- +-------------------------------------------------------------------------------- +local MintedInline = 0 +local MintedBlock = 1 + +-------------------------------------------------------------------------------- +-- Utility functions. -- +-------------------------------------------------------------------------------- +-- Return the string lexer class to be used with minted. `elem` should be +-- either a Code or CodeBlock element (whose `classes` list will be inspected +-- first). `kind` is assumed to be either `MintedInline` or `MintedBlock` in +-- order to choose the appropriate fallback lexer when unspecified. +local function minted_language(elem, kind) + -- If the code [block] attached classes, we assume the first one is the + -- lexer class to use. + if #elem.classes > 0 then + return elem.classes[1] + end + -- Allow user-level metadata to override the inline language. + if kind == MintedInline then + return minted_default_inline_language + end + -- Allow user-level metadata to override the block language. + if kind == MintedBlock then + return minted_default_block_language + end + + -- Failsafe, should not hit here unless function called incorrectly. + return "text" +end + +-- Returns a boolean specifying whether or not the specified string `cls` is an +-- option that is supported by the minted package. +local function is_minted_class(cls) + -- Section 5.3 Available Options of Minted documentation. Note that many of + -- these do not apply to \mintinline (inline Code). Users are responsible + -- for supplying valid arguments to minted. For example, specifying + -- `autogobble` and `gobble` at the same time is a usage error. + -- + -- http://mirrors.ctan.org/macros/latex/contrib/minted/minted.pdf + local all_minted_options = List:new{ + "autogobble", "baselinestretch", "beameroverlays", "breakafter", + "breakaftergroup", "breakaftersymbolpre", "breakaftersymbolpost", + "breakanywhere", "breakanywheresymbolpre", "breakanywheresymbolpost", + "breakautoindent", "breakbefore", "breakbeforegroup", + "breakbeforesymbolpre", "breakbeforesymbolpost", "breakbytoken", + "breakbytokenanywhere", "breakindent", "breakindentnchars", "breaklines", + "breaksymbol", "breaksymbolleft", "breaksymbolright", "breaksymbolindent", + "breaksymbolindentnchars", "breaksymbolindentleft", + "breaksymbolindentleftnchars", "breaksymbolindentright", + "breaksymbolindentrightnchars", "breaksymbolsep", "breaksymbolsepnchars", + "breaksymbolsepleft", "breaksymbolsepleftnchars", "breaksymbolsepright", + "breaksymbolseprightnchars", "bgcolor", "codetagify", "curlyquotes", + "encoding", "escapeinside", "firstline", "firstnumber", "fontfamily", + "fontseries", "fontsize", "fontshape", "formatcom", "frame", "framerule", + "framesep", "funcnamehighlighting", "gobble", "highlightcolor", + "highlightlines", "keywordcase", "label", "labelposition", "lastline", + "linenos", "numberfirstline", "numbers", "mathescape", "numberblanklines", + "numbersep", "obeytabs", "outencoding", "python3", "resetmargins", + "rulecolor", "samepage", "showspaces", "showtabs", "space", "spacecolor", + "startinline", "style", "stepnumber", "stepnumberfromfirst", + "stepnumberoffsetvalues", "stripall", "stripnl", "tab", "tabcolor", + "tabsize", "texcl", "texcomments", "xleftmargin", "xrightmargin" + } + return all_minted_options:includes(cls, 0) +end + +-- Return a string for the minted attributes `\begin{minted}[attributes]` or +-- `\mintinline[attributes]`. Attributes are acquired by inspecting the +-- specified element's `classes` and `attr` fields. Any global attributes +-- provided in the document metadata will be included _only_ if they do not +-- override the element-level attributes. +-- +-- `elem` should either be a Code or CodeBlock element, and `kind` is assumed to +-- be either `MintedInline` or `MintedBlock`. The `kind` determines which +-- global default attribute list to use. +local function minted_attributes(elem, kind) + -- The full listing of attributes that will be joined and returned. + local minted_attributes = {} + + -- Book-keeping, track xxx=yyy keys `xxx` that have been added to + -- `minted_attributes` to make checking optional global defaults via the + -- `block_attributes` or `inline_attributes` easier. + local minted_keys = {} + + -- Boolean style options for minted (e.g., ```{.bash .autogobble}) will appear + -- in the list of classes. + for _, cls in ipairs(elem.classes) do + if is_minted_class(cls) then + table.insert(minted_attributes, cls) + table.insert(minted_keys, cls) + end + end + + -- Value options using key=value (e.g., ```{.bash fontsize=\scriptsize}) show + -- up in the list of attributes. + for cls, value in pairs(elem.attributes) do + if is_minted_class(cls) then + table.insert(minted_attributes, cls .. "=" .. value) + table.insert(minted_keys, cls) + end + end + + -- Add any global defaults _only_ if they do not conflict. Note that conflict + -- is only in the literal sense. If a user has `autogobble` and `gobble=2` + -- specified, these do conflict in the minted sense, but this filter makes no + -- checks on validity ;) + local global_defaults = nil + if kind == MintedInline then + global_defaults = minted_inline_attributes + elseif kind == MintedBlock then + global_defaults = minted_block_attributes + end + for _, global_attr in ipairs(global_defaults) do + -- Either use the index of `=` minus one, or -1 if no `=` present. Fallback + -- on -1 means that the substring is the original string. + local end_idx = (string.find(global_attr, "=") or 0) - 1 + local global_key = string.sub(global_attr, 1, end_idx) + local can_insert_global = true + for _, existing_key in ipairs(minted_keys) do + if existing_key == global_key then + can_insert_global = false + break + end + end + + if can_insert_global then + table.insert(minted_attributes, global_attr) + end + end + + -- Return a comma delimited string for specifying the attributes to minted. + return table.concat(minted_attributes, ",") +end + +-- Return the specified `elem` with any minted data removed from the `classes` +-- and `attr`. Otherwise writers such as the HTML writer might produce invalid +-- code since latex makes heavy use of the \backslash. +local function remove_minted_attibutes(elem) + -- Remove any minted items from the classes. + classes = {} + for _, cls in ipairs(elem.classes) do + if not is_minted_class(cls) and cls ~= "no_minted" then + table.insert(classes, cls) + end + end + elem.classes = classes + + -- Remove any minted items from the attributes. + extra_attrs = {} + for cls, value in pairs(elem.attributes) do + if not is_minted_class(cls) then + table.insert(extra_attrs, {cls, value}) + end + end + elem.attributes = extra_attrs + + -- Return the (potentially modified) element for pandoc to take over. + return elem +end + +-- Return a `start_delim` and `end_delim` that can safely wrap around the +-- specified `text` when used inline. If no special characters occur in `text`, +-- then a pair of braces are returned. Otherwise, if any character of +-- `possible_delims` are not in `text`, then it is returned. If no delimiter +-- could be found, an error is raised. +local function minted_inline_delims(text) + local start_delim, end_delim + if text:find('[{}]') then + -- Try some other delimiter (the alphanumeric digits are in Python's + -- string.digits + string.ascii_letters order) + possible_delims = ('|!@#^&*-=+' .. '0123456789' .. + 'abcdefghijklmnopqrstuvwxyz' .. + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + for char in possible_delims:gmatch('.') do + if not text:find(char, 1, true) then + start_delim = char + end_delim = char + break + end + end + if not start_delim then + local msg = 'Unable to determine delimiter to use around inline code %q' + error(msg:format(text)) + end + else + start_delim = '{' + end_delim = '}' + end + + return start_delim, end_delim +end + +-------------------------------------------------------------------------------- +-- Pandoc overrides. -- +-------------------------------------------------------------------------------- +-- Override the pandoc Meta function so that we can parse the metadata for the +-- document and store the necessary variables locally to use in other functions +-- such as Code and CodeBlock (helper methods). +function Meta(m) + -- Grab the `minted` metadata, quit early if not present. + local minted = m["minted"] + local found_autogobble = false + local always_autogobble = true + if minted ~= nil then + -- Parse and set the global bypass to turn off all \mintinline calls. + local no_mintinline = minted["no_mintinline"] + if no_mintinline ~= nil then + minted_no_mintinline = no_mintinline + end + + -- Parse and set the default block language. + local default_block_language = minted.default_block_language + and pandoc.utils.stringify(minted.default_block_language) + if default_block_language ~= nil then + minted_default_block_language = default_block_language + end + + -- Parse and set the default inline language. + local default_inline_language = minted.default_inline_language + and pandoc.utils.stringify(minted.default_inline_language) + if default_inline_language ~= nil then + minted_default_inline_language = default_inline_language + end + + -- Parse the global default minted attributes to use on every block. + local block_attributes = minted["block_attributes"] + if block_attributes ~= nil then + for _, attr in ipairs(block_attributes) do + if attr == "autogobble" then + found_autogobble = true + end + table.insert(minted_block_attributes, attr[1].text) + end + end + + -- Allow users to turn off autogobble for blocks, but really they should not + -- ever seek to do this (indented code blocks under list for example). + local no_default_autogobble = minted["no_default_autogobble"] + if no_default_autogobble ~= nil then + always_autogobble = not no_default_autogobble + end + + -- Parse the global default minted attributes to use on ever inline. + local inline_attributes = minted["inline_attributes"] + if inline_attributes ~= nil then + for _, attr in ipairs(inline_attributes) do + table.insert(minted_inline_attributes, attr[1].text) + end + end + end + + -- Make sure autogobble is turned on by default if no `minted` meta key is + -- provided for the document. + if always_autogobble and not found_autogobble then + table.insert(minted_block_attributes, "autogobble") + end + + -- Return the metadata to pandoc (unchanged). + return m +end + +-- Override inline code elements to use \mintinline for beamer / latex writers. +-- Other writers have all minted attributes removed. +function Code(elem) + if FORMAT == "beamer" or FORMAT == "latex" then + -- Allow a bypass to turn off \mintinline via adding .no_minted class. + local found_no_minted_class = false + for _, cls in ipairs(elem.classes) do + if cls == "no_minted" then + found_no_minted_class = true + break + end + end + + -- Check for local or global bypass to turn off \mintinline + if minted_no_mintinline or found_no_minted_class then + return nil -- Return `nil` signals to `pandoc` that elem is not changed. + end + + local start_delim, end_delim = minted_inline_delims(elem.text) + local language = minted_language(elem, MintedInline) + local attributes = minted_attributes(elem, MintedInline) + local raw_minted = string.format( + "\\mintinline[%s]{%s}%s%s%s", + attributes, + language, + start_delim, + elem.text, + end_delim + ) + -- NOTE: prior to pandoc commit 24a0d61, `beamer` cannot be used as the + -- RawBlock format. Using `latex` should not cause any problems. + return pandoc.RawInline("latex", raw_minted) + else + return remove_minted_attibutes(elem) + end +end + +-- Override code blocks to use \begin{minted}...\end{minted} for beamer / latex +-- writers. Other writers have all minted attributes removed. +function CodeBlock(block) + if FORMAT == "beamer" or FORMAT == "latex" then + local language = minted_language(block, MintedBlock) + local attributes = minted_attributes(block, MintedBlock) + local raw_minted = string.format( + "\\begin{minted}[%s]{%s}\n%s\n\\end{minted}", + attributes, + language, + block.text + ) + -- NOTE: prior to pandoc commit 24a0d61, `beamer` cannot be used as the + -- RawBlock format. Using `latex` should not cause any problems. + return pandoc.RawBlock("latex", raw_minted) + else + return remove_minted_attibutes(block) + end +end + +-- Override headers to make all beamer frames fragile, since any minted +-- environments or \mintinline invocations will halt compilation if the frame +-- is not marked as fragile. +function Header(elem) + if FORMAT == 'beamer' then + -- Check first that 'fragile' is not already present. + local has_fragile = false + for _, val in ipairs(elem.classes) do + if val == 'fragile' then + has_fragile = true + break + end + end + + -- If not found, add fragile to the list of classes. + if not has_fragile then + table.insert(elem.classes, 'fragile') + end + + -- NOTE: pass the remaining work to pandoc, noting that 2.5 and below + -- may duplicate the 'fragile' specifier. Duplicated fragile does *not* + -- cause compile errors. + return elem + end +end + +-- NOTE: order of return matters, Meta needs to be first otherwise the metadata +-- from the document will not be loaded _first_. +return { + {Meta = Meta}, + {Code = Code}, + {CodeBlock = CodeBlock}, + {Header = Header} +} diff --git a/pandoc/include-files.lua b/pandoc/include-files.lua deleted file mode 100644 index f9f208e9..00000000 --- a/pandoc/include-files.lua +++ /dev/null @@ -1,120 +0,0 @@ ---- include-files.lua – filter to include Markdown files ---- ---- Copyright: © 2019–2021 Albert Krewinkel ---- License: MIT – see LICENSE file for details - --- Module pandoc.path is required and was added in version 2.12 -PANDOC_VERSION:must_be_at_least '2.12' - -local List = require 'pandoc.List' -local path = require 'pandoc.path' -local system = require 'pandoc.system' - ---- Get include auto mode -local include_auto = false -function get_vars (meta) - if meta['include-auto'] then - include_auto = true - end -end - ---- Keep last heading level found -local last_heading_level = 0 -function update_last_level(header) - last_heading_level = header.level -end - ---- Update contents of included file -local function update_contents(blocks, shift_by, include_path) - local update_contents_filter = { - -- Shift headings in block list by given number - Header = function (header) - if shift_by then - header.level = header.level + shift_by - end - return header - end, - -- If image paths are relative then prepend include file path - Image = function (image) - if path.is_relative(image.src) then - image.src = path.normalize(path.join({include_path, image.src})) - end - return image - end, - -- Update path for include-code-files.lua filter style CodeBlocks - CodeBlock = function (cb) - if cb.attributes.include and path.is_relative(cb.attributes.include) then - cb.attributes.include = - path.normalize(path.join({include_path, cb.attributes.include})) - end - return cb - end - } - - return pandoc.walk_block(pandoc.Div(blocks), update_contents_filter).content -end - ---- Filter function for code blocks -local transclude -function transclude (cb) - -- ignore code blocks which are not of class "include". - if not cb.classes:includes 'include' then - return - end - - -- Markdown is used if this is nil. - local format = cb.attributes['format'] - - -- Attributes shift headings - local shift_heading_level_by = 0 - local shift_input = cb.attributes['shift-heading-level-by'] - if shift_input then - shift_heading_level_by = tonumber(shift_input) - else - if include_auto then - -- Auto shift headings - shift_heading_level_by = last_heading_level - end - end - - --- keep track of level before recusion - local buffer_last_heading_level = last_heading_level - - local blocks = List:new() - for line in cb.text:gmatch('[^\n]+') do - if line:sub(1,2) ~= '//' then - local fh = io.open(line) - if not fh then - io.stderr:write("Cannot open file " .. line .. " | Skipping includes\n") - else - -- read file as the given format with global reader options - local contents = pandoc.read( - fh:read '*a', - format, - PANDOC_READER_OPTIONS - ).blocks - last_heading_level = 0 - -- recursive transclusion - contents = system.with_working_directory( - path.directory(line), - function () - return pandoc.walk_block( - pandoc.Div(contents), - { Header = update_last_level, CodeBlock = transclude } - ) - end).content - --- reset to level before recursion - last_heading_level = buffer_last_heading_level - blocks:extend(update_contents(contents, shift_heading_level_by, - path.directory(line))) - fh:close() - end - end - end - return blocks -end - -return { - { Meta = get_vars }, - { Header = update_last_level, CodeBlock = transclude } -} diff --git a/pandoc/minted.lua b/pandoc/minted.lua deleted file mode 100644 index 68db5f0b..00000000 --- a/pandoc/minted.lua +++ /dev/null @@ -1,454 +0,0 @@ ---[[ -minted -- enable the minted environment for code listings in beamer and latex. - -MIT License - -Copyright (c) 2019 Stephen McDowell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -]] - --------------------------------------------------------------------------------- --- Quick documentation. See full documentation here: -- --- https://github.com/pandoc/lua-filters/blob/master/minted -- --------------------------------------------------------------------------------- ---[[ -Brief overview of metadata keys that you can use in your document: - -minted: - no_default_autogobble: , *DISCOURAGED* - no_mintinline: - default_block_language: - default_inline_language: - block_attributes: - - attr_1 - - attr_2 - - ... - inline_attributes: - - attr_1 - - attr_2 - - ... - -In words, underneath the `minted` metadata key, you have the following options: - -### `no_default_autogobble` (boolean) - -By default this filter will always use `autogobble` with minted, which will -automatically trim common preceding whitespace. This is important because -code blocks nested under a list or other block elements _will_ have common -preceding whitespace that you _will_ want trimmed. - -### `no_mintinline` (boolean) - -Globally prevent this filter from emitting `\mintinline` calls for inline -Code elements, emitting `\texttt` instead. Possibly useful in saving -compile time for large documents that do not seek to have syntax -highlighting on inline code elements. - -### `default_block_language` (string) - -The default pygments lexer class to use for code blocks. By default this -is `"text"`, meaning no syntax highlighting. This is a fallback value, code -blocks that explicitly specify a lexer will not use it. - -### `default_inline_language` (string) - -Same as `default_block_language`, only for inline code (typed in single -backticks). The default is also `"text"`, and changing is discouraged. - -### `block_attributes` (list of strings) - -Any default attributes to apply to _all_ code blocks. These may be -overridden on a per-code-block basis. See section 5.3 of the -[minted documentation][minted_docs] for available options. - -### `inline_attributes` (list of strings) - -Any default attributes to apply to _all_ inline code. These may be -overridden on a per-code basis. See section 5.3 of the -[minted documentation][minted_docs] for available options. - -[minted_docs]: http://mirrors.ctan.org/macros/latex/contrib/minted/minted.pdf -]] - -local List = require('pandoc.List') - --------------------------------------------------------------------------------- --- Potential metadata elements to override. -- --------------------------------------------------------------------------------- -local minted_no_mintinline = false -local minted_default_block_language = "text" -local minted_default_inline_language = "text" -local minted_block_attributes = {} -local minted_inline_attributes = {} - --------------------------------------------------------------------------------- --- Constants used to differentiate Code and CodeBlock elements. -- --------------------------------------------------------------------------------- -local MintedInline = 0 -local MintedBlock = 1 - --------------------------------------------------------------------------------- --- Utility functions. -- --------------------------------------------------------------------------------- --- Return the string lexer class to be used with minted. `elem` should be --- either a Code or CodeBlock element (whose `classes` list will be inspected --- first). `kind` is assumed to be either `MintedInline` or `MintedBlock` in --- order to choose the appropriate fallback lexer when unspecified. -local function minted_language(elem, kind) - -- If the code [block] attached classes, we assume the first one is the - -- lexer class to use. - if #elem.classes > 0 then - return elem.classes[1] - end - -- Allow user-level metadata to override the inline language. - if kind == MintedInline then - return minted_default_inline_language - end - -- Allow user-level metadata to override the block language. - if kind == MintedBlock then - return minted_default_block_language - end - - -- Failsafe, should not hit here unless function called incorrectly. - return "text" -end - --- Returns a boolean specifying whether or not the specified string `cls` is an --- option that is supported by the minted package. -local function is_minted_class(cls) - -- Section 5.3 Available Options of Minted documentation. Note that many of - -- these do not apply to \mintinline (inline Code). Users are responsible - -- for supplying valid arguments to minted. For example, specifying - -- `autogobble` and `gobble` at the same time is a usage error. - -- - -- http://mirrors.ctan.org/macros/latex/contrib/minted/minted.pdf - local all_minted_options = List:new{ - "autogobble", "baselinestretch", "beameroverlays", "breakafter", - "breakaftergroup", "breakaftersymbolpre", "breakaftersymbolpost", - "breakanywhere", "breakanywheresymbolpre", "breakanywheresymbolpost", - "breakautoindent", "breakbefore", "breakbeforegroup", - "breakbeforesymbolpre", "breakbeforesymbolpost", "breakbytoken", - "breakbytokenanywhere", "breakindent", "breakindentnchars", "breaklines", - "breaksymbol", "breaksymbolleft", "breaksymbolright", "breaksymbolindent", - "breaksymbolindentnchars", "breaksymbolindentleft", - "breaksymbolindentleftnchars", "breaksymbolindentright", - "breaksymbolindentrightnchars", "breaksymbolsep", "breaksymbolsepnchars", - "breaksymbolsepleft", "breaksymbolsepleftnchars", "breaksymbolsepright", - "breaksymbolseprightnchars", "bgcolor", "codetagify", "curlyquotes", - "encoding", "escapeinside", "firstline", "firstnumber", "fontfamily", - "fontseries", "fontsize", "fontshape", "formatcom", "frame", "framerule", - "framesep", "funcnamehighlighting", "gobble", "highlightcolor", - "highlightlines", "keywordcase", "label", "labelposition", "lastline", - "linenos", "numberfirstline", "numbers", "mathescape", "numberblanklines", - "numbersep", "obeytabs", "outencoding", "python3", "resetmargins", - "rulecolor", "samepage", "showspaces", "showtabs", "space", "spacecolor", - "startinline", "style", "stepnumber", "stepnumberfromfirst", - "stepnumberoffsetvalues", "stripall", "stripnl", "tab", "tabcolor", - "tabsize", "texcl", "texcomments", "xleftmargin", "xrightmargin" - } - return all_minted_options:includes(cls, 0) -end - --- Return a string for the minted attributes `\begin{minted}[attributes]` or --- `\mintinline[attributes]`. Attributes are acquired by inspecting the --- specified element's `classes` and `attr` fields. Any global attributes --- provided in the document metadata will be included _only_ if they do not --- override the element-level attributes. --- --- `elem` should either be a Code or CodeBlock element, and `kind` is assumed to --- be either `MintedInline` or `MintedBlock`. The `kind` determines which --- global default attribute list to use. -local function minted_attributes(elem, kind) - -- The full listing of attributes that will be joined and returned. - local minted_attributes = {} - - -- Book-keeping, track xxx=yyy keys `xxx` that have been added to - -- `minted_attributes` to make checking optional global defaults via the - -- `block_attributes` or `inline_attributes` easier. - local minted_keys = {} - - -- Boolean style options for minted (e.g., ```{.bash .autogobble}) will appear - -- in the list of classes. - for _, cls in ipairs(elem.classes) do - if is_minted_class(cls) then - table.insert(minted_attributes, cls) - table.insert(minted_keys, cls) - end - end - - -- Value options using key=value (e.g., ```{.bash fontsize=\scriptsize}) show - -- up in the list of attributes. - for cls, value in pairs(elem.attributes) do - if is_minted_class(cls) then - table.insert(minted_attributes, cls .. "=" .. value) - table.insert(minted_keys, cls) - end - end - - -- Add any global defaults _only_ if they do not conflict. Note that conflict - -- is only in the literal sense. If a user has `autogobble` and `gobble=2` - -- specified, these do conflict in the minted sense, but this filter makes no - -- checks on validity ;) - local global_defaults = nil - if kind == MintedInline then - global_defaults = minted_inline_attributes - elseif kind == MintedBlock then - global_defaults = minted_block_attributes - end - for _, global_attr in ipairs(global_defaults) do - -- Either use the index of `=` minus one, or -1 if no `=` present. Fallback - -- on -1 means that the substring is the original string. - local end_idx = (string.find(global_attr, "=") or 0) - 1 - local global_key = string.sub(global_attr, 1, end_idx) - local can_insert_global = true - for _, existing_key in ipairs(minted_keys) do - if existing_key == global_key then - can_insert_global = false - break - end - end - - if can_insert_global then - table.insert(minted_attributes, global_attr) - end - end - - -- Return a comma delimited string for specifying the attributes to minted. - return table.concat(minted_attributes, ",") -end - --- Return the specified `elem` with any minted data removed from the `classes` --- and `attr`. Otherwise writers such as the HTML writer might produce invalid --- code since latex makes heavy use of the \backslash. -local function remove_minted_attibutes(elem) - -- Remove any minted items from the classes. - classes = {} - for _, cls in ipairs(elem.classes) do - if not is_minted_class(cls) and cls ~= "no_minted" then - table.insert(classes, cls) - end - end - elem.classes = classes - - -- Remove any minted items from the attributes. - extra_attrs = {} - for cls, value in pairs(elem.attributes) do - if not is_minted_class(cls) then - table.insert(extra_attrs, {cls, value}) - end - end - elem.attributes = extra_attrs - - -- Return the (potentially modified) element for pandoc to take over. - return elem -end - --- Return a `start_delim` and `end_delim` that can safely wrap around the --- specified `text` when used inline. If no special characters occur in `text`, --- then a pair of braces are returned. Otherwise, if any character of --- `possible_delims` are not in `text`, then it is returned. If no delimiter --- could be found, an error is raised. -local function minted_inline_delims(text) - local start_delim, end_delim - if text:find('[{}]') then - -- Try some other delimiter (the alphanumeric digits are in Python's - -- string.digits + string.ascii_letters order) - possible_delims = ('|!@#^&*-=+' .. '0123456789' .. - 'abcdefghijklmnopqrstuvwxyz' .. - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') - for char in possible_delims:gmatch('.') do - if not text:find(char, 1, true) then - start_delim = char - end_delim = char - break - end - end - if not start_delim then - local msg = 'Unable to determine delimiter to use around inline code %q' - error(msg:format(text)) - end - else - start_delim = '{' - end_delim = '}' - end - - return start_delim, end_delim -end - --------------------------------------------------------------------------------- --- Pandoc overrides. -- --------------------------------------------------------------------------------- --- Override the pandoc Meta function so that we can parse the metadata for the --- document and store the necessary variables locally to use in other functions --- such as Code and CodeBlock (helper methods). -function Meta(m) - -- Grab the `minted` metadata, quit early if not present. - local minted = m["minted"] - local found_autogobble = false - local always_autogobble = true - if minted ~= nil then - -- Parse and set the global bypass to turn off all \mintinline calls. - local no_mintinline = minted["no_mintinline"] - if no_mintinline ~= nil then - minted_no_mintinline = no_mintinline - end - - -- Parse and set the default block language. - local default_block_language = minted.default_block_language - and pandoc.utils.stringify(minted.default_block_language) - if default_block_language ~= nil then - minted_default_block_language = default_block_language - end - - -- Parse and set the default inline language. - local default_inline_language = minted.default_inline_language - and pandoc.utils.stringify(minted.default_inline_language) - if default_inline_language ~= nil then - minted_default_inline_language = default_inline_language - end - - -- Parse the global default minted attributes to use on every block. - local block_attributes = minted["block_attributes"] - if block_attributes ~= nil then - for _, attr in ipairs(block_attributes) do - if attr == "autogobble" then - found_autogobble = true - end - table.insert(minted_block_attributes, attr[1].text) - end - end - - -- Allow users to turn off autogobble for blocks, but really they should not - -- ever seek to do this (indented code blocks under list for example). - local no_default_autogobble = minted["no_default_autogobble"] - if no_default_autogobble ~= nil then - always_autogobble = not no_default_autogobble - end - - -- Parse the global default minted attributes to use on ever inline. - local inline_attributes = minted["inline_attributes"] - if inline_attributes ~= nil then - for _, attr in ipairs(inline_attributes) do - table.insert(minted_inline_attributes, attr[1].text) - end - end - end - - -- Make sure autogobble is turned on by default if no `minted` meta key is - -- provided for the document. - if always_autogobble and not found_autogobble then - table.insert(minted_block_attributes, "autogobble") - end - - -- Return the metadata to pandoc (unchanged). - return m -end - --- Override inline code elements to use \mintinline for beamer / latex writers. --- Other writers have all minted attributes removed. -function Code(elem) - if FORMAT == "beamer" or FORMAT == "latex" then - -- Allow a bypass to turn off \mintinline via adding .no_minted class. - local found_no_minted_class = false - for _, cls in ipairs(elem.classes) do - if cls == "no_minted" then - found_no_minted_class = true - break - end - end - - -- Check for local or global bypass to turn off \mintinline - if minted_no_mintinline or found_no_minted_class then - return nil -- Return `nil` signals to `pandoc` that elem is not changed. - end - - local start_delim, end_delim = minted_inline_delims(elem.text) - local language = minted_language(elem, MintedInline) - local attributes = minted_attributes(elem, MintedInline) - local raw_minted = string.format( - "\\mintinline[%s]{%s}%s%s%s", - attributes, - language, - start_delim, - elem.text, - end_delim - ) - -- NOTE: prior to pandoc commit 24a0d61, `beamer` cannot be used as the - -- RawBlock format. Using `latex` should not cause any problems. - return pandoc.RawInline("latex", raw_minted) - else - return remove_minted_attibutes(elem) - end -end - --- Override code blocks to use \begin{minted}...\end{minted} for beamer / latex --- writers. Other writers have all minted attributes removed. -function CodeBlock(block) - if FORMAT == "beamer" or FORMAT == "latex" then - local language = minted_language(block, MintedBlock) - local attributes = minted_attributes(block, MintedBlock) - local raw_minted = string.format( - "\\begin{minted}[%s]{%s}\n%s\n\\end{minted}", - attributes, - language, - block.text - ) - -- NOTE: prior to pandoc commit 24a0d61, `beamer` cannot be used as the - -- RawBlock format. Using `latex` should not cause any problems. - return pandoc.RawBlock("latex", raw_minted) - else - return remove_minted_attibutes(block) - end -end - --- Override headers to make all beamer frames fragile, since any minted --- environments or \mintinline invocations will halt compilation if the frame --- is not marked as fragile. -function Header(elem) - if FORMAT == 'beamer' then - -- Check first that 'fragile' is not already present. - local has_fragile = false - for _, val in ipairs(elem.classes) do - if val == 'fragile' then - has_fragile = true - break - end - end - - -- If not found, add fragile to the list of classes. - if not has_fragile then - table.insert(elem.classes, 'fragile') - end - - -- NOTE: pass the remaining work to pandoc, noting that 2.5 and below - -- may duplicate the 'fragile' specifier. Duplicated fragile does *not* - -- cause compile errors. - return elem - end -end - --- NOTE: order of return matters, Meta needs to be first otherwise the metadata --- from the document will not be loaded _first_. -return { - {Meta = Meta}, - {Code = Code}, - {CodeBlock = CodeBlock}, - {Header = Header} -} diff --git a/pandoc/templates/beamer.tex b/pandoc/templates/beamer.tex new file mode 100644 index 00000000..4910bcd8 --- /dev/null +++ b/pandoc/templates/beamer.tex @@ -0,0 +1,584 @@ +% 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$ +$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)$ + \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$} +$endif$ +$if(sansfont)$ + \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$} +$endif$ +$if(monofont)$ + \setmonofont[$for(monofontoptions)$$monofontoptions$$sep$,$endfor$]{$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 +\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} +\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} +\makeatother +% Scale images if necessary, so that they will not overflow the page +% margins by default, and it is still possible to overwrite the defaults +% using explicit options in \includegraphics[width, height, ...]{} +\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} +% Set default figure placement to htbp +\makeatletter +\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} +\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 +\ifx\paragraph\undefined\else + \let\oldparagraph\paragraph + \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}} +\fi +\ifx\subparagraph\undefined\else + \let\oldsubparagraph\subparagraph + \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}} +\fi +$endif$ +$endif$ +$if(pagestyle)$ +\pagestyle{$pagestyle$} +$endif$ +$if(csl-refs)$ +\newlength{\cslhangindent} +\setlength{\cslhangindent}{1.5em} +\newlength{\csllabelwidth} +\setlength{\csllabelwidth}{3em} +\newlength{\cslentryspacingunit} % times entry-spacing +\setlength{\cslentryspacingunit}{\parskip} +\newenvironment{CSLReferences}[2] % #1 hanging-ident, #2 entry spacing + {% don't indent paragraphs + \setlength{\parindent}{0pt} + % turn on hanging indent if param 1 is 1 + \ifodd #1 + \let\oldpar\par + \def\par{\hangindent=\cslhangindent\oldpar} + \fi + % set entry spacing + \setlength{\parskip}{#2\cslentryspacingunit} + }% + {} +\usepackage{calc} +\newcommand{\CSLBlock}[1]{#1\hfill\break} +\newcommand{\CSLLeftMargin}[1]{\parbox[t]{\csllabelwidth}{#1}} +\newcommand{\CSLRightInline}[1]{\parbox[t]{\linewidth - \csllabelwidth}{#1}\break} +\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$]{$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{} +$endif$ +$for(header-includes)$ +$header-includes$ +$endfor$ +\ifLuaTeX + \usepackage{selnolig} % disable illegal ligatures +\fi +$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$ +\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} +\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{$titlegraphic$}} +$endif$ +$if(logo)$ +\logo{\includegraphics{$logo$}} +$endif$ +$endif$ + +% My default packages +\usepackage{tikz} +\usetikzlibrary{calc, positioning, tikzmark, shapes.arrows, arrows.meta} +\usepackage[school]{pgf-umlcd} +\usepackage{fontawesome5} +\usepackage{tabularx} + +% My commands +\newcommand{\boldred}[1]{\textcolor{red}{\textbf{#1}}} + +\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$ + \tableofcontents[hideallsubsections] +\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} diff --git a/templates/slides.md b/templates/slides.md index c13a6653..3c71f947 100644 --- a/templates/slides.md +++ b/templates/slides.md @@ -3,11 +3,6 @@ header-includes: | \makeatletter \beamer@ignorenonframefalse \makeatother - \usepackage{fontawesome5} - \usepackage[school]{pgf-umlcd} - \usepackage{unicode-math} - \usepackage{tikz} - \usetikzlibrary{calc} --- @@ -98,3 +93,13 @@ Der Grundsatz der **Datenkapselung** besagt, dass nur ein Objekt selbst Zugriff \vspace{0.75cm} Der Zugriff von außen sollte nur über durch das Objekt bereitgestellte Methoden erfolgen. + +## Tables + +\centering +\begin{tabularx}{10cm}{X | X} +\multicolumn{2}{c}{Multicolumn} \\ +\hline +\rowcolor{red!30} red line & yeah \\ +\rowcolor{blue!30} blue line & wuhu \\ +\end{tabularx} -- cgit v1.2.3