initial
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
out/
|
||||
mermaid-filter.err
|
||||
_minted-input/
|
11
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"folder-path-color.folders": [
|
||||
{ "path": "chapters/01", "symbol": "SR", "tooltip": "Source files" },
|
||||
{ "path": "chapters/02", "symbol": "T", "tooltip": "Common" },
|
||||
{ "path": "chapters/03", "symbol": "T", "tooltip": "Common" },
|
||||
{ "path": "chapters/04", "symbol": "T", "tooltip": "Common" },
|
||||
{ "path": "chapters/05", "symbol": "T", "tooltip": "Common" },
|
||||
{ "path": "chapters/06", "symbol": "T", "tooltip": "Common" },
|
||||
{ "path": "chapters/07", "symbol": "T", "tooltip": "Common" },
|
||||
]
|
||||
}
|
37
Bachelor.bib
Normal file
@ -0,0 +1,37 @@
|
||||
@online{bizzottoComparisonPopularFlutter2023,
|
||||
title = {A {{Comparison}} of {{Popular Flutter App Architectures}}},
|
||||
author = {Bizzotto, Andrea},
|
||||
date = {2023-09-01},
|
||||
url = {https://codewithandrea.com/articles/comparison-flutter-app-architectures/},
|
||||
urldate = {2023-11-19},
|
||||
abstract = {Comparing my Riverpod App Architecture with other popular ones such as MVC, MVVM, Bloc, Stacked, Clean Architecture, and Android App Architecture.},
|
||||
langid = {english},
|
||||
organization = {{Code With Andrea}},
|
||||
file = {/Users/fabian/Zotero/storage/DUDXBAGD/comparison-flutter-app-architectures.html}
|
||||
}
|
||||
|
||||
@online{FlutterArchitecturalOverviewb,
|
||||
title = {Flutter Architectural Overview},
|
||||
url = {https://docs.flutter.dev/resources/architectural-overview},
|
||||
urldate = {2024-02-12},
|
||||
abstract = {A high-level overview of the architecture of Flutter, including the core principles and concepts that form its design.},
|
||||
langid = {english},
|
||||
file = {/Users/fabian/Zotero/storage/W67CJYBZ/architectural-overview.html}
|
||||
}
|
||||
|
||||
@article{weiserComputer21stCentury1999,
|
||||
title = {The Computer for the 21st Century},
|
||||
author = {Weiser, Mark},
|
||||
date = {1999-07-01},
|
||||
journaltitle = {ACM SIGMOBILE Mobile Computing and Communications Review},
|
||||
shortjournal = {SIGMOBILE Mob. Comput. Commun. Rev.},
|
||||
volume = {3},
|
||||
number = {3},
|
||||
pages = {3--11},
|
||||
issn = {1559-1662},
|
||||
doi = {10.1145/329124.329126},
|
||||
url = {https://dl.acm.org/doi/10.1145/329124.329126},
|
||||
urldate = {2023-11-14},
|
||||
abstract = {Specialized elements of hardware and software, connected by wires, radio waves and infrared, will be so ubiquitous that no one will notice their presence.},
|
||||
file = {/Users/fabian/Zotero/storage/8CCSE83J/Weiser - 1999 - The computer for the 21st century.pdf}
|
||||
}
|
21
Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
SHELL:=/bin/bash
|
||||
MARKDOWN_FILES := $(shell find chapters -type f -name "*.md" | sort | tr '\n' ' ')
|
||||
BACHELOR_TEXT := @cat $(MARKDOWN_FILES)
|
||||
|
||||
all: local
|
||||
|
||||
help:
|
||||
@echo "Please choose an option!"
|
||||
@echo "- Create pdf: make pdf"
|
||||
|
||||
dir:
|
||||
mkdir -p out
|
||||
|
||||
bachelor: @cat $(MARKDOWN_FILES)
|
||||
|
||||
local: dir
|
||||
@echo "Building paper"
|
||||
MERMAID_FILTER_FORMAT=pdf pandoc -V colorlinks=true -V linkcolor=black -V urlcolor=black -f 'markdown+autolink_bare_uris' --pdf-engine=lualatex --pdf-engine-opt=-shell-escape --filter mermaid-filter --lua-filter columns.lua --citeproc -s $(MARKDOWN_FILES) -o ./out/bachelor.pdf -V lang=de-DE -V fontsize=11pt --highlight-style tango --reference-links --bibliography Bachelor.bib --csl=harvard-right.csl -M lang:de --number-sections
|
||||
|
||||
clean:
|
||||
rm -rf out
|
BIN
assets/.DS_Store
vendored
Normal file
BIN
assets/skizzen/dashgame.png
Normal file
After Width: | Height: | Size: 140 KiB |
BIN
assets/skizzen/einstellungen.png
Normal file
After Width: | Height: | Size: 171 KiB |
BIN
assets/skizzen/home.png
Normal file
After Width: | Height: | Size: 131 KiB |
BIN
assets/skizzen/led.png
Normal file
After Width: | Height: | Size: 137 KiB |
BIN
assets/skizzen/materialWidgets.png
Normal file
After Width: | Height: | Size: 125 KiB |
BIN
assets/skizzen/matrix.png
Normal file
After Width: | Height: | Size: 166 KiB |
BIN
assets/skizzen/openapi.png
Normal file
After Width: | Height: | Size: 168 KiB |
BIN
assets/skizzen/openstreetmap.png
Normal file
After Width: | Height: | Size: 217 KiB |
BIN
assets/skizzen/redled.jpg
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
assets/skizzen/sparkfun.jpg
Normal file
After Width: | Height: | Size: 145 KiB |
BIN
assets/skizzen/systeminfo.png
Normal file
After Width: | Height: | Size: 199 KiB |
BIN
assets/skizzen/video.png
Normal file
After Width: | Height: | Size: 123 KiB |
BIN
chapters/.DS_Store
vendored
Normal file
79
chapters/00_pandoc/00_pandoc.md
Normal file
@ -0,0 +1,79 @@
|
||||
---
|
||||
header-includes: |
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage[usefilenames,RMstyle={Text,Semibold},SSstyle={Text,Semibold},TTstyle={Text,Semibold},DefaultFeatures={Ligatures=Common}]{plex-otf}
|
||||
\usepackage[a4paper,bindingoffset=0.2in,%
|
||||
left=4cm,right=2cm,top=2cm,bottom=2cm,%
|
||||
footskip=.25in]{geometry}
|
||||
\usepackage{fancyhdr}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{tikz}
|
||||
\usetikzlibrary{snakes,arrows,shapes}
|
||||
\usepackage{amsmath}
|
||||
\usepackage{pgfplots}
|
||||
\usepackage{pgfplotstable}
|
||||
\pgfplotsset{compat=1.8}
|
||||
\usepackage{multicol,lipsum}
|
||||
\usepackage{listings}
|
||||
\usepackage{wrapfig}
|
||||
\usepackage[font=small,labelfont=bf]{caption}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{xcolor,stackengine}
|
||||
\usepackage{colortbl}
|
||||
\usepackage{tcolorbox}
|
||||
\usepackage{lastpage}
|
||||
\usepackage{subcaption}
|
||||
\usepackage{tabularx}
|
||||
\usepackage{biblatex}
|
||||
\usepackage{float}
|
||||
\usepackage{refract}
|
||||
\usepackage{svg}
|
||||
\usepackage{setspace}
|
||||
\usepackage{titling}
|
||||
\usepackage{fvextra}
|
||||
\usepackage{emoji}
|
||||
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines,commandchars=\\\{\}}
|
||||
\newcommand{\hideFromPandoc}[1]{#1}
|
||||
\hideFromPandoc{
|
||||
\let\Begin\begin
|
||||
\let\End\end
|
||||
}
|
||||
\makeatletter
|
||||
\def\fps@figure{h}
|
||||
\makeatother
|
||||
nocite: |
|
||||
@*
|
||||
---
|
||||
|
||||
\setstretch{1.5}
|
||||
|
||||
\setemojifont{Twemoji Mozilla}
|
||||
|
||||
\renewcommand{\familydefault}{\sfdefault}
|
||||
|
||||
\graphicspath{ {./img/} }
|
||||
|
||||
\overfullrule=0pt
|
||||
|
||||
\newcolumntype{C}{>{\centering\arraybackslash}X}
|
||||
|
||||
\renewcommand{\comment}[1]{\hspace{2em}{\small\textit{#1}}\bigskip\par}
|
||||
|
||||
\newcommand\palbox[1]{{\sffamily\fboxsep=5pt\relax\fboxrule=1pt\relax\footnotesize%
|
||||
\fcolorbox{gray!50}{gray!10}{%
|
||||
\stackengine{4pt}{%
|
||||
\colorbox[HTML]{#1}{\rule{30pt}{0pt}\rule{0pt}{30pt}}%
|
||||
}{%
|
||||
\color{black!60}\stackengine{6pt}{\##1}{\saycolors{#1}}{U}{l}{F}{F}{S}%
|
||||
}{U}{l}{F}{F}{S}%
|
||||
}%
|
||||
}}
|
||||
\newcommand\saycolors[1]{\relax}
|
||||
|
||||
\lstset{
|
||||
basicstyle=\ttfamily,
|
||||
columns=fullflexible,
|
||||
frame=single,
|
||||
breaklines=true,
|
||||
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
|
||||
}
|
32
chapters/01_titel/00_titlepage.md
Normal file
@ -0,0 +1,32 @@
|
||||
\thispagestyle{empty}
|
||||
|
||||
\begin{titlepage}
|
||||
\begin{center}
|
||||
\Large Hochschule Rhein-Waal \\
|
||||
\vspace{2.5cm}
|
||||
\Large Proposal für die Bachelorarbeit \\
|
||||
\vspace{2.5cm}
|
||||
\huge \textbf{\textsc{Flutter als Entwicklungsplattform für eingebettete Linux Systeme: eine Fallstudie}} \\
|
||||
\vspace{1.0cm}
|
||||
\Large Fabian Baldeau \\
|
||||
\vspace{2.5cm}
|
||||
\vspace{0.25cm}
|
||||
\textsc{Studiengang}\\
|
||||
\vspace{0.25cm}
|
||||
\textsc{Medieninformatik}\\
|
||||
\vspace{2.5cm}
|
||||
\textsc{Gutachter}\\
|
||||
\vspace{0.25cm}
|
||||
\textsc{Prof. Dr.-Ing. Ido Iurgel}\\
|
||||
\vspace{0.25cm}
|
||||
\textsc{Prof. Dr. Kai Essig}\\
|
||||
\vspace{2cm}
|
||||
\end{center}
|
||||
|
||||
\end{titlepage}
|
||||
|
||||
\pagenumbering{Roman}
|
||||
\fancyhf{}
|
||||
\fancyhead[C]{\thepage}
|
||||
\renewcommand{\headrulewidth}{0pt}
|
||||
\pagestyle{fancy}
|
0
chapters/01_titel/01_abstract.md
Normal file
23
chapters/01_titel/02_toc.md
Normal file
@ -0,0 +1,23 @@
|
||||
\tableofcontents
|
||||
\pagebreak
|
||||
|
||||
<!-- \fzframelinU{
|
||||
\centering
|
||||
\Huge{Kurz-Exposé} \\
|
||||
\Large{\emph{Subtitle}}\\
|
||||
\vspace{0.25cm}
|
||||
\small{University/School}\\
|
||||
\small{Class}\\
|
||||
\small{Name}
|
||||
}
|
||||
|
||||
\vspace{8pt} -->
|
||||
|
||||
\renewcommand{\headrulewidth}{0pt}
|
||||
|
||||
\pagenumbering{arabic}
|
||||
|
||||
<!-- \fancyfoot[C]{Seite \thepage\ von \pageref{LastPage}} -->
|
||||
|
||||
\fancyhead[C]{}
|
||||
\fancyfoot[R]{\thepage}
|
1
chapters/02_einleitung/00_motivation_relevanz.md
Normal file
@ -0,0 +1 @@
|
||||
|
0
chapters/02_einleitung/01_zielsetzung.md
Normal file
0
chapters/02_einleitung/02_methodik.md
Normal file
0
chapters/03_grundlagen/01_eLinux.md
Normal file
0
chapters/03_grundlagen/02_raspberryPi.md
Normal file
0
chapters/03_grundlagen/03_i2c_bus.md
Normal file
0
chapters/03_grundlagen/04_spi_bus.md
Normal file
0
chapters/03_grundlagen/05_yocto_linux.md
Normal file
25
chapters/03_grundlagen/06_flutter.md
Normal file
@ -0,0 +1,25 @@
|
||||
<!-- TODO: Was ist Flutter? -->
|
||||
|
||||
# Flutter
|
||||
|
||||
Was ist Flutter [@FlutterArchitecturalOverviewb]
|
||||
|
||||
test [@weiserComputer21stCentury1999]
|
||||
|
||||
```{#test .dart .number-lines caption="Example Dart test"}
|
||||
import 'package:retry/retry.dart';
|
||||
|
||||
final response = await retry(
|
||||
// Make a GET request
|
||||
() => http.get('https://google.com').timeout(Duration(seconds: 5)),
|
||||
// Retry on SocketException or TimeoutException
|
||||
retryIf: (e) => e is SocketException || e is TimeoutException,
|
||||
);
|
||||
print(response.body);
|
||||
```
|
||||
|
||||
Nice Dart highlighting!
|
||||
|
||||

|
||||
|
||||
WORKING :)
|
BIN
chapters/05_yocto/.DS_Store
vendored
Normal file
0
chapters/05_yocto/01_pi_image.md
Normal file
0
chapters/05_yocto/02_meta_flutter.md
Normal file
0
chapters/05_yocto/03_network_manager.md
Normal file
0
chapters/05_yocto/04_hot_reload_embedder.md
Normal file
0
chapters/05_yocto/05_qemu_linux.md
Normal file
BIN
chapters/06_flutter/.DS_Store
vendored
Normal file
0
chapters/06_flutter/01_architecture.md
Normal file
0
chapters/06_flutter/02_home.md
Normal file
0
chapters/06_flutter/03_material_demo.md
Normal file
0
chapters/06_flutter/04_liste.md
Normal file
0
chapters/06_flutter/05_kartenansicht.md
Normal file
0
chapters/06_flutter/06_einstellungen.md
Normal file
0
chapters/06_flutter/08_matrix.md
Normal file
0
chapters/06_flutter/09_video.md
Normal file
0
chapters/06_flutter/10_flame.md
Normal file
0
chapters/06_flutter/led.md
Normal file
BIN
chapters/07_fazit/.DS_Store
vendored
Normal file
0
chapters/07_fazit/01_vergleich.md
Normal file
0
chapters/07_fazit/02_bewertung.md
Normal file
0
chapters/07_fazit/03_zusammenfassung_ausblick.md
Normal file
3
chapters/08_literatur/00_literature.md
Normal file
@ -0,0 +1,3 @@
|
||||
\pagebreak
|
||||
|
||||
# Literaturverzeichnis
|
941
columns.lua
Normal file
@ -0,0 +1,941 @@
|
||||
--[[-- # Columns - multiple column support in Pandoc's markdown.
|
||||
|
||||
This Lua filter provides support for multiple columns in
|
||||
latex and html outputs. For details, see README.md.
|
||||
|
||||
@author Julien Dutant <julien.dutant@kcl.ac.uk>
|
||||
@copyright 2021 Julien Dutant
|
||||
@license MIT - see LICENSE file for details.
|
||||
@release 1.1.2
|
||||
]]
|
||||
|
||||
-- # Version control
|
||||
local required_version = '2.9.0'
|
||||
local version_err_msg = "ERROR: pandoc >= " .. required_version
|
||||
.. " required for columns filter"
|
||||
-- pandoc 2.9 required for pandoc.List insert method
|
||||
-- if PANDOC_VERSION == nil then -- if pandoc_version < 2.1
|
||||
-- error(version_err_msg)
|
||||
-- elseif PANDOC_VERSION[2] < 9 then
|
||||
-- error(version_err_msg)
|
||||
-- else
|
||||
-- PANDOC_VERSION:must_be_at_least(required_version, version_err_msg)
|
||||
-- end
|
||||
local utils = require('pandoc.utils') -- this is superfluous in Pandoc >= 2.7 I think
|
||||
|
||||
-- # Internal settings
|
||||
|
||||
-- target_formats filter is triggered when those formats are targeted
|
||||
local target_formats = {
|
||||
"html.*",
|
||||
"latex",
|
||||
}
|
||||
local options = {
|
||||
raggedcolumns = false, -- global ragged columns option
|
||||
}
|
||||
|
||||
-- # Helper functions
|
||||
|
||||
--- type: pandoc-friendly type function
|
||||
-- panbdoc.utils.type is only defined in Pandoc >= 2.17
|
||||
-- if it isn't, we extend Lua's type function to give the same values
|
||||
-- as pandoc.utils.type on Meta objects: Inlines, Inline, Blocks, Block,
|
||||
-- string and booleans
|
||||
-- Caution: not to be used on non-Meta Pandoc elements, the
|
||||
-- results will differ (only 'Block', 'Blocks', 'Inline', 'Inlines' in
|
||||
-- >=2.17, the .t string in <2.17).
|
||||
local type = utils.type or function(obj)
|
||||
local tag = type(obj) == 'table' and obj.t and obj.t:gsub('^Meta', '')
|
||||
return tag and tag ~= 'Map' and tag or type(obj)
|
||||
end
|
||||
|
||||
--- Test whether the target format is in a given list.
|
||||
-- @param formats list of formats to be matched
|
||||
-- @return true if match, false otherwise
|
||||
local function format_matches(formats)
|
||||
for _, format in pairs(formats) do
|
||||
if FORMAT:match(format) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
--- Add a block to the document's header-includes meta-data field.
|
||||
-- @param meta the document's metadata block
|
||||
-- @param block Pandoc block element (e.g. RawBlock or Para) to be added to header-includes
|
||||
-- @return meta the modified metadata block
|
||||
local function add_header_includes(meta, block)
|
||||
local header_includes = pandoc.List:new()
|
||||
|
||||
-- use meta['header-includes']
|
||||
|
||||
if meta['header-includes'] then
|
||||
if type(meta['header-includes']) == 'List' then
|
||||
header_includes:extend(meta['header-includes'])
|
||||
else
|
||||
header_includes:insert(meta['header-includes'])
|
||||
end
|
||||
end
|
||||
|
||||
-- insert `block` in header-includes
|
||||
|
||||
header_includes:insert(pandoc.MetaBlocks({ block }))
|
||||
|
||||
-- save header-includes in the document's meta
|
||||
|
||||
meta['header-includes'] = header_includes
|
||||
|
||||
return meta
|
||||
end
|
||||
|
||||
--- Add a class to an element.
|
||||
-- @param element Pandoc AST element
|
||||
-- @param class name of the class to be added (string)
|
||||
-- @return the modified element, or the unmodified element if the element has no classes
|
||||
local function add_class(element, class)
|
||||
-- act only if the element has classes
|
||||
if element.attr and element.attr.classes then
|
||||
-- if the class is absent, add it
|
||||
if not element.attr.classes:includes(class) then
|
||||
element.attr.classes:insert(class)
|
||||
end
|
||||
end
|
||||
|
||||
return element
|
||||
end
|
||||
|
||||
--- Removes a class from an element.
|
||||
-- @param element Pandoc AST element
|
||||
-- @param class name of the class to be removed (string)
|
||||
-- @return the modified element, or the unmodified element if the element has no classes
|
||||
local function remove_class(element, class)
|
||||
-- act only if the element has classes
|
||||
if element.attr and element.attr.classes then
|
||||
-- if the class is present, remove it
|
||||
if element.attr.classes:includes(class) then
|
||||
element.attr.classes = element.attr.classes:filter(
|
||||
function(x)
|
||||
return not (x == class)
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
return element
|
||||
end
|
||||
|
||||
--- Set the value of an element's attribute.
|
||||
-- @param element Pandoc AST element to be modified
|
||||
-- @param key name of the attribute to be set (string)
|
||||
-- @param value value to be set. If nil, the attribute is removed.
|
||||
-- @return the modified element, or the element if it's not an element with attributes.
|
||||
local function set_attribute(element, key, value)
|
||||
-- act only if the element has attributes
|
||||
if element.attr and element.attr.attributes then
|
||||
-- if `value` is `nil`, remove the attribute
|
||||
if value == nil then
|
||||
if element.attr.attributes[key] then
|
||||
element.attr.attributes[key] = nil
|
||||
end
|
||||
|
||||
-- otherwise set its value
|
||||
else
|
||||
element.attr.attributes[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
return element
|
||||
end
|
||||
|
||||
--- Add html style markup to an element's attributes.
|
||||
-- @param element the Pandoc AST element to be modified
|
||||
-- @param style the style markup to add (string in CSS)
|
||||
-- @return the modified element, or the unmodified element if it's an element without attributes
|
||||
local function add_to_html_style(element, style)
|
||||
-- act only if the element has attributes
|
||||
if element.attr and element.attr.attributes then
|
||||
-- if the element has style markup, append
|
||||
if element.attr.attributes['style'] then
|
||||
element.attr.attributes['style'] =
|
||||
element.attr.attributes['style'] .. '; ' .. style .. ' ;'
|
||||
|
||||
-- otherwise create
|
||||
else
|
||||
element.attr.attributes['style'] = style .. ' ;'
|
||||
end
|
||||
end
|
||||
|
||||
return element
|
||||
end
|
||||
|
||||
--- Translate an English number name into a number.
|
||||
-- Converts cardinals ("one") and numerals ("first").
|
||||
-- Returns nil if the name isn't understood.
|
||||
-- @param name an English number name (string)
|
||||
-- @return number or nil
|
||||
local function number_by_name(name)
|
||||
local names = {
|
||||
one = 1,
|
||||
two = 2,
|
||||
three = 3,
|
||||
four = 4,
|
||||
five = 5,
|
||||
six = 6,
|
||||
seven = 7,
|
||||
eight = 8,
|
||||
nine = 9,
|
||||
ten = 10,
|
||||
first = 1,
|
||||
second = 2,
|
||||
third = 3,
|
||||
fourth = 4,
|
||||
fifth = 5,
|
||||
sixth = 6,
|
||||
seventh = 7,
|
||||
eighth = 8,
|
||||
ninth = 9,
|
||||
tenth = 10,
|
||||
}
|
||||
|
||||
result = nil
|
||||
|
||||
if name and names[name] then
|
||||
return names[name]
|
||||
end
|
||||
end
|
||||
|
||||
--- Convert some CSS values (lengths, colous) to LaTeX equivalents.
|
||||
-- Example usage: `css_values_to_latex("1px solid black")` returns
|
||||
-- `{ length = "1pt", color = "black", colour = "black"}`.
|
||||
-- @param css_str a CSS string specifying a value
|
||||
-- @return table with keys `length`, `color` (alias `colour`) if found
|
||||
local function css_values_to_latex(css_str)
|
||||
-- color conversion table
|
||||
-- keys are CSS values, values are LaTeX equivalents
|
||||
|
||||
latex_colors = {
|
||||
-- xcolor always available
|
||||
black = 'black',
|
||||
blue = 'blue',
|
||||
brown = 'brown',
|
||||
cyan = 'cyan',
|
||||
darkgray = 'darkgray',
|
||||
gray = 'gray',
|
||||
green = 'green',
|
||||
lightgray = 'lightgray',
|
||||
lime = 'lime',
|
||||
magenta = 'magenta',
|
||||
olive = 'olive',
|
||||
orange = 'orange',
|
||||
pink = 'pink',
|
||||
purple = 'purple',
|
||||
red = 'red',
|
||||
teal = 'teal',
|
||||
violet = 'violet',
|
||||
white = 'white',
|
||||
yellow = 'yellow',
|
||||
-- css1 colors
|
||||
silver = 'lightgray',
|
||||
fuschia = 'magenta',
|
||||
aqua = 'cyan',
|
||||
}
|
||||
|
||||
local result = {}
|
||||
|
||||
-- look for color values
|
||||
-- by color name
|
||||
-- rgb, etc.: to be added
|
||||
|
||||
local color = ''
|
||||
|
||||
-- space in front simplifies pattern matching
|
||||
css_str = ' ' .. css_str
|
||||
|
||||
-- look for colour names
|
||||
for text in string.gmatch(css_str, '[%s](%a+)') do
|
||||
-- if we have LaTeX equivalent of `text`, store it
|
||||
if latex_colors[text] then
|
||||
result['color'] = latex_colors[text]
|
||||
end
|
||||
end
|
||||
|
||||
-- provide British spelling
|
||||
|
||||
if result['color'] then
|
||||
result['colour'] = result['color']
|
||||
end
|
||||
|
||||
-- look for lengths
|
||||
|
||||
-- 0 : converted to 0em
|
||||
if string.find(css_str, '%s0%s') then
|
||||
result['length'] = '0em'
|
||||
end
|
||||
|
||||
-- px : converted to pt
|
||||
for text in string.gmatch(css_str, '(%s%d+)px') do
|
||||
result['length'] = text .. 'pt'
|
||||
end
|
||||
|
||||
-- lengths units to be kept as is
|
||||
-- nb, % must be escaped
|
||||
-- nb, if several found, the latest type is preserved
|
||||
keep_units = { '%%', 'pt', 'mm', 'cm', 'in', 'ex', 'em' }
|
||||
|
||||
for _, unit in pairs(keep_units) do
|
||||
-- .11em format
|
||||
for text in string.gmatch(css_str, '%s%.%d+' .. unit) do
|
||||
result['length'] = text
|
||||
end
|
||||
|
||||
-- 2em and 1.2em format
|
||||
for text in string.gmatch(css_str, '%s%d+%.?%d*' .. unit) do
|
||||
result['length'] = text
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
--- Ensures that a string specifies a LaTeX length
|
||||
-- @param text text to be checked
|
||||
-- @return text if it is a LaTeX length, `nil` otherwise
|
||||
local function ensures_latex_length(text)
|
||||
-- LaTeX lengths units
|
||||
-- nb, % must be escaped in lua patterns
|
||||
units = { '%%', 'pt', 'mm', 'cm', 'in', 'ex', 'em' }
|
||||
|
||||
local result = nil
|
||||
|
||||
-- ignore spaces, controls and punctuation other than
|
||||
-- dot, plus, minus
|
||||
text = string.gsub(text, "[%s%c,;%(%)%[%]%*%?%%%^%$]+", "")
|
||||
|
||||
for _, unit in pairs(units) do
|
||||
-- match .11em format and 1.2em format
|
||||
if string.match(text, '^%.%d+' .. unit .. '$') or
|
||||
string.match(text, '^%d+%.?%d*' .. unit .. '$') then
|
||||
result = text
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
-- # Filter-specific functions
|
||||
|
||||
--- Process the metadata block.
|
||||
-- Adds any needed material to the document's metadata block.
|
||||
-- @param meta the document's metadata element
|
||||
local function process_meta(meta)
|
||||
-- in LaTeX, require the `multicols` package
|
||||
if FORMAT:match('latex') then
|
||||
return add_header_includes(meta,
|
||||
pandoc.RawBlock('latex', '\\usepackage{multicol}\n'))
|
||||
end
|
||||
|
||||
-- in html, ensure that the first element of `columns` div
|
||||
-- has a top margin of zero (otherwise we get white space
|
||||
-- on the top of the first column)
|
||||
-- idem for the first element after a `column-span` element
|
||||
if FORMAT:match('html.*') then
|
||||
html_header = [[
|
||||
<style>
|
||||
/* Styles added by the columns.lua pandoc filter */
|
||||
.columns :first-child {margin-top: 0;}
|
||||
.column-span + * {margin-top: 0;}
|
||||
</style>
|
||||
]]
|
||||
|
||||
return add_header_includes(meta, pandoc.RawBlock('html', html_header))
|
||||
end
|
||||
|
||||
return meta
|
||||
end
|
||||
|
||||
--- Convert explicit columnbreaks.
|
||||
-- This function converts any explict columnbreak markup in an element
|
||||
-- into a single syntax: a Div with class `columnbreak`.
|
||||
-- Note: if there are `column` Divs in the element we keep them
|
||||
-- in case they harbour further formatting (e.g. html classes). However
|
||||
-- we remove their `column` class to avoid double-processing when
|
||||
-- column fields are nested.
|
||||
-- @param elem Pandoc native Div element
|
||||
-- @return elem modified as needed
|
||||
local function convert_explicit_columbreaks(elem)
|
||||
-- if `elem` ends with a `column` Div, this last Div should
|
||||
-- not generate a columnbreak. We tag it to make sure we don't convert it.
|
||||
|
||||
if elem.content[#elem.content] and elem.content[#elem.content].classes
|
||||
and elem.content[#elem.content].classes:includes('column') then
|
||||
elem.content[#elem.content] =
|
||||
add_class(elem.content[#elem.content], 'column-div-in-last-position')
|
||||
end
|
||||
|
||||
-- processes `column` Divs and `\columnbreak` LaTeX RawBlocks
|
||||
filter = {
|
||||
|
||||
Div = function(el)
|
||||
-- syntactic sugar: `column-break` converted to `columnbreak`
|
||||
if el.classes:includes("column-break") then
|
||||
el = add_class(el, "columnbreak")
|
||||
el = remove_class(el, "column-break")
|
||||
end
|
||||
|
||||
if el.classes:includes("column") then
|
||||
-- with `column` Div, add a break if it's not in last position
|
||||
if not el.classes:includes('column-div-in-last-position') then
|
||||
local breaking_div = pandoc.Div({})
|
||||
breaking_div = add_class(breaking_div, "columnbreak")
|
||||
|
||||
el.content:insert(breaking_div)
|
||||
|
||||
-- if it's in the last position, remove the custom tag
|
||||
else
|
||||
el = remove_class(el, 'column-div-in-last-position')
|
||||
end
|
||||
|
||||
-- remove `column` classes, but leave the div and other
|
||||
-- attributes the user might have added
|
||||
el = remove_class(el, 'column')
|
||||
end
|
||||
|
||||
return el
|
||||
end,
|
||||
|
||||
RawBlock = function(el)
|
||||
if el.format == "tex" and el.text == '\\columnbreak' then
|
||||
local breaking_div = pandoc.Div({})
|
||||
breaking_div = add_class(breaking_div, "columnbreak")
|
||||
|
||||
return breaking_div
|
||||
else
|
||||
return el
|
||||
end
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
return pandoc.walk_block(elem, filter)
|
||||
end
|
||||
|
||||
--- Tag an element with the number of explicit columnbreaks it contains.
|
||||
-- Counts the number of epxlicit columnbreaks contained in an element and
|
||||
-- tags the element with a `number_explicit_columnbreaks` attribute.
|
||||
-- In the process columnbreaks are tagged with the class `columnbreak_already_counted`
|
||||
-- in order to avoid double-counting when multi-columns are nested.
|
||||
-- @param elem Pandoc element (native Div element of class `columns`)
|
||||
-- @return elem with the attribute `number_explicit_columnbreaks` set.
|
||||
local function tag_with_number_of_explicit_columnbreaks(elem)
|
||||
local number_columnbreaks = 0
|
||||
|
||||
local filter = {
|
||||
|
||||
Div = function(el)
|
||||
if el.classes:includes('columnbreak') and
|
||||
not el.classes:includes('columnbreak_already_counted') then
|
||||
number_columnbreaks = number_columnbreaks + 1
|
||||
el = add_class(el, 'columnbreak_already_counted')
|
||||
end
|
||||
|
||||
return el
|
||||
end
|
||||
}
|
||||
|
||||
elem = pandoc.walk_block(elem, filter)
|
||||
|
||||
elem = set_attribute(elem, 'number_explicit_columnbreaks',
|
||||
number_columnbreaks)
|
||||
|
||||
return elem
|
||||
end
|
||||
|
||||
--- Consolidate aliases for column attributes.
|
||||
-- Provides syntacic sugar: unifies various ways of
|
||||
-- specifying attributes of a multi-column environment.
|
||||
-- When several specifications conflit, favours `column-gap` and
|
||||
-- `column-rule` specifications.
|
||||
-- @param elem Pandoc element (Div of class `columns`) with column attributes.
|
||||
-- @return elem modified as needed.
|
||||
local function consolidate_colattrib_aliases(elem)
|
||||
if elem.attr and elem.attr.attributes then
|
||||
-- `column-gap` if the preferred syntax is set, erase others
|
||||
if elem.attr.attributes["column-gap"] then
|
||||
elem = set_attribute(elem, "columngap", nil)
|
||||
elem = set_attribute(elem, "column-sep", nil)
|
||||
elem = set_attribute(elem, "columnsep", nil)
|
||||
|
||||
-- otherwise fetch and unset any alias
|
||||
else
|
||||
if elem.attr.attributes["columnsep"] then
|
||||
elem = set_attribute(elem, "column-gap",
|
||||
elem.attr.attributes["columnsep"])
|
||||
elem = set_attribute(elem, "columnsep", nil)
|
||||
end
|
||||
|
||||
if elem.attr.attributes["column-sep"] then
|
||||
elem = set_attribute(elem, "column-gap",
|
||||
elem.attr.attributes["column-sep"])
|
||||
elem = set_attribute(elem, "column-sep", nil)
|
||||
end
|
||||
|
||||
if elem.attr.attributes["columngap"] then
|
||||
elem = set_attribute(elem, "column-gap",
|
||||
elem.attr.attributes["columngap"])
|
||||
elem = set_attribute(elem, "columngap", nil)
|
||||
end
|
||||
end
|
||||
|
||||
-- `column-rule` if the preferred syntax is set, erase others
|
||||
if elem.attr.attributes["column-rule"] then
|
||||
elem = set_attribute(elem, "columnrule", nil)
|
||||
|
||||
-- otherwise fetch and unset any alias
|
||||
else
|
||||
if elem.attr.attributes["columnrule"] then
|
||||
elem = set_attribute(elem, "column-rule",
|
||||
elem.attr.attributes["columnrule"])
|
||||
elem = set_attribute(elem, "columnrule", nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return elem
|
||||
end
|
||||
|
||||
--- Pre-process a Div of class `columns`.
|
||||
-- Converts explicit column breaks into a unified syntax
|
||||
-- and count the Div's number of columns.
|
||||
-- When several columns are nested Pandoc will apply
|
||||
-- this filter to the innermost `columns` Div first;
|
||||
-- we use that feature to prevent double-counting.
|
||||
-- @param elem Pandoc element to be processes (Div of class `columns`)
|
||||
-- @return elem modified as needed
|
||||
local function preprocess_columns(elem)
|
||||
-- convert any explicit column syntax in a single format:
|
||||
-- native Divs with class `columnbreak`
|
||||
|
||||
elem = convert_explicit_columbreaks(elem)
|
||||
|
||||
-- count explicit columnbreaks
|
||||
|
||||
elem = tag_with_number_of_explicit_columnbreaks(elem)
|
||||
|
||||
return elem
|
||||
end
|
||||
|
||||
--- Determine the number of column in a `columns` Div.
|
||||
-- Looks up two attributes in the Div: the user-specified
|
||||
-- `columns-count` and the filter-generated `number_explicit_columnbreaks`
|
||||
-- which is based on the number of explicit breaks specified.
|
||||
-- The final number of columns will be 2 or whichever of `column-count` and
|
||||
-- `number_explicit_columnbreaks` is the highest. This ensures there are
|
||||
-- enough columns for all explicit columnbreaks.
|
||||
-- This provides a single-column when the user specifies `column-count = 1` and
|
||||
-- there are no explicit columnbreaks.
|
||||
-- @param elem Pandoc element (Div of class `columns`) whose number of columns is to be determined.
|
||||
-- @return number of columns (number, default 2).
|
||||
local function determine_column_count(elem)
|
||||
-- is there a specified column count?
|
||||
local specified_column_count = 0
|
||||
if elem.attr.attributes and elem.attr.attributes['column-count'] then
|
||||
specified_column_count = tonumber(
|
||||
elem.attr.attributes["column-count"])
|
||||
end
|
||||
|
||||
-- is there an count of explicit columnbreaks?
|
||||
local number_explicit_columnbreaks = 0
|
||||
if elem.attr.attributes and elem.attr.attributes['number_explicit_columnbreaks'] then
|
||||
number_explicit_columnbreaks = tonumber(
|
||||
elem.attr.attributes['number_explicit_columnbreaks']
|
||||
)
|
||||
|
||||
set_attribute(elem, 'number_explicit_columnbreaks', nil)
|
||||
end
|
||||
|
||||
-- determines the number of columns
|
||||
-- default 2
|
||||
-- recall that number of columns = nb columnbreaks + 1
|
||||
|
||||
local number_columns = 2
|
||||
|
||||
if specified_column_count > 0 or number_explicit_columnbreaks > 0 then
|
||||
if (number_explicit_columnbreaks + 1) > specified_column_count then
|
||||
number_columns = number_explicit_columnbreaks + 1
|
||||
else
|
||||
number_columns = specified_column_count
|
||||
end
|
||||
end
|
||||
|
||||
return number_columns
|
||||
end
|
||||
|
||||
--- Convert a pandoc Header to a list of inlines for latex output.
|
||||
-- @param header Pandoc Header element
|
||||
-- @return list of Inline elements
|
||||
local function header_to_latex_and_inlines(header)
|
||||
-- @todo check if level interpretation has been shifted, e.g. section is level 2
|
||||
-- @todo we could check the Pandoc state to check whether hypertargets are required?
|
||||
|
||||
local latex_header = {
|
||||
'section',
|
||||
'subsection',
|
||||
'subsubsection',
|
||||
'paragraph',
|
||||
'subparagraph',
|
||||
}
|
||||
|
||||
-- create a list if the header's inlines
|
||||
local inlines = pandoc.List:new(header.content)
|
||||
|
||||
-- wrap in a latex_header if available
|
||||
|
||||
if header.level and latex_header[header.level] then
|
||||
inlines:insert(1, pandoc.RawInline('latex',
|
||||
'\\' .. latex_header[header.level] .. '{'))
|
||||
inlines:insert(pandoc.RawInline('latex', '}'))
|
||||
end
|
||||
|
||||
-- wrap in a link if available
|
||||
if header.identifier then
|
||||
inlines:insert(1, pandoc.RawInline('latex',
|
||||
'\\hypertarget{' .. header.identifier .. '}{%\n'))
|
||||
inlines:insert(pandoc.RawInline('latex',
|
||||
'\\label{' .. header.identifier .. '}}'))
|
||||
end
|
||||
|
||||
return inlines
|
||||
end
|
||||
|
||||
--- Format column span in LaTeX.
|
||||
-- Formats a bit of text spanning across all columns for LaTeX output.
|
||||
-- If the colspan is only one block, it is turned into an option
|
||||
-- of a new `multicol` environment. Otherwise insert it is
|
||||
-- inserted between the two `multicol` environments.
|
||||
-- @param elem Pandoc element that is supposed to span across all
|
||||
-- columns.
|
||||
-- @param number_columns number of columns in the present environment.
|
||||
-- @return a pandoc RawBlock element in LaTeX format
|
||||
local function format_colspan_latex(elem, number_columns)
|
||||
local result = pandoc.List:new()
|
||||
|
||||
-- does the content consists of a single header?
|
||||
|
||||
if #elem.content == 1 and elem.content[1].t == 'Header' then
|
||||
-- create a list of inlines
|
||||
inlines = pandoc.List:new()
|
||||
inlines:insert(pandoc.RawInline('latex',
|
||||
"\\end{multicols}\n"))
|
||||
inlines:insert(pandoc.RawInline('latex',
|
||||
"\\begin{multicols}{" .. number_columns .. "}["))
|
||||
inlines:extend(header_to_latex_and_inlines(elem.content[1]))
|
||||
inlines:insert(pandoc.RawInline('latex', "]\n"))
|
||||
|
||||
-- insert as a Plain block
|
||||
result:insert(pandoc.Plain(inlines))
|
||||
|
||||
return result
|
||||
else
|
||||
result:insert(pandoc.RawBlock('latex',
|
||||
"\\end{multicols}\n"))
|
||||
result:extend(elem.content)
|
||||
result:insert(pandoc.RawBlock('latex',
|
||||
"\\begin{multicols}{" .. number_columns .. "}"))
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
--- Format columns for LaTeX output
|
||||
-- @param elem Pandoc element (Div of "columns" class) containing the
|
||||
-- columns to be formatted.
|
||||
-- @return elem with suitable RawBlocks in LaTeX added
|
||||
local function format_columns_latex(elem)
|
||||
-- make content into a List object
|
||||
pandoc.List:new(elem.content)
|
||||
|
||||
-- how many columns?
|
||||
number_columns = determine_column_count(elem)
|
||||
|
||||
-- set properties and insert LaTeX environment
|
||||
-- we wrap the entire environment in `{...}` to
|
||||
-- ensure properties (gap, rule) don't carry
|
||||
-- over to following columns
|
||||
|
||||
local latex_begin = '{'
|
||||
local latex_end = '}'
|
||||
local ragged = options.raggedcolumns
|
||||
|
||||
-- override global ragged setting?
|
||||
if elem.classes:includes('ragged')
|
||||
or elem.classes:includes('raggedcolumns')
|
||||
or elem.classes:includes('ragged-columns') then
|
||||
ragged = true
|
||||
elseif elem.classes:includes('justified')
|
||||
or elem.classes:includes('justifiedcolumns')
|
||||
or elem.classes:includes('justified-columns') then
|
||||
ragged = false
|
||||
end
|
||||
if ragged then
|
||||
latex_begin = latex_begin .. '\\raggedcolumns'
|
||||
end
|
||||
|
||||
if elem.attr.attributes then
|
||||
if elem.attr.attributes["column-gap"] then
|
||||
local latex_value = ensures_latex_length(
|
||||
elem.attr.attributes["column-gap"])
|
||||
|
||||
if latex_value then
|
||||
latex_begin = latex_begin ..
|
||||
"\\setlength{\\columnsep}{" .. latex_value .. "}\n"
|
||||
end
|
||||
|
||||
-- remove the `column-gap` attribute
|
||||
elem = set_attribute(elem, "column-gap", nil)
|
||||
end
|
||||
|
||||
if elem.attr.attributes["column-rule"] then
|
||||
-- converts CSS value string to LaTeX values
|
||||
local latex_values = css_values_to_latex(
|
||||
elem.attr.attributes["column-rule"])
|
||||
|
||||
if latex_values["length"] then
|
||||
latex_begin = latex_begin ..
|
||||
"\\setlength{\\columnseprule}{" ..
|
||||
latex_values["length"] .. "}\n"
|
||||
end
|
||||
|
||||
if latex_values["color"] then
|
||||
latex_begin = latex_begin ..
|
||||
"\\renewcommand{\\columnseprulecolor}{\\color{" ..
|
||||
latex_values["color"] .. "}}\n"
|
||||
end
|
||||
|
||||
|
||||
-- remove the `column-rule` attribute
|
||||
elem = set_attribute(elem, "column-rule", nil)
|
||||
end
|
||||
end
|
||||
|
||||
latex_begin = latex_begin ..
|
||||
"\\begin{multicols}{" .. number_columns .. "}\n"
|
||||
latex_end = "\\end{multicols}\n" .. latex_end
|
||||
|
||||
elem.content:insert(1, pandoc.RawBlock('latex', latex_begin))
|
||||
elem.content:insert(pandoc.RawBlock('latex', latex_end))
|
||||
|
||||
-- process blocks contained in `elem`
|
||||
-- turn any explicit columnbreaks into LaTeX markup
|
||||
-- turn `column-span` Divs into LaTeX markup
|
||||
|
||||
filter = {
|
||||
|
||||
Div = function(el)
|
||||
if el.classes:includes("columnbreak") then
|
||||
return pandoc.RawBlock('latex', "\\columnbreak\n")
|
||||
end
|
||||
|
||||
if el.classes:includes("column-span-to-be-processed") then
|
||||
return format_colspan_latex(el, number_columns)
|
||||
end
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
elem = pandoc.walk_block(elem, filter)
|
||||
|
||||
return elem
|
||||
end
|
||||
|
||||
|
||||
--- Formats columns for html output.
|
||||
-- Uses CSS3 style added to the elements themselves.
|
||||
-- @param elem Pandoc element (Div of `columns` style)
|
||||
-- @return elem with suitable html attributes
|
||||
local function format_columns_html(elem)
|
||||
-- how many columns?
|
||||
number_columns = determine_column_count(elem)
|
||||
|
||||
-- add properties to the `columns` Div
|
||||
|
||||
elem = add_to_html_style(elem, 'column-count: ' .. number_columns)
|
||||
elem = set_attribute(elem, 'column-count', nil)
|
||||
|
||||
if elem.attr.attributes then
|
||||
if elem.attr.attributes["column-gap"] then
|
||||
elem = add_to_html_style(elem, 'column-gap: ' ..
|
||||
elem.attr.attributes["column-gap"])
|
||||
|
||||
-- remove the `column-gap` attribute
|
||||
elem = set_attribute(elem, "column-gap")
|
||||
end
|
||||
|
||||
if elem.attr.attributes["column-rule"] then
|
||||
elem = add_to_html_style(elem, 'column-rule: ' ..
|
||||
elem.attr.attributes["column-rule"])
|
||||
|
||||
-- remove the `column-rule` attribute
|
||||
elem = set_attribute(elem, "column-rule", nil)
|
||||
end
|
||||
end
|
||||
|
||||
-- convert any explicit columnbreaks in CSS markup
|
||||
|
||||
filter = {
|
||||
|
||||
Div = function(el)
|
||||
-- format column-breaks
|
||||
if el.classes:includes("columnbreak") then
|
||||
el = add_to_html_style(el, 'break-after: column')
|
||||
|
||||
-- remove columbreaks class to avoid double processing
|
||||
-- when nested
|
||||
-- clean up already-counted tag
|
||||
el = remove_class(el, "columnbreak")
|
||||
el = remove_class(el, "columnbreak_already_counted")
|
||||
|
||||
-- format column-spans
|
||||
elseif el.classes:includes("column-span-to-be-processed") then
|
||||
el = add_to_html_style(el, 'column-span: all')
|
||||
|
||||
-- remove column-span-to-be-processed class to avoid double processing
|
||||
-- add column-span class to allow for styling
|
||||
el = add_class(el, "column-span")
|
||||
el = remove_class(el, "column-span-to-be-processed")
|
||||
end
|
||||
|
||||
return el
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
elem = pandoc.walk_block(elem, filter)
|
||||
|
||||
return elem
|
||||
end
|
||||
|
||||
|
||||
-- # Main filters
|
||||
|
||||
--- Formating filter.
|
||||
-- Applied last, converts prepared columns in target output formats
|
||||
-- @field Div looks for `columns` class
|
||||
format_filter = {
|
||||
|
||||
Div = function(element)
|
||||
-- pick up `columns` Divs for formatting
|
||||
if element.classes:includes("columns") then
|
||||
if FORMAT:match('latex') then
|
||||
element = format_columns_latex(element)
|
||||
elseif FORMAT:match('html.*') then
|
||||
element = format_columns_html(element)
|
||||
end
|
||||
|
||||
return element
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--- Preprocessing filter.
|
||||
-- Processes meta-data fields and walks the document to pre-process
|
||||
-- columns blocks. Determine how many columns they contain, tags the
|
||||
-- last column Div, etc. Avoids double-counting when columns environments
|
||||
-- are nested.
|
||||
-- @field Div looks for `columns` class
|
||||
-- @field Meta processes the metadata block
|
||||
preprocess_filter = {
|
||||
|
||||
Div = function(element)
|
||||
-- send `columns` Divs to pre-processing
|
||||
if element.classes:includes("columns") then
|
||||
return preprocess_columns(element)
|
||||
end
|
||||
end,
|
||||
|
||||
Meta = function(meta)
|
||||
return process_meta(meta)
|
||||
end
|
||||
}
|
||||
|
||||
--- Syntactic sugar filter.
|
||||
-- Provides alternative ways of specifying columns properties.
|
||||
-- Kept separate from the pre-processing filter for clarity.
|
||||
-- @field Div looks for Div of classes `columns` (and related) and `column-span`
|
||||
syntactic_sugar_filter = {
|
||||
|
||||
Div = function(element)
|
||||
-- convert "two-columns" into `columns` Divs
|
||||
for _, class in pairs(element.classes) do
|
||||
-- match xxxcolumns, xxx_columns, xxx-columns
|
||||
-- if xxx is the name of a number, make
|
||||
-- a `columns` div and set its `column-count` attribute
|
||||
local number = number_by_name(
|
||||
string.match(class, '(%a+)[_%-]?columns$')
|
||||
)
|
||||
|
||||
if number then
|
||||
element = set_attribute(element,
|
||||
"column-count", tostring(number))
|
||||
element = remove_class(element, class)
|
||||
element = add_class(element, "columns")
|
||||
end
|
||||
end
|
||||
|
||||
-- allows different ways of specifying `columns` attributes
|
||||
if element.classes:includes('columns') then
|
||||
element = consolidate_colattrib_aliases(element)
|
||||
end
|
||||
|
||||
-- `column-span` syntax
|
||||
-- mark up as "to-be-processed" to avoid
|
||||
-- double processing when nested
|
||||
if element.classes:includes('column-span') or
|
||||
element.classes:includes('columnspan') then
|
||||
element = add_class(element, 'column-span-to-be-processed')
|
||||
element = remove_class(element, 'column-span')
|
||||
element = remove_class(element, 'columnspan')
|
||||
end
|
||||
|
||||
return element
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
--- Read options filter
|
||||
read_options_filter = {
|
||||
Meta = function(meta)
|
||||
if not meta then return end
|
||||
|
||||
-- global vertical ragged / justified settings
|
||||
if meta.raggedcolumns or meta['ragged-columns'] then
|
||||
options.raggedcolumns = true
|
||||
elseif meta.justifiedcolumns or meta['justified-columns'] then
|
||||
options.raggedcolumns = false
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
-- Main statement returns filters only if the
|
||||
-- target format matches our list. The filters
|
||||
-- returned are applied in the following order:
|
||||
-- 1. `syntatic_sugar_filter` deals with multiple syntax
|
||||
-- 2. `preprocessing_filter` converts all explicit
|
||||
-- columnbreaks into a common syntax and tags
|
||||
-- those that are already counted. We must do
|
||||
-- that for all `columns` environments before
|
||||
-- turning any break back into LaTeX `\columnbreak` blocks
|
||||
-- otherwise we mess up the count in nested `columns` Divs.
|
||||
-- 3. `format_filter` formats the columns after the counting
|
||||
-- has been done
|
||||
if format_matches(target_formats) then
|
||||
return {
|
||||
read_options_filter,
|
||||
syntactic_sugar_filter,
|
||||
preprocess_filter,
|
||||
format_filter
|
||||
}
|
||||
else
|
||||
return
|
||||
end
|
15
docker-compose.yml
Normal file
@ -0,0 +1,15 @@
|
||||
version: "2.4"
|
||||
services:
|
||||
void:
|
||||
# if you want to build your own container locally:
|
||||
# container_name: paper-builder
|
||||
# build: .
|
||||
image: baldeau/paper-builder
|
||||
platform: linux/amd64
|
||||
volumes:
|
||||
- ".:/paper"
|
||||
environment:
|
||||
- PATH=$PATH:~/.local/bin
|
||||
- PATH=$PATH:~/.cabal/bin
|
||||
- TERM=xterm-256color
|
||||
command: bash -c "cd paper && ./docker_build.sh"
|
11
docker_build.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
shopt -s globstar # Enable recursive globbing
|
||||
|
||||
markdown_files=(chapters/**/*.md)
|
||||
|
||||
IFS=$'\n'
|
||||
sorted_files=($(sort <<<"${markdown_files[*]}"));
|
||||
unset IFS
|
||||
|
||||
echo "${sorted_files[@]}"
|
||||
MERMAID_FILTER_FORMAT=pdf pandoc -V colorlinks=true -V linkcolor=black -V urlcolor=black -f 'markdown+autolink_bare_uris' --pdf-engine=lualatex --pdf-engine-opt=-shell-escape --filter mermaid-filter --lua-filter columns.lua --citeproc -s "${sorted_files[@]}" -o ./out/bachelor.pdf -V lang=de-DE -V fontsize=11pt --highlight-style tango --reference-links --bibliography Bachelor.bib --csl=harvard-right.csl -M lang:de --number-sections
|
318
harvard-right.csl
Normal file
@ -0,0 +1,318 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only" default-locale="en-GB">
|
||||
<info>
|
||||
<title>Cite Them Right 11th edition - Harvard</title>
|
||||
<id>http://www.zotero.org/styles/harvard-cite-them-right</id>
|
||||
<link href="http://www.zotero.org/styles/harvard-cite-them-right" rel="self"/>
|
||||
<link href="http://www.zotero.org/styles/harvard-cite-them-right-10th-edition" rel="template"/>
|
||||
<link href="http://www.citethemrightonline.com/" rel="documentation"/>
|
||||
<author>
|
||||
<name>Patrick O'Brien</name>
|
||||
</author>
|
||||
<category citation-format="author-date"/>
|
||||
<category field="generic-base"/>
|
||||
<summary>Harvard according to Cite Them Right, 11th edition.</summary>
|
||||
<updated>2021-09-01T07:43:59+00:00</updated>
|
||||
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
|
||||
</info>
|
||||
<locale xml:lang="en-GB">
|
||||
<terms>
|
||||
<term name="editor" form="short">
|
||||
<single>ed.</single>
|
||||
<multiple>eds</multiple>
|
||||
</term>
|
||||
<term name="editortranslator" form="verb">edited and translated by</term>
|
||||
<term name="edition" form="short">edn.</term>
|
||||
</terms>
|
||||
</locale>
|
||||
<macro name="editor">
|
||||
<choose>
|
||||
<if type="chapter paper-conference" match="any">
|
||||
<names variable="container-author" delimiter=", " suffix=", ">
|
||||
<name and="text" initialize-with=". " delimiter=", " sort-separator=", " name-as-sort-order="all"/>
|
||||
</names>
|
||||
<choose>
|
||||
<if variable="container-author" match="none">
|
||||
<names variable="editor translator" delimiter=", ">
|
||||
<name and="text" initialize-with="." name-as-sort-order="all"/>
|
||||
<label form="short" prefix=" (" suffix=")"/>
|
||||
</names>
|
||||
</if>
|
||||
</choose>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="secondary-contributors">
|
||||
<choose>
|
||||
<if type="chapter paper-conference" match="none">
|
||||
<names variable="editor translator" delimiter=". ">
|
||||
<label form="verb" text-case="capitalize-first" suffix=" "/>
|
||||
<name and="text" initialize-with="."/>
|
||||
</names>
|
||||
</if>
|
||||
<else-if variable="container-author" match="any">
|
||||
<names variable="editor translator" delimiter=". ">
|
||||
<label form="verb" text-case="capitalize-first" suffix=" "/>
|
||||
<name and="text" initialize-with=". " delimiter=", "/>
|
||||
</names>
|
||||
</else-if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="author">
|
||||
<names variable="author">
|
||||
<name and="text" delimiter-precedes-last="never" initialize-with="." name-as-sort-order="all"/>
|
||||
<label form="short" prefix=" (" suffix=")"/>
|
||||
<et-al font-style="italic"/>
|
||||
<substitute>
|
||||
<names variable="editor"/>
|
||||
<names variable="translator"/>
|
||||
<choose>
|
||||
<if type="article-newspaper article-magazine" match="any">
|
||||
<text variable="container-title" text-case="title" font-style="italic"/>
|
||||
</if>
|
||||
<else>
|
||||
<text macro="title"/>
|
||||
</else>
|
||||
</choose>
|
||||
</substitute>
|
||||
</names>
|
||||
</macro>
|
||||
<macro name="author-short">
|
||||
<names variable="author">
|
||||
<name form="short" and="text" delimiter=", " delimiter-precedes-last="never" initialize-with=". "/>
|
||||
<et-al font-style="italic"/>
|
||||
<substitute>
|
||||
<names variable="editor"/>
|
||||
<names variable="translator"/>
|
||||
<choose>
|
||||
<if type="article-newspaper article-magazine" match="any">
|
||||
<text variable="container-title" text-case="title" font-style="italic"/>
|
||||
</if>
|
||||
<else>
|
||||
<text macro="title"/>
|
||||
</else>
|
||||
</choose>
|
||||
</substitute>
|
||||
</names>
|
||||
</macro>
|
||||
<macro name="access">
|
||||
<choose>
|
||||
<if variable="DOI">
|
||||
<text variable="DOI" prefix="doi:"/>
|
||||
</if>
|
||||
<else-if variable="URL">
|
||||
<text term="available at" suffix=": " text-case="capitalize-first"/>
|
||||
<text variable="URL"/>
|
||||
<group prefix=" (" delimiter=": " suffix=")">
|
||||
<text term="accessed" text-case="capitalize-first"/>
|
||||
<date form="text" variable="accessed">
|
||||
<date-part name="day"/>
|
||||
<date-part name="month"/>
|
||||
<date-part name="year"/>
|
||||
</date>
|
||||
</group>
|
||||
</else-if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="number-volumes">
|
||||
<choose>
|
||||
<if variable="volume" match="none">
|
||||
<group delimiter=" " prefix="(" suffix=")">
|
||||
<text variable="number-of-volumes"/>
|
||||
<label variable="volume" form="short" strip-periods="true"/>
|
||||
</group>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="title">
|
||||
<choose>
|
||||
<if type="bill book legal_case legislation motion_picture report song thesis webpage graphic" match="any">
|
||||
<group delimiter=". ">
|
||||
<group delimiter=" ">
|
||||
<group delimiter=" ">
|
||||
<text variable="title" font-style="italic"/>
|
||||
<text variable="medium" prefix="[" suffix="]"/>
|
||||
</group>
|
||||
<text macro="number-volumes"/>
|
||||
</group>
|
||||
<text macro="edition"/>
|
||||
</group>
|
||||
</if>
|
||||
<else>
|
||||
<text variable="title" form="long" quotes="true"/>
|
||||
</else>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="publisher">
|
||||
<choose>
|
||||
<if type="thesis">
|
||||
<group delimiter=". ">
|
||||
<text variable="genre"/>
|
||||
<text variable="publisher"/>
|
||||
</group>
|
||||
</if>
|
||||
<else-if type="report">
|
||||
<group delimiter=". ">
|
||||
<group delimiter=" ">
|
||||
<text variable="genre"/>
|
||||
<text variable="number"/>
|
||||
</group>
|
||||
<group delimiter=": ">
|
||||
<text variable="publisher-place"/>
|
||||
<text variable="publisher"/>
|
||||
</group>
|
||||
</group>
|
||||
</else-if>
|
||||
<else-if type="article-journal article-newspaper article-magazine" match="none">
|
||||
<group delimiter=" ">
|
||||
<group delimiter=", ">
|
||||
<choose>
|
||||
<if type="speech" variable="event" match="any">
|
||||
<text variable="event" font-style="italic"/>
|
||||
</if>
|
||||
</choose>
|
||||
<group delimiter=": ">
|
||||
<text variable="publisher-place"/>
|
||||
<text variable="publisher"/>
|
||||
</group>
|
||||
</group>
|
||||
<group prefix="(" suffix=")" delimiter=", ">
|
||||
<text variable="collection-title"/>
|
||||
<text variable="collection-number"/>
|
||||
</group>
|
||||
</group>
|
||||
</else-if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="year-date">
|
||||
<choose>
|
||||
<if variable="issued">
|
||||
<date variable="issued">
|
||||
<date-part name="year"/>
|
||||
</date>
|
||||
<text variable="year-suffix"/>
|
||||
</if>
|
||||
<else>
|
||||
<text term="no date"/>
|
||||
<text variable="year-suffix" prefix=" "/>
|
||||
</else>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="locator">
|
||||
<choose>
|
||||
<if type="article-journal">
|
||||
<text variable="volume"/>
|
||||
<text variable="issue" prefix="(" suffix=")"/>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="published-date">
|
||||
<choose>
|
||||
<if type="article-newspaper article-magazine post-weblog speech" match="any">
|
||||
<date variable="issued">
|
||||
<date-part name="day" suffix=" "/>
|
||||
<date-part name="month" form="long"/>
|
||||
</date>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="pages">
|
||||
<choose>
|
||||
<if type="chapter paper-conference article-journal article article-magazine article-newspaper book review review-book report" match="any">
|
||||
<group delimiter=" ">
|
||||
<label variable="page" form="short"/>
|
||||
<text variable="page"/>
|
||||
</group>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="container-title">
|
||||
<choose>
|
||||
<if variable="container-title">
|
||||
<group delimiter=". ">
|
||||
<group delimiter=" ">
|
||||
<text variable="container-title" font-style="italic"/>
|
||||
<choose>
|
||||
<if type="article article-journal" match="any">
|
||||
<choose>
|
||||
<if match="none" variable="page volume">
|
||||
<text value="Preprint" prefix="[" suffix="]"/>
|
||||
</if>
|
||||
</choose>
|
||||
</if>
|
||||
</choose>
|
||||
</group>
|
||||
<text macro="edition"/>
|
||||
</group>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="edition">
|
||||
<choose>
|
||||
<if is-numeric="edition">
|
||||
<group delimiter=" ">
|
||||
<number variable="edition" form="ordinal"/>
|
||||
<text term="edition" form="short" strip-periods="true"/>
|
||||
</group>
|
||||
</if>
|
||||
<else>
|
||||
<text variable="edition"/>
|
||||
</else>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="container-prefix">
|
||||
<choose>
|
||||
<if type="chapter paper-conference" match="any">
|
||||
<text term="in"/>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<citation et-al-min="4" et-al-use-first="1" disambiguate-add-year-suffix="true" disambiguate-add-names="true" disambiguate-add-givenname="true" collapse="year">
|
||||
<sort>
|
||||
<key macro="year-date"/>
|
||||
</sort>
|
||||
<layout prefix="(" suffix=")" delimiter="; ">
|
||||
<group delimiter=", ">
|
||||
<group delimiter=", ">
|
||||
<text macro="author-short"/>
|
||||
<text macro="year-date"/>
|
||||
</group>
|
||||
<group>
|
||||
<label variable="locator" form="short" suffix=" "/>
|
||||
<text variable="locator"/>
|
||||
</group>
|
||||
</group>
|
||||
</layout>
|
||||
</citation>
|
||||
<bibliography and="text" et-al-min="4" et-al-use-first="1">
|
||||
<sort>
|
||||
<key macro="author"/>
|
||||
<key macro="year-date"/>
|
||||
<key variable="title"/>
|
||||
</sort>
|
||||
<layout suffix=".">
|
||||
<group delimiter=". ">
|
||||
<group delimiter=" ">
|
||||
<text macro="author"/>
|
||||
<text macro="year-date" prefix="(" suffix=")"/>
|
||||
<group delimiter=", ">
|
||||
<text macro="title"/>
|
||||
<group delimiter=" ">
|
||||
<text macro="container-prefix"/>
|
||||
<text macro="editor"/>
|
||||
<text macro="container-title"/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<text macro="secondary-contributors"/>
|
||||
<text macro="publisher"/>
|
||||
</group>
|
||||
<group delimiter=", " prefix=", ">
|
||||
<text macro="locator"/>
|
||||
<text macro="published-date"/>
|
||||
<text macro="pages"/>
|
||||
</group>
|
||||
<text macro="access" prefix=". "/>
|
||||
</layout>
|
||||
</bibliography>
|
||||
</style>
|
361
refract.sty
Normal file
@ -0,0 +1,361 @@
|
||||
%%
|
||||
%% This is the file fzframes.sty
|
||||
%% Author: Kathryn Andersen <http://www.katspace.com>
|
||||
%%
|
||||
%% This provides a collection of nice frames based on the niceframes
|
||||
%% package
|
||||
%%
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{refract}[2001/06/22
|
||||
fancy frames for fanzine package
|
||||
: Kathryn Andersen]
|
||||
\RequirePackage{niceframe}
|
||||
\RequirePackage{graphics}
|
||||
|
||||
%% Frame with scrolly things
|
||||
\newcommand{\fzframescroll}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char'136}{\border\char'137}{\border\char'140}
|
||||
{\border\char'145} {\border\char'141}
|
||||
{\border\char'144}{\border\char'143}{\border\char'142}
|
||||
{#1}}
|
||||
%% Frame with flowers
|
||||
\newcommand{\fzframeflower}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char78}{\border\char79}{\border\char84}
|
||||
{\border\char81} {\border\char85}
|
||||
{\border\char80}{\border\char83}{\border\char82}
|
||||
{#1}}
|
||||
|
||||
%% Frame with snakes
|
||||
\newcommand{\fzframesnake}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char87}{\border\char87}{\border\char87}
|
||||
{\border\char89} {\border\char93}
|
||||
{\border\char91}{\border\char91}{\border\char91}
|
||||
{#1}}
|
||||
|
||||
%% Frame with triangles
|
||||
\newcommand{\fzframetri}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char7}{\border\char6}{\border\char5}
|
||||
{\reflectbox{\border\char4}} {\border\char4}
|
||||
{\border\char1}{\border\char2}{\border\char3}
|
||||
{#1}}
|
||||
%% Frame with triangles pointing out
|
||||
\newcommand{\fzframetriout}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char3}{\border\char2}{\border\char1}
|
||||
{\border\char4} {\reflectbox{\border\char4}}
|
||||
{\border\char5}{\border\char6}{\border\char7}
|
||||
{#1}}
|
||||
|
||||
%% Here follows a collection of frames made of decorative boxes
|
||||
%% so they are called fzframebx with a letter to differentiate
|
||||
%% them, A-Z
|
||||
\newcommand{\fzframebxA}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char39}{\border\char37}{\border\char37}
|
||||
{\border\char39} {\border\char43}
|
||||
{\border\char41}{\border\char41}{\border\char43}
|
||||
{#1}}
|
||||
%
|
||||
\newcommand{\fzframebxB}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char41}{\border\char41}{\border\char39}
|
||||
{\border\char43} {\border\char39}
|
||||
{\border\char43}{\border\char37}{\border\char37}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframebxC}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char38}{\border\char38}{\border\char36}
|
||||
{\border\char38} {\border\char36}
|
||||
{\border\char40}{\border\char40}{\border\char42}
|
||||
{#1}
|
||||
}
|
||||
|
||||
\newcommand{\fzframebxD}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char42}{\border\char40}{\border\char40}
|
||||
{\border\char36} {\border\char38}
|
||||
{\border\char36}{\border\char38}{\border\char38}
|
||||
{#1}
|
||||
}
|
||||
|
||||
\newcommand{\fzframebxE}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char44}{\border\char44}{\border\char50}
|
||||
{\border\char46} {\border\char50}
|
||||
{\border\char46}{\border\char48}{\border\char48}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframebxF}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char51}{\border\char51}{\border\char49}
|
||||
{\border\char45} {\border\char49}
|
||||
{\border\char45}{\border\char47}{\border\char47}
|
||||
{#1}}
|
||||
|
||||
%% Here follows a collection of frames made of circles
|
||||
%% so they are called fzframecir with a letter to differentiate
|
||||
%% them, A-Z
|
||||
\newcommand{\fzframecirA}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char34}{\border\char34}{\border\char34}
|
||||
{\border\char34} {\border\char34}
|
||||
{\border\char34}{\border\char34}{\border\char34}
|
||||
{#1}}
|
||||
\newcommand{\fzframecirB}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char35}{\border\char35}{\border\char35}
|
||||
{\border\char35} {\border\char35}
|
||||
{\border\char35}{\border\char35}{\border\char35}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframecirC}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char20}{\border\char25}{\border\char24}
|
||||
{\border\char22} {\border\char22}
|
||||
{\border\char24}{\border\char25}{\border\char20}
|
||||
{#1}}
|
||||
\newcommand{\fzframecirD}[1]{%
|
||||
\font\border=umranda
|
||||
\generalframe{\border\char26}{\border\char30}{\border\char29}
|
||||
{\border\char27} {\border\char27}
|
||||
{\border\char29}{\border\char30}{\border\char26}
|
||||
{#1}}
|
||||
|
||||
%% Here follows a collection of frames with lots of lines
|
||||
%% so they are called fzframelin with a letter to differentiate
|
||||
%% them, A-Z
|
||||
|
||||
%% This bunch, the border has 6 lines, same thickness
|
||||
\newcommand{\fzframelinA}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char5}{\border\char1}{\border\char4}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char6}{\border\char3}{\border\char7}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinB}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char9}{\border\char1}{\border\char8}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char10}{\border\char3}{\border\char11}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinC}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char13}{\border\char1}{\border\char12}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char14}{\border\char3}{\border\char15}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinD}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char17}{\border\char1}{\border\char16}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char18}{\border\char3}{\border\char19}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinE}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char21}{\border\char1}{\border\char20}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char22}{\border\char3}{\border\char23}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinF}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char25}{\border\char1}{\border\char24}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char26}{\border\char3}{\border\char27}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinG}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char29}{\border\char1}{\border\char28}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char30}{\border\char3}{\border\char31}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinH}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char33}{\border\char1}{\border\char32}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char34}{\border\char3}{\border\char35}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinI}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char37}{\border\char1}{\border\char36}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char38}{\border\char3}{\border\char39}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinJ}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char41}{\border\char1}{\border\char40}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char42}{\border\char3}{\border\char43}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinK}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char45}{\border\char1}{\border\char44}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char46}{\border\char3}{\border\char47}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinL}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char49}{\border\char1}{\border\char48}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char50}{\border\char3}{\border\char51}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinM}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char53}{\border\char1}{\border\char52}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char54}{\border\char3}{\border\char55}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinN}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char57}{\border\char1}{\border\char56}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char58}{\border\char3}{\border\char59}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinO}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char61}{\border\char1}{\border\char60}
|
||||
{\border\char2} {\reflectbox{\border\char2}}
|
||||
{\border\char62}{\border\char3}{\border\char63}
|
||||
{#1}}
|
||||
|
||||
%% Border has 4 lines, same thickness
|
||||
\newcommand{\fzframelinP}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char69}{\border\char65}{\border\char68}
|
||||
{\border\char64} {\border\char66}
|
||||
{\border\char70}{\border\char67}{\border\char71}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinQ}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char73}{\border\char65}{\border\char72}
|
||||
{\border\char64} {\border\char66}
|
||||
{\border\char74}{\border\char67}{\border\char75}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinR}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char77}{\border\char65}{\border\char76}
|
||||
{\border\char64} {\border\char66}
|
||||
{\border\char78}{\border\char67}{\border\char79}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinS}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char81}{\border\char65}{\border\char80}
|
||||
{\border\char64} {\border\char66}
|
||||
{\border\char82}{\border\char67}{\border\char83}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinT}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char85}{\border\char65}{\border\char84}
|
||||
{\border\char64} {\border\char66}
|
||||
{\border\char86}{\border\char67}{\border\char87}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinU}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char89}{\border\char65}{\border\char88}
|
||||
{\border\char64} {\border\char66}
|
||||
{\border\char90}{\border\char67}{\border\char91}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinV}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char93}{\border\char65}{\border\char92}
|
||||
{\border\char64} {\border\char66}
|
||||
{\border\char94}{\border\char67}{\border\char95}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinW}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char97}{\border\char65}{\border\char96}
|
||||
{\border\char64} {\border\char66}
|
||||
{\border\char98}{\border\char67}{\border\char99}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinX}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char101}{\border\char65}{\border\char100}
|
||||
{\border\char64} {\border\char66}
|
||||
{\border\char102}{\border\char67}{\border\char103}
|
||||
{#1}}
|
||||
|
||||
%% Border has 5 lines, the middle one thicker
|
||||
\newcommand{\fzframelinY}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char113}{\border\char105}{\border\char112}
|
||||
{\border\char106} {\border\char104}
|
||||
{\border\char114}{\border\char107}{\border\char115}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinZ}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char113}{\border\char109}{\border\char112}
|
||||
{\border\char110} {\border\char108}
|
||||
{\border\char114}{\border\char111}{\border\char115}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinAA}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char117}{\border\char105}{\border\char116}
|
||||
{\border\char106} {\border\char104}
|
||||
{\border\char118}{\border\char107}{\border\char119}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinAB}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char117}{\border\char109}{\border\char116}
|
||||
{\border\char110} {\border\char108}
|
||||
{\border\char118}{\border\char111}{\border\char119}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinAC}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char121}{\border\char105}{\border\char120}
|
||||
{\border\char106} {\border\char104}
|
||||
{\border\char122}{\border\char107}{\border\char123}
|
||||
{#1}}
|
||||
|
||||
\newcommand{\fzframelinAD}[1]{%
|
||||
\font\border=umrandb
|
||||
\generalframe{\border\char121}{\border\char109}{\border\char120}
|
||||
{\border\char110} {\border\char108}
|
||||
{\border\char122}{\border\char111}{\border\char123}
|
||||
{#1}}
|
||||
|
||||
%%
|
||||
%% Sample of dingbats in a font
|
||||
\RequirePackage{ifthen}
|
||||
\newcounter{clet}
|
||||
\newcounter{numchars}
|
||||
\newcommand{\dingsample}{%
|
||||
\setcounter{clet}{1}
|
||||
\setcounter{numchars}{256}
|
||||
\whiledo{\value{clet}<256}{%
|
||||
\mbox{
|
||||
\texttt{ \theclet\ = }\char\value{clet}
|
||||
}
|
||||
\addtocounter{clet}{1}
|
||||
}
|
||||
}
|
||||
\endinput
|