' \
if "author" in self.attributes else ""
return (f'
\n'
f'{self.convert_text()}'
f'{author}\n
')
if __name__ == "__main__":
run_transform_filter(["epigraph"], latex, html)
PK ! Xb * pandoc_styles/config_dir/filter/include.py"""
Includes other markdown files given in a Code block with the class "include. One
file path per line.
"""
from os.path import isfile
from pandoc_styles import run_pandoc_styles_filter, CodeBlock, file_read
def include(self):
new = "\n".join(file_read(line) for line in self.text.splitlines()
if not line[0] == "#" and isfile(line))
return new
if __name__ == "__main__":
run_pandoc_styles_filter(include, CodeBlock, "include")
PK ! G4~ ~ + pandoc_styles/config_dir/filter/new_page.pyfrom pandoc_styles import run_transform_filter
def latex(self):
if "odd-page" in self.classes:
return r"\cleardoublepage"
return r"\clearpage"
if __name__ == "__main__":
run_transform_filter(["new_page", "new-page"],
latex,
'',
"\n----\n")
PK ! +mOP + pandoc_styles/config_dir/filter/noindent.pyfrom pandoc_styles import run_transform_filter
if __name__ == "__main__":
run_transform_filter(
["noindent", "no-indent", "no_indent"],
'\\noindent\n{text}\n',
'
\n{text}\n
')
PK ! " 0 pandoc_styles/config_dir/filter/numbered_code.pyfrom pandoc_styles import run_pandoc_styles_filter, CodeBlock
def numbered(self):
self.classes.append("numberLines")
if __name__ == "__main__":
run_pandoc_styles_filter(numbered, CodeBlock)
PK ! `+ ' pandoc_styles/config_dir/filter/poem.py"""
Formats poems. The poem has to be inside a Code block with the class "poem".
There are many optional attributes that can be set:
author: The author of the poem
title: The title of the poem
altverse: true or false
poemlines: true or false
In addition you can set a style. Either global by adding the "quote-style" field to
the metadata style definition or by setting the style as a class in the code block.
The three styles are: "bottom", "top" and "one-line".
"""
import re
from pandoc_styles import run_transform_filter, strip_html_tag
def all_formats(self):
self.style = self.get_metadata("poem-style", "bottom")
if "top" in self.classes:
self.style = "top"
elif "bottom" in self.classes:
self.style = "bottom"
elif "one-line" in self.classes:
self.style = "one-line"
def latex(self):
new = []
if self.style == "top" and "title" in self.attributes:
new.extend([r"\poemtitle*{", self.attributes["title"], "}\n"])
if "versewidth" in self.attributes:
new.extend([r"\settowidth{\versewidth}{", self.attributes["versewidth"],
"}", "\n", r"\begin{verse}[\versewidth]", "\n"])
elif "no_versewidth" in self.classes:
new.extend([r'\begin{verse}', "\n"])
else:
lst = []
for line in self.text.split("\n"):
if line and line[0] not in ["!", "[", "{"]:
lst.append((len(line), line))
_, max_line = max(lst)
new.extend([r"\settowidth{\versewidth}{", max_line,
"}\n", r"\begin{verse}[\versewidth]", "\n"])
if "poemlines" in self.attributes:
new.extend([r"\poemlines{", self.attributes["poemlines"], "}\n"])
if "altverse" in self.classes:
new.extend([r"\begin{altverse}", "\n"])
for line in self.text.split("\n"):
if line == "":
if "altverse" in self.classes:
new.extend([r"\\!", r"\end{altverse}", "\n\n", r"\begin{altverse}", "\n"])
else:
new.extend([r"\\!", "\n"])
else:
new.extend([self.convert_text(line).strip("\n"), r"\\", "*", "\n"])
new.extend([r"\\!", "\n"])
if self.style == "top" and "author" in self.attributes:
new.extend([r"\hspace*{\fill}", r"\rightskip2em \textit{",
self.attributes["author"], "}\n"])
elif self.style == "one-line" and "author" in self.attributes and\
"title" in self.attributes:
new.extend([r"\hfill \rightskip2em \textit{", self.attributes["author"],
"} --- ", r"\textbf{", self.attributes["title"], "}\n"])
elif self.style != "top":
if "title" in self.attributes and "author" in self.attributes:
new.extend([r"\hspace*{\fill}", r"\rightskip2em \textbf{",
self.attributes["title"], "}", r"\linebreak"])
new.extend([r"\hspace*{\fill}", r"\rightskip2em \textit{",
self.attributes["author"], "}\n"])
elif "author" in self.attributes:
new.extend([r"\hspace*{\fill}", r"\rightskip2em \textit{",
self.attributes["author"], "}\n"])
elif "title" in self.attributes:
new.extend([r"\hspace*{\fill}", r"\rightskip2em \textbf{",
self.attributes["title"], "}\n"])
if "altverse" in self.classes:
new.extend([r"\end{altverse}", "\n"])
if "poemlines" in self.attributes:
new.extend([r"\poemlines{0", "}\n"])
new.append(r"\end{verse}")
new = ''.join(new)
new = re.sub(r'\\\\\*\n\\\\!', '\\\\\!\n', new) # pylint: disable=W1401
return new
def html(self):
new = ['
']
if self.style == "top" and "title" in self.attributes:
new.extend(["\n
", self.attributes["title"], "
"])
if self.style == "top" and "author" in self.attributes:
new.extend(["\n
", self.attributes["author"], "
"])
new.extend(['\n
'])
i = 0
for line in self.text.split("\n"):
if line == "":
if "altverse" in self.classes:
i = 1
new.extend(['\n
\n
\n
'])
elif "altverse" in self.classes:
if i % 2 == 0:
new.extend(["\n", self.convert_text(line)])
else:
new.extend(["\n
",
strip_html_tag(self.convert_text(line)), "
"])
else:
new.extend(["\n", self.convert_text(line)])
i += 1
new.extend(['\n
'])
if self.style == "one-line" and "author" in self.attributes and\
"title" in self.attributes:
new.extend(["\n
"])
elif self.style != "top":
if "title" in self.attributes:
new.extend(["\n
", self.attributes["title"], "
"])
if "author" in self.attributes:
new.extend(["\n
", self.attributes["author"], "
"])
new.extend(['\n
'])
return new
def other(self):
new = []
if self.style == "top" and "title" in self.attributes:
new.extend(["| __", self.attributes["title"], "__\n"])
if self.style == "top" and "author" in self.attributes:
new.extend(["| _", self.attributes["author"], "_\n"])
if self.style == "top" and ("author" in self.attributes or "title" in self.attributes):
new.extend(["| \n"])
i = 0
for line in self.text.split("\n"):
if line == "":
if "altverse" in self.classes:
i = 1
new.extend(['| ', "\n"])
elif "altverse" in self.classes:
if i % 2 == 0:
new.extend(['| ', line, "\n"])
else:
new.extend(['| ', line, "\n"])
else:
new.extend(['| ', line, "\n"])
i += 1
if self.style == "one-line" and "author" in self.attributes and\
"title" in self.attributes:
new.extend(['| \n| _', self.attributes["author"], '_ --- __',
self.attributes["title"], '__\n'])
elif self.style != "top":
if "title" in self.attributes:
new.extend(['| \n| __', self.attributes["title"], '__\n'])
if "author" in self.attributes:
new.extend(['| \n| _', self.attributes["author"], '_\n'])
new = ''.join(new)
new = re.sub(r'\|\s\|', '|', new, flags=re.MULTILINE)
return new
if __name__ == "__main__":
run_transform_filter(["poem"], latex, html, other, all_formats)
PK ! 8e ( pandoc_styles/config_dir/filter/quote.py"""
Formats quotes with a title and author. The quote has to be inside a Code block with
the class "quote".
There are two optional attributes that can be set:
author: The author of the quote
title: The title/source of the quote
In addition you can set a style. Either global by adding the "quote-style" field to
the metadata style definition or by setting the style as a class in the code block.
The three styles are: "bottom", "top" and "one-line".
"""
from pandoc_styles import run_transform_filter
def all_formats(self):
self.style = self.get_metadata("quote-style", "bottom")
if "top" in self.classes:
self.style = "top"
elif "bottom" in self.classes:
self.style = "bottom"
elif "one-line" in self.classes:
self.style = "one-line"
def latex(self):
new = [r"\begin{quote}", "\n"]
if self.style == "top" and ("title" in self.attributes or "author" in self.attributes):
new.extend([r"\begin{center}", '\n'])
if "title" in self.attributes:
new.extend([r"\large\textbf{", self.attributes["title"], "}\n"])
if "author" in self.attributes:
new.extend(["\n", r"\normalsize\textit{", self.attributes["author"], "}\n"])
new.extend([r"\end{center}", '\n'])
new.extend([self.convert_text(), "\n"])
if self.style == "one-line" and "author" in self.attributes \
and "title" in self.attributes:
new.extend([r"\hfill \textit{", self.attributes["author"], "} --- ",
r"\textbf{", self.attributes["title"], "}\n"])
elif self.style != "top":
if "title" in self.attributes and "author" in self.attributes:
new.extend(["\n", r"\hspace*{\fill}", r"\textbf{",
self.attributes["title"], "}", r"\linebreak"])
new.extend([r"\hspace*{\fill}", r"\textit{",
self.attributes["author"], "}\n"])
elif "author" in self.attributes:
new.extend(["\n", r"\hspace*{\fill}", r"\textit{",
self.attributes["author"], "}\n"])
elif "title" in self.attributes:
new.extend(["\n", r"\hspace*{\fill}", r"\textbf{",
self.attributes["title"], "}\n"])
new.extend([r"\end{quote}", "\n"])
return new
def html(self):
new = ['
']
if self.style == "top" and "title" in self.attributes:
new.extend(['\n
',
self.attributes["title"], "
"])
if self.style == "top" and "author" in self.attributes:
new.extend(['\n
',
self.attributes["author"], "
"])
new.extend(["\n", self.convert_text()])
if self.style == "one-line" and "author" in self.attributes and\
"title" in self.attributes:
new.extend(['\n
Navbar-top:
inherits: Navbar
html:
sass:
variables:
nav-top: true
Extra-styles:
all:
preflight:
- ~/scenes.py
command-line:
filter:
- ~/new_page.py
- ~/epigraph.py
- ~/noindent.py
- ~/alignment.py
- ~/quote.py
- ~/poem.py
- ~/custom_styles.py
metadata:
poem-style: bottom
quote-style: bottom
scenes:
new-scene-style: default
new-scene-text: "* * *"
new-scene-image: false
html:
sass:
files:
- ~/extra_styles.scss
epub:
sass:
files:
- ~/extra_styles.scss
Widows:
pdf:
metadata:
header-includes:
- |
\widowpenalties=3 10000 10000 150
Italic-quotes:
pdf: &pdf-italic-quotes
metadata:
header-includes:
- |
\makeatletter
\g@addto@macro{\quote}{\itshape}
\makeatother
latex:
<< : *pdf-italic-quotes
Bibliography:
all:
preflight:
- ~/append_to_file.py
append-to-file:
- |
# References{.unnumbered}
command-line:
filter:
- pandoc-citeproc
pdf:
append-to-file:
- |
\setlength{\parindent}{-0.5in}
\setlength{\leftskip}{0.5in}
\setlength{\parskip}{8pt}
\noindent
Math:
html:
command-line:
mathjax: true
pdf: &pdf-math
metadata:
header-includes:
- |
\usepackage{newunicodechar}
\newunicodechar{√}{\sqrt}
latex:
<< : *pdf-math
Code:
all:
command-line:
highlight-style: tango
pdf: &pdf-code
metadata:
monofont: Fira Code
# allow code line break
add-to-template:
- |
\usepackage{fvextra}
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines,breakautoindent=true,commandchars=\\\{\}}
- |
\setmonofont[
Contextuals={Alternate}
]{$monofont$}
\makeatletter
\def\verbatim@nolig@list{}
\makeatother
latex:
<< : *pdf-code
Fancy-header:
pdf: &pdf-fancy-header
metadata:
disable-header: false
disable-footer: false
# example options: \headertitle: title, \headerauthor: author, \headerdate: date,
# \thepage: page number, \leftmark: chapter, \rightmark: section
header-left: \headertitle
header-center: false
header-right: \nouppercase\leftmark
footer-left: \headerauthor
footer-center: false
footer-right: \thepage
headrule: true
footrule: true
add-to-template:
- |
\newcommand{\headertitle}{$title$}
\newcommand{\headerauthor}{$for(author)$$author$$sep$, $endfor$}
\newcommand{\headerdate}{$date$}
\usepackage{fancyhdr}
\pagestyle{fancy}
$if(disable-header)$
\fancyhead{}
\renewcommand{\headrulewidth}{0pt}
$else$
\fancyhead{}
\lhead[$if(header-right)$$header-right$$else$$date$$endif$]{$if(header-left)$$header-left$$else$$title$$endif$}
\chead[$if(header-center)$$header-center$$else$$endif$]{$if(header-center)$$header-center$$else$$endif$}
\rhead[$if(header-left)$$header-left$$else$$title$$endif$]{$if(header-right)$$header-right$$else$$date$$endif$}
$if(headrule)$
\renewcommand{\headrulewidth}{0.4pt}
$else$
\renewcommand{\headrulewidth}{0pt}
$endif$
$endif$
$if(disable-footer)$
\renewcommand{\footrulewidth}{0pt}
$else$
\fancyfoot{}
\lfoot[$if(footer-right)$$footer-right$$else$\thepage$endif$]{$if(footer-left)$$footer-left$$else$$for(author)$$author$$sep$, $endfor$$endif$}
\cfoot[$if(footer-center)$$footer-center$$else$$endif$]{$if(footer-center)$$footer-center$$else$$endif$}
\rfoot[$if(footer-left)$$footer-left$$else$$for(author)$$author$$sep$, $endfor$$endif$]{$if(footer-right)$$footer-right$$else$\thepage$endif$}
$if(footrule)$
\renewcommand{\footrulewidth}{0.4pt}
$else$
\renewcommand{\footrulewidth}{0pt}
$endif$
$endif$
latex:
<< : *pdf-fancy-header
# report, book etc. classes for better header/footers
Renew-chaptermark:
pdf:
add-to-template:
- |
\renewcommand{\chaptermark}[1]{ \markboth{#1}{} }
\renewcommand{\sectionmark}[1]{ \markright{#1}{} }
Pdf-title:
pdf: &pdf-title
metadata:
header-includes:
- |
\usepackage{pagecolor}
\usepackage{afterpage}
\usepackage{xcolor}
\usepackage{setspace}
replace-in-template:
- pattern: \\maketitle
replacement-text: |
\begin{titlepage}
\newgeometry{left=6cm}
$if(titlepage-color)$
\definecolor{titlepage-color}{HTML}{$titlepage-color$}
\newpagecolor{titlepage-color}\afterpage{\restorepagecolor}
$endif$
\newcommand{\colorRule}[3][black]{\textcolor[HTML]{#1}{\rule{#2}{#3}}}
\begin{flushleft}
\noindent
\\[-1em]
\color[HTML]{$if(titlepage-text-color)$$titlepage-text-color$$else$5F5F5F$endif$}
\makebox[0pt][l]{\colorRule[$if(titlepage-rule-color)$$titlepage-rule-color$$else$435488$endif$]{1.3\textwidth}{$if(titlepage-rule-height)$$titlepage-rule-height$$else$4$endif$pt}}
\par
\noindent
{
\setstretch{1.4}
\vfill
\noindent {\huge \textbf{\textsf{$title$}}}
$if(subtitle)$
\vskip 1em
{\Large \textsf{$subtitle$}}
$endif$
\vskip 2em
\noindent
{\Large \textsf{$for(author)$$author$$sep$, $endfor$}
\vfill
}
$if(logo)$
\noindent
\includegraphics[width=$if(logo-width)$$logo-width$$else$100$endif$pt, left]{$logo$}
$endif$
\textsf{$date$}}
\end{flushleft}
\end{titlepage}
\restoregeometry
latex:
<< : *pdf-title
Listings:
pdf: &pdf-listings
command-line:
highlight-style: false
listings: true
metadata:
listings-disable-line-numbers: false
listings-frame: single
listings-text-size: small
listings-text-style: ttfamily
listing-numbers-size: tiny
listing-keyword-style: bfseries
listing-identifier-style: upshape
listing-comment-style: itshape
listings-linespread: 1.15
listing-background-color: "F7F7F7"
listing-rule-color: "B3B2B3"
listing-numbers-color: "B3B2B3"
listing-text-color: "000000"
listing-keyword-color: "435489"
listing-identifier-color: "000000"
listing-string-color: "719B6E"
listing-comment-color: "8E8E8E"
add-to-template:
- |
$if(listings)$
\usepackage{xcolor}
$if(listing-background-color)$
\definecolor{listing-background}{HTML}{$listing-background-color$}
$endif$
\definecolor{listing-rule}{HTML}{$listing-rule-color$}
\definecolor{listing-numbers}{HTML}{$listing-numbers-color$}
\definecolor{listing-text-color}{HTML}{$listing-text-color$}
\definecolor{listing-keyword}{HTML}{$listing-keyword-color$}
\definecolor{listing-identifier}{HTML}{$listing-identifier-color$}
\definecolor{listing-string}{HTML}{$listing-string-color$}
\definecolor{listing-comment}{HTML}{$listing-comment-color$}
\lstset{
$if(listings-disable-line-numbers)$
xleftmargin = 0.6em,
framexleftmargin = 0.4em,
$else$
numbers = left,
xleftmargin = 2.7em,
framexleftmargin = 2.5em,
$endif$
$if(listing-background-color)$
backgroundcolor = \color{listing-background},
$endif$
basicstyle = \color{listing-text-color}\$listings-text-size$\$listings-text-style${}\linespread{$listings-linespread$},
breaklines = true,
breakatwhitespace= true,
breakautoindent = true,
frame = $listings-frame$,
framesep = 0.6mm,
rulecolor = \color{listing-rule},
frameround = ffff,
tabsize = 4,
numberstyle = \$listing-numbers-size$\color{listing-numbers},
aboveskip = 1.0em,
belowcaptionskip = 1.0em,
keywordstyle = \color{listing-keyword}\$listing-keyword-style$,
classoffset = 0,
sensitive = true,
identifierstyle = \color{listing-identifier}\$listing-identifier-style$,
commentstyle = \color{listing-comment}\$listing-comment-style$,
stringstyle = \color{listing-string},
showstringspaces = false,
escapeinside = {/*@}{@*/}, % Allow LaTeX inside these special comments
literate =
{á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1
{Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1
{à}{{\`a}}1 {è}{{\'e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1
{À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1
{ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1
{Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1
{â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1
{Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1
{œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1
{ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1
{€}{{\EUR}}1 {£}{{\pounds}}1 {«}{{\guillemotleft}}1
{»}{{\guillemotright}}1 {ñ}{{\~n}}1 {Ñ}{{\~N}}1 {¿}{{?`}}1
{…}{{\ldots}}1 {≥}{{>=}}1 {≤}{{<=}}1 {„}{{\glqq}}1 {“}{{\grqq}}1
{”}{{''}}1
}
$endif$
latex:
<< : *pdf-listings
...
PK ! Q-% % + pandoc_styles/config_dir/template/novel.tex\documentclass[$if(fontsize)$fontsize=$fontsize$,$endif$$if(lang)$$babel-lang$,$endif$$if(DIV)$DIV=$DIV$,$endif$$if(BCOR)$BCOR=$BCOR$,$endif$$if(papersize)$paper=$papersize$,$endif$$if(paper)$paper=$paper$,$endif$$if(parskip)$parskip=$parskip$,$endif$$if(headings)$headings=$headings$,$endif$$if(open)$open=$open$,$endif$$if(toc)$toc=$toc$,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$}
$if(beamerarticle)$
\usepackage{beamerarticle} % needs to be loaded first
$endif$
$for(koma-options)$
\KOMAoption{$koma-options.name$}{$koma-options.arguments$}
$endfor$
$if(fontfamily)$
\usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$}
$else$
\usepackage{lmodern}
$endif$
$if(linestretch)$
\usepackage{setspace}
\setstretch{$linestretch$}
$endif$
\usepackage{verse}
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\usepackage{fixltx2e} % provides \textsubscript
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc}
\usepackage[utf8]{inputenc}
$if(euro)$
\usepackage{eurosym}
$endif$
\else % if luatex or xelatex
\ifxetex
\usepackage{mathspec}
\else
\usepackage{fontspec}
\fi
\defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase}
$for(fontfamilies)$
\newfontfamily\$fontfamilies.name${$fontfamilies.font$}[$fontfamilies.options$]
$endfor$
$if(euro)$
\newcommand{\euro}{€}
$endif$
$if(mainfont)$
\setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$}
$endif$
$if(sansfont)$
\setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$}
$endif$
$if(monofont)$
\setmonofont[Mapping=tex-ansi$if(monofontoptions)$,$for(monofontoptions)$$monofontoptions$$sep$,$endfor$$endif$]{$monofont$}
$endif$
$if(mathfont)$
\setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
$endif$
$if(CJKmainfont)$
\usepackage{xeCJK}
\setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$}
$endif$
\fi
% use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
% use microtype if available
\IfFileExists{microtype.sty}{%
\usepackage{microtype}
\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
\PassOptionsToPackage{backref}{hyperref}
\usepackage{bookmark}
$if(colorlinks)$
\PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref
$endif$
\hypersetup{unicode=true,
$if(title-meta)$
pdftitle={$title-meta$},
$endif$
$if(author-meta)$
pdfauthor={$author-meta$},
$endif$
$if(keywords)$
pdfkeywords={$for(keywords)$$keywords$$sep$; $endfor$},
$endif$
$if(colorlinks)$
colorlinks=true,
linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$,
citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$,
urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$,
$else$
pdfborder={0 0 0},
$endif$
breaklinks=true}
\urlstyle{same} % don't use monospace font for urls
$if(lang)$
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel}
$if(babel-newcommands)$
$babel-newcommands$
$endif$
\else
\usepackage{polyglossia}
\setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$}
$for(polyglossia-otherlangs)$
\setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$}
$endfor$
\fi
$endif$
$if(natbib)$
\usepackage{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(pagestyle)$
\pagestyle{$pagestyle$}
$endif$
\recalctypearea
$if(geometry)$
\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
$endif$
$if(listings)$
\usepackage{listings}
$endif$
$if(lhs)$
\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
$endif$
$if(highlighting-macros)$
$highlighting-macros$
$endif$
$if(verbatim-in-note)$
\usepackage{fancyvrb}
\VerbatimFootnotes % allows verbatim text in footnotes
$endif$
$if(tables)$
\usepackage{longtable,booktabs}
$endif$
$if(graphics)$
\usepackage{graphicx,grffile}
\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}
$endif$
$if(links-as-notes)$
% Make links footnotes instead of hotlinks:
\renewcommand{\href}[2]{#2\footnote{\url{#1}}}
$endif$
$if(strikeout)$
\usepackage[normalem]{ulem}
% avoid problems with \sout in headers with hyperref:
\pdfstringdefDisableCommands{\renewcommand{\sout}{}}
$endif$
$if(noindent)$
\IfFileExists{parskip.sty}{%
\usepackage{parskip}
}{% else
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
}
$endif$
\setlength{\emergencystretch}{3em} % prevent overfull lines
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
$if(number-sections)$
\setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$}
$else$
\setcounter{secnumdepth}{0}
$endif$
$if(subparagraph)$
$else$
% Redefines (sub)paragraphs to behave more like sections
\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$
$if(dir)$
\ifxetex
% load bidi as late as possible as it modifies e.g. graphicx
$if(latex-dir-rtl)$
\usepackage[RTLdocument]{bidi}
$else$
\usepackage{bidi}
$endif$
\fi
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\TeXXeTstate=1
\newcommand{\RL}[1]{\beginR #1\endR}
\newcommand{\LR}[1]{\beginL #1\endL}
\newenvironment{RTL}{\beginR}{\endR}
\newenvironment{LTR}{\beginL}{\endL}
\fi
$endif$
% set default figure placement to htbp
\makeatletter
\def\fps@figure{htbp}
\makeatother
$if(pdf-cover)$
\usepackage{pdfpages}
$endif$
$for(header-includes)$
$header-includes$
$endfor$
$if(subject_title)$
\subject{$subject$}
$endif$
$if(title)$
\title{$title$$if(thanks)$\thanks{$thanks$}$endif$}
$endif$
$if(subtitle)$
\providecommand{\subtitle}[1]{}
\subtitle{$subtitle$}
$endif$
$if(author)$
\author{$for(author)$$author$$sep$ \and $endfor$}
$endif$
$if(institute)$
\providecommand{\institute}[1]{}
\institute{$for(institute)$$institute$$sep$ \and $endfor$}
$endif$
$if(date_title)$
\date{$date$}
$else$
\date{}
$endif$
$if(dedication)$
\dedication{$dedication$}
$endif$
$if(copyrights)$
\lowertitleback{\centering{$copyrights$}}
$endif$
$if(center-headings)$
\renewcommand*{\raggedsection}{\centering}
$endif$
$if(number-sections)$
$else$
\renewcommand*{\partformat}{}
\renewcommand{\chapterlinesformat}[3]{{#3}}
\renewcommand{\sectionlinesformat}[4]{\hskip #2 {#4}}
\usepackage{titletoc}
\titlecontents{part}[0em]
{\vspace{1em}\normalsize\bfseries\sffamily\relax}
{\contentslabel[\relax]{0em}}{}{\hfill\contentspage}
\titlecontents{chapter}[0em]
{\vspace{1em}\normalsize\bfseries\sffamily\relax}
{\contentslabel[\relax]{0em}}{}{\hfill\contentspage}
\titlecontents{section}[0em]
{\vspace{1em}\normalsize\bfseries\sffamily\relax}
{\contentslabel[\relax]{0em}}{}{\hfill\contentspage}
$endif$
$if(toc-dots)$
$else$
\makeatletter
\renewcommand{\@dotsep}{10000}
\makeatother
$endif$
\renewcommand*{\dictumauthorformat}[1]{\textit{#1}}
\renewcommand*{\figureformat}{}
\renewcommand*{\tableformat}{}
\renewcommand*{\captionformat}{}
$for(koma-fonts)$
$if(koma-fonts.element)$
\addtokomafont{$koma-fonts.element$}{$koma-fonts.fontfamily$}
$endif$
$endfor$
\begin{document}
$if(pdf-cover)$
\pagenumbering{gobble}
\includepdf{$pdf-cover$}
\clearpage{\thispagestyle{empty}\cleardoublepage}
\pagenumbering{arabic}
$endif$
$if(title)$
\maketitle
$endif$
$if(abstract)$
\begin{abstract}
$abstract$
\end{abstract}
$endif$
$for(include-before)$
$include-before$
$endfor$
$if(toc)$
{
$if(colorlinks)$
\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$black$endif$}
$endif$
\setcounter{tocdepth}{$toc-depth$}
\tableofcontents
}
$endif$
$if(lot)$
\listoftables
$endif$
$if(lof)$
\listoffigures
$endif$
$body$
$if(natbib)$
$if(bibliography)$
$if(biblio-title)$
$if(book-class)$
\renewcommand\bibname{$biblio-title$}
$else$
\renewcommand\refname{$biblio-title$}
$endif$
$endif$
\bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$}
$endif$
$endif$
$if(biblatex)$
\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$
$endif$
$for(include-after)$
$include-after$
$endfor$
\end{document}
PK ! %*P . pandoc_styles/config_dir/template/scrlttr2.tex\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$lang$,$endif$$if(papersize)$$papersize$,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{scrlttr2}
$if(fontfamily)$
\usepackage{$fontfamily$}
$else$
\usepackage{lmodern}
$endif$
$if(linestretch)$
\usepackage{setspace}
\setstretch{$linestretch$}
$endif$
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\usepackage{fixltx2e} % provides \textsubscript
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
$if(euro)$
\usepackage{eurosym}
$endif$
\else % if luatex or xelatex
\ifxetex
\usepackage{mathspec}
\usepackage{xltxtra,xunicode}
\else
\usepackage{fontspec}
\fi
\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
\newcommand{\euro}{€}
$if(mainfont)$
\setmainfont{$mainfont$}
$endif$
$if(sansfont)$
\setsansfont{$sansfont$}
$endif$
$if(monofont)$
\setmonofont[Mapping=tex-ansi]{$monofont$}
$endif$
$if(mathfont)$
\setmathfont(Digits,Latin,Greek){$mathfont$}
$endif$
\fi
% use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
% use microtype if available
\IfFileExists{microtype.sty}{\usepackage{microtype}}{}
$if(geometry)$
\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
$endif$
$if(listings)$
\usepackage{listings}
$endif$
$if(lhs)$
\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
$endif$
$if(highlighting-macros)$
$highlighting-macros$
$endif$
$if(verbatim-in-note)$
\usepackage{fancyvrb}
$endif$
$if(tables)$
\usepackage{longtable,booktabs}
$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}
$endif$
\ifxetex
\usepackage[setpagesize=false, % page size defined by xetex
unicode=false, % unicode breaks when used with xetex
xetex]{hyperref}
\else
\usepackage[unicode=true]{hyperref}
\fi
\hypersetup{breaklinks=true,
bookmarks=true,
pdfauthor={$author-meta$},
pdftitle={$title-meta$},
colorlinks=true,
citecolor=$if(citecolor)$$citecolor$$else$blue$endif$,
urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$,
linkcolor=$if(linkcolor)$$linkcolor$$else$magenta$endif$,
pdfborder={0 0 0}}
\urlstyle{same} % don't use monospace font for urls
$if(links-as-notes)$
% Make links footnotes instead of hotlinks:
\renewcommand{\href}[2]{#2\footnote{\url{#1}}}
$endif$
$if(strikeout)$
\usepackage[normalem]{ulem}
% avoid problems with \sout in headers with hyperref:
\pdfstringdefDisableCommands{\renewcommand{\sout}{}}
$endif$
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
\setlength{\emergencystretch}{3em} % prevent overfull lines
$if(numbersections)$
\setcounter{secnumdepth}{5}
$else$
\setcounter{secnumdepth}{0}
$endif$
$if(verbatim-in-note)$
\VerbatimFootnotes % allows verbatim text in footnotes
$endif$
$if(lang)$
\ifxetex
\usepackage{polyglossia}
\setmainlanguage{$mainlang$}
\else
\usepackage[$lang$]{babel}
\fi
$endif$
$if(title)$
\title{$title$}
$endif$
$if(subtitle)$
\subtitle{$subtitle$}
$endif$
$if(author)$
\author{$for(author)$$author$$sep$ \and $endfor$}
$endif$
$if(date)$
\date{$date$}
$endif$
$for(header-includes)$
$header-includes$
$endfor$
\newkomavar{opening}
\newkomavar{closing}
$for(letteroption)$
\LoadLetterOption{$letteroption$}
$endfor$
$if(addresseeimage)$\setkomavar{addresseeimage}{$addresseeimage$}$endif$
$if(backaddress)$\setkomavar{backaddress}{$backaddress$}\KOMAoptions{backaddress=true}$endif$
$if(customer)$\setkomavar{customer}{$customer$}$endif$
$if(date)$\setkomavar{date}{$date$}$endif$
$if(fromaddress)$\setkomavar{fromaddress}{$fromaddress$}$endif$
$if(frombank)$\setkomavar{frombank}{$frombank$}$endif$
$if(fromemail)$\setkomavar{fromemail}{$fromemail$}\KOMAoptions{fromemail=true}$else$\KOMAoptions{fromemail=false}$endif$
$if(fromfax)$\setkomavar{fromfax}{$fromfax$}\KOMAoptions{fromfax=true}$else$\KOMAoptions{fromfax=false}$endif$
$if(fromlogo)$\setkomavar{fromlogo}{$fromlogo$}\KOMAoptions{fromlogo=true}$else$\KOMAoptions{fromlogo=false}$endif$
$if(frommobilephone)$\setkomavar{frommobilephone}{$frommobilephone$}\KOMAoptions{frommobilephone=true}$else$\KOMAoptions{frommobilephone=false}$endif$
$if(fromname)$\setkomavar{fromname}{$fromname$}$endif$
$if(fromphone)$\setkomavar{fromphone}{$fromphone$}\KOMAoptions{fromphone=true}$else$\KOMAoptions{fromphone=false}$endif$
$if(fromurl)$\setkomavar{fromurl}{$fromurl$}\KOMAoptions{fromurl=true}$else$\KOMAoptions{fromurl=false}$endif$
$if(fromzipcode)$\setkomavar{fromzipcode}{$fromzipcode$}$endif$
$if(invoice)$\setkomavar{invoice}{$invoice$}$endif$
$if(location)$\setkomavar{location}{$location$}$endif$
$if(myref)$\setkomavar{myref}{$myref$}$endif$
$if(myrefname)$\setkomavar*{myref}{$myrefname$}$endif$
$if(place)$\setkomavar{place}{$place$}$endif$
$if(PPdatamatrix)$\setkomavar{PPdatamatrix}{$PPdatamatrix$}$endif$
$if(PPcode)$\setkomavar{PPcode}{$PPcode$}$endif$
$if(signature)$\setkomavar{signature}{$signature$}$endif$
$if(specialmail)$\setkomavar{specialmail}{$specialmail$}$endif$
$if(subject)$\setkomavar{subject}{$subject$}$endif$
$if(title)$\setkomavar{title}{$title$}$endif$
$if(toaddress)$\setkomavar{toaddress}{$toaddress$}\KOMAoptions{toaddress=true}$endif$
$if(toname)$\setkomavar{toname}{$toname$}\KOMAoptions{toname=true}$endif$
$if(yourmail)$\setkomavar{yourmail}{$yourmail$}$endif$
$if(yourref)$\setkomavar{yourref}{$yourref$}$endif$
$if(opening)$\setkomavar{opening}{$opening$}$endif$
$if(closing)$\setkomavar{closing}{$closing$}$endif$
\KOMAoptions{
fromalign=right
}
\begin{document}
\begin{letter}{%
$to$
}
$for(include-before)$
$include-before$
$endfor$
\opening{\usekomavar{opening}}
$body$
\closing{\usekomavar{closing}}
$if(ps)$\ps{$ps$}$endif$
$if(encl)$\encl{$encl$}$endif$
$for(include-after)$
$include-after$
$endfor$
\end{letter}
\end{document}
PK ! @&b b pandoc_styles/constants.pyfrom os.path import expanduser, join
# Generel constants
MODULE_NAME = "pandoc_styles"
CONFIG_DIR = join(expanduser("~"), MODULE_NAME)
STYLE_FILE = join(CONFIG_DIR, "styles.yaml")
PANDOC_CMD = "pandoc"
FMT = "fmt"
TO_FMT = "to_fmt"
OUTPUT_FILE = "output_file"
CFG_TEMP_FILE = "cfg.yaml"
ALL_STYLE = "All"
USER_DIR_PREFIX = "~/"
PATH_MISC = "misc"
PATH_TEMP = "temp"
PATH_SASS = "sass"
PATH_CSS = "css"
# Metadata fields constants
MD_METADATA = "metadata"
MD_CMD_LINE = "command-line"
MD_DESTINATION = "destination"
MD_OUTPUT_NAME = "output-name"
MD_FORMATS = "formats"
MD_FROM_FORMAT = "from-format"
MD_STYLE_FILE = "style-file"
MD_STYLE = "style"
MD_INHERITS = "inherits"
MD_STYLE_DEF = "style-definition"
MD_CURRENT_FILES = "current-files"
MD_TEMP_DIR = "temp-dir"
MD_CFG_DIR = "config-dir"
MD_PANDOC_STYLES_MD = "pandoc_styles_"
MD_PREFLIGHT = "preflight"
MD_POSTFLIGHT = "postflight"
MD_SASS = "sass"
MD_SASS_OUTPUT_PATH = "output-path"
MD_SASS_FILES = "files"
MD_SASS_VARS = "variables"
MD_SASS_APPEND = "append"
MD_ADD_TO_TEMPLATE = "add-to-template"
MD_REPL_IN_TEMPLATE = "replace-in-template"
MD_REPL_PATTERN = "pattern"
MD_REPL_TEXT = "replacement-text"
MD_REPL_ADD = "add"
MD_REPL_COUNT = "count"
MD_TEMPLATE = "template"
MD_REPL_IN_OUTPUT = "replace-in-output"
# Configuartion constants
CFG_FILE = "config.yaml"
CFG_PANDOC_PATH = "pandoc-path"
CFG_PYTHON_PATH = "python-path"
# Some formats:
ALL_FMTS = "all"
HTML = "html"
PDF = "pdf"
LATEX = "latex"
EPUB = "epub"
CSS = "css"
# Filter
FIL_OTHER = "other"
FIL_ALL = "all_formats"
FIL_CHECK = "check"
PK ! QmS# # pandoc_styles/filter.pyimport yaml
import panflute as pf
from panflute import ( # pylint: disable=W0611
Null, HorizontalRule, Space, SoftBreak, LineBreak, Str,
Code, BlockQuote, Note, Div, Plain, Para, Emph, Strong, Strikeout,
Superscript, Subscript, SmallCaps, Span, RawBlock, RawInline, Math,
CodeBlock, Link, Image, BulletList, OrderedList, DefinitionList,
LineBlock, Header, Quoted, Cite, Table, ListContainer,
convert_text, Element, run_filter)
from .constants import (HTML, PDF, LATEX, EPUB, MD_PANDOC_STYLES_MD,
FIL_OTHER, FIL_ALL, FIL_CHECK)
from .utils import file_read, file_write
class PandocStylesFilter():
'''
Base class for filters. Defines methods to help writing filters and to
run them.
'''
def __init__(self, func, filter_type=None, tags=None):
self._add_method(func, "func")
self.filter_type = filter_type
self.tags = tags
def run(self):
run_filter(self._pandoc_filter)
def _pandoc_filter(self, elem, doc):
self._init_filter(elem, doc)
if not self.check():
return
self.new_text = self.func() # pylint: disable=E1128
return self._return_filter()
def _init_filter(self, elem, doc):
self.elem = elem
self.doc = doc
self.cfg = dict()
self._get_format()
self.classes = elem.classes if hasattr(elem, "classes") else None
self.attributes = elem.attributes if hasattr(elem, "attributes") else None
self.text = elem.text if hasattr(elem, "text") else None
self.content = elem.content if hasattr(elem, "content") else None
def _return_filter(self):
if self.new_text is None:
return
elif self.new_text == [] or is_pandoc_element(self.new_text):
return self.new_text
return convert_text(self.new_text)
def _get_format(self):
self.fmt = self.doc.format
self.real_fmt = self.fmt
if self.fmt == PDF:
self.fmt = LATEX
elif self.fmt == EPUB:
self.fmt = HTML
def check(self):
return (not self.filter_type or isinstance(self.elem, self.filter_type)) \
and (not self.tags or any(x in self.tags for x in self.classes))
def func(self):
return
def _add_method(self, var, name):
if var is not None:
if callable(var):
setattr(self, name, var.__get__(self))
else:
raise TypeError("Only strings and functions are allowed in filter generation!")
def get_metadata(self, key, default=None):
'''Gets metadata'''
return self.doc.get_metadata(key, default)
def get_pandoc_styles_metadata(self):
'''Return the pandoc_styles cfg as a dictionary'''
try:
self.cfg = yaml.safe_load(file_read(self.get_metadata(MD_PANDOC_STYLES_MD)))
except FileNotFoundError:
self.cfg = {}
return self.cfg
def save_pandoc_styles_metadata(self):
'''Save the given cfg in the cfg-file'''
file_write(self.get_metadata(MD_PANDOC_STYLES_MD), yaml.dump(self.cfg))
def stringify(self, elem=None):
'''Stringify an element'''
if elem is None:
elem = self.elem
return stringify(elem)
def raw_block(self, *args):
'''Return a RawBlock pandoc element in self.fmt. Accepts strings, tuples
and lists as arguments.
'''
return raw(self.fmt, *args)
def raw_inline(self, *args):
'''Return a RawInline pandoc element in self.fmt. Accepts strings, tuples
and lists as arguments.
'''
return raw(self.fmt, *args, element_type=RawInline)
def run_pandoc_styles_filter(func, filter_type=None, tags=None):
"""
Run a filter with the given func. The function is now a method to a filter object
and you can access its contents through self.
"""
PandocStylesFilter(func, filter_type, tags).run()
class TransformFilter(PandocStylesFilter):
'''
Base class for filters. Defines methods to help writing filters and to
run them.
'''
# pylint: disable=W0231
def __init__(self, tags=None, latex=None, html=None, other=None,
all_formats=None, filter_type=None, check=None):
self.tags = tags or []
self.filter_type = filter_type if filter_type is not None else CodeBlock
self._add_method(latex, LATEX)
self._add_method(html, HTML)
self._add_method(other, FIL_OTHER)
self._add_method(all_formats, FIL_ALL)
self._add_method(check, FIL_CHECK)
def _pandoc_filter(self, elem, doc):
self._init_filter(elem, doc)
if not self.check():
return
self.all_formats()
self._call_filter()
return self._return_filter()
# pylint: disable=E1128
def _call_filter(self):
if self.fmt == LATEX:
self.new_text = self.latex()
elif self.fmt == HTML:
self.new_text = self.html()
else:
self.new_text = self.other()
def _return_filter(self):
if self.new_text is None:
return
elif self.new_text == [] or is_pandoc_element(self.new_text):
return self.new_text
return self.raw_block(self.new_text)
def all_formats(self):
return
def latex(self):
return None
def html(self):
return None
def other(self):
return None
def _add_method(self, var, name):
if var is not None:
if isinstance(var, str):
setattr(self, name, lambda: var.format(text=self.convert_text()))
elif callable(var):
setattr(self, name, var.__get__(self))
else:
raise TypeError("Only strings and functions are allowed in filter generation!")
def convert_text(self, text=None, input_fmt='markdown', extra_args=None):
'''Converts text in input_fmt to self.fmt'''
if text is None:
text = self.text
return convert_text(text, input_fmt, self.fmt, False, extra_args)
def run_transform_filter(tags=None, latex=None, html=None, other=None,
all_formats=None, filter_type=None, check=None):
'''
Creates and runs a pandoc filter.
tags: The default check method checks, if these tags are in the classes of
the element the filter searches for. If it is [], check only checks for
the element type
latex, html, other: Accepts either a function or a string.
> Function: These functions are registered as a method and are executed,
if the format of the output matches the name. These methods have to
either return a string/list of strings or an pandoc element/list of elements.
> String: The string is returned as the output. The string can contain
the formating {text], which gets replaced by the converted text
of the element.
all_formats: This method is executed before the format specific methods
and is used to execute shared code.
filter_type: If the filter searches for an element other than a CodeBlock
check: Replace the default check method with your own.
'''
pandoc_filter = TransformFilter(tags, latex, html, other, all_formats, filter_type,
check)
pandoc_filter.run()
def is_pandoc_element(ele):
if isinstance(ele, Element):
return True
elif isinstance(ele, (list, tuple)):
return is_pandoc_element(ele[0])
return False
def raw(fmt, *args, element_type=RawBlock):
'''Return a Raw pandoc element in the given format. Accepts strings,
lists and tuples as arguments.
'''
text = []
for s in args:
if isinstance(s, str):
text.append(s)
elif isinstance(s, list):
text.extend(s)
elif isinstance(s, tuple):
text.extend(list(s))
else:
raise TypeError('Only strings and lists/tuples of strings are allowed in raw')
if fmt not in ['tex', 'latex', 'html', 'context']:
return convert_text(''.join(text))
return element_type(''.join(text), fmt)
def stringify(elem, newlines=True):
"""
Return the raw text version of an element (and its children elements).
Example:
>>> e1 = Emph(Str('Hello'), Space, Str('world!'))
>>> e2 = Strong(Str('Bye!'))
>>> para = Para(e1, Space, e2)
>>> stringify(para)
'Hello world! Bye!\n\n'
:param newlines: add a new line after a paragraph (default True)
"""
if isinstance(elem, ListContainer):
elem = Para(*elem)
return pf.stringify(elem, newlines)
def strip_html_tag(text, tag="p"):
text = text.replace(f"<{tag}>", "")
return text.replace(f"{tag}>", "")
PK ! w w pandoc_styles/flight_scripts.pyfrom argparse import ArgumentParser
import yaml
from .constants import CFG_TEMP_FILE, MD_TEMP_DIR, MD_CURRENT_FILES, FMT, OUTPUT_FILE
from .utils import file_read, file_write
class FlightScript:
def __init__(self, func, flight_type):
setattr(self, "fligh_script", func.__get__(self))
parser = ArgumentParser(description="")
parser.add_argument('--cfg', nargs='?', default="",
help='The cfg from pandoc_styles')
args = parser.parse_args()
self.cfg = yaml.safe_load(file_read(args.cfg))
self.fmt = self.cfg[FMT]
if flight_type == "preflight":
self.files = self.cfg[MD_CURRENT_FILES]
else:
self.file = self.cfg[OUTPUT_FILE]
def fligh_script(self):
pass
def save_cfg(self):
file_write(CFG_TEMP_FILE, yaml.dump(self.cfg), self.cfg.get(MD_TEMP_DIR))
def run_preflight_script(func):
script = FlightScript(func, "preflight")
script.fligh_script()
def run_postflight_script(func):
script = FlightScript(func, "postflight")
script.fligh_script()
PK ! ~# pandoc_styles/format_mappings.pyFORMAT_TO_EXTENSION = {
"asciidoc": "adoc",
"adoc": "adoc",
"beamer": "beamer",
"commonmark": "md",
"context": "ctx",
"ctx": "ctx",
"docbook": "dbk",
"docbook4": "dbk",
"docbook5": "dbk",
"dbk": "dbk",
"docx": "docx",
"dzslides": "html",
"epub": "epub",
"epub2": "epub",
"epub3": "epub",
"fb2": "fb2",
"gfm": "md",
"haddock": "html",
"html": "html",
"html4": "html",
"html5": "html",
"icml": "icml",
"jats": "jats",
"json": "json",
"latex": "latex",
"man": "man",
"markdown": "md",
"markdown_github": "md",
"markdown_mmd": "md",
"markdown_phpextra": "md",
"markdown_strict": "md",
"markdown+lhs": "lhs",
"lhs": "lhs",
"md": "md",
"mediawiki": "html",
"ms": "ms",
"muse": "muse",
"odt": "odt",
"opendocument": "odt",
"opml": "opml",
"org": "org",
"pdf": "pdf",
"plain": "txt",
"pptx": "pptx",
"revealjs": "html",
"rst": "rst",
"rtf": "rtf",
"s5": "s5",
"slideous": "html",
"slidy": "html",
"tei": "tei",
"texinfo": "texi",
"textile": "tex",
"zimwiki": "html",
}
PK ! *sK K pandoc_styles/main.pyimport logging
import re
import subprocess
import sys
from argparse import ArgumentParser
from copy import deepcopy
from os import getcwd, listdir, mkdir
from os.path import (basename, dirname, isdir, join, normpath, relpath)
from shutil import copy, copytree
from tempfile import TemporaryDirectory
from pkg_resources import resource_filename
import sass
import yaml
from .constants import * # pylint: disable=W0401, W0614
from .format_mappings import FORMAT_TO_EXTENSION
from .utils import (change_dir, expand_directories, file_read, file_write,
has_extension, make_list, run_process)
class PandocStyles:
"""Handles the conversion with styles"""
def __init__(self, files, formats=None, from_format="", use_styles=None,
add_styles=None, metadata="", target="", output_name="",
style_file=None, quiet=False):
self.metadata = metadata
self.files = files
self.pandoc_metadata = self.get_pandoc_metadata()
self.quiet = quiet
self.from_format = from_format or self.pandoc_metadata.get(MD_FROM_FORMAT)
self.use_styles = use_styles or make_list(self.pandoc_metadata.get(MD_STYLE, []))
self.use_styles.extend(add_styles or [])
style_file = style_file or \
expand_directories(self.pandoc_metadata.get(MD_STYLE_FILE)) or \
STYLE_FILE
self.styles = yaml.load(file_read(style_file))
self.target = target or self.pandoc_metadata.get(MD_DESTINATION, "")
self.output_name = output_name or self.pandoc_metadata.get(MD_OUTPUT_NAME) or \
f'{files[0].rpartition(".")[0]}'
self.formats = formats or make_list(self.pandoc_metadata.get(MD_FORMATS, [])) or \
[HTML, PDF]
self.actual_temp_dir = TemporaryDirectory()
self.temp_dir = self.actual_temp_dir.name
self.python_path = ""
self.do_user_config()
def run(self):
"""Convert to all given formats"""
if self.target and not isdir(self.target):
mkdir(self.target)
for fmt in self.formats:
if self.make_format(fmt):
logging.info(f"Build {fmt}")
else:
logging.error(f"Failed to build {fmt}!")
def get_output(self, fmt):
"""
Converts to the given format and returns the output.
"""
self.quiet = True
self.target = self.temp_dir
self.make_format(fmt)
return file_read(self.cfg[OUTPUT_FILE])
def print_output(self, fmt):
"""
Converts to the given format and prints the output.
"""
print(self.get_output(fmt))
def make_format(self, fmt):
"""
Converts to the given format.
All attributes defined here change with each format
"""
self.cfg = self.get_cfg(fmt)
self.preflight()
self.process_sass()
self.add_to_template()
self.replace_in_template()
pandoc_args = self.get_pandoc_args()
logging.debug(f"Command-line args: {pandoc_args}")
success = run_process(PANDOC_CMD, pandoc_args, self.quiet)
if success:
self.replace_in_output()
self.postflight()
return success
def get_pandoc_metadata(self):
"""Get the metadata yaml block in the first source file or given metadata file"""
md = file_read(self.metadata or self.files[0])
if not self.metadata:
md = re.match(r'.?-{3}(.*?)(\n\.{3}\n|\n-{3}\n)', md, flags=re.DOTALL)
md = md.group(1) if md else False
return yaml.safe_load(md) if md else {}
def do_user_config(self):
"""Read the config file and set the options"""
try:
config = yaml.safe_load(file_read(CFG_FILE, CONFIG_DIR))
except FileNotFoundError:
logging.warning("No configuration file found! Please initialize "\
"pandoc_styles with: pandoc_styles --init")
return
if config.get(CFG_PANDOC_PATH):
sys.path.append(normpath(dirname(config[CFG_PANDOC_PATH])))
if config.get(CFG_PYTHON_PATH):
self.python_path = normpath(config[CFG_PYTHON_PATH])
def get_cfg(self, fmt):
"""Get the style configuration for the current format"""
cfg = dict()
if self.use_styles:
start_style = self.styles.get(ALL_STYLE, {})
start_style[MD_INHERITS] = self.use_styles
cfg = self.get_styles(start_style, fmt)
# update fields in the cfg with fields in the document metadata
for key, val in self.pandoc_metadata.items():
if key in cfg.get(MD_METADATA, {}):
cfg_ = cfg[MD_METADATA]
elif key in cfg.get(MD_CMD_LINE, {}):
cfg_ = cfg[MD_CMD_LINE]
else:
cfg_ = cfg
self.update_dict(cfg_, {key: val})
if MD_STYLE_DEF in self.pandoc_metadata:
self.update_dict(cfg,
self.style_to_cfg(self.pandoc_metadata[MD_STYLE_DEF], fmt))
# add all needed infos to cfg
cfg[MD_CURRENT_FILES] = self.files.copy()
cfg[OUTPUT_FILE] = f"{self.output_name}.{FORMAT_TO_EXTENSION.get(fmt, fmt)}"
if self.target:
cfg[OUTPUT_FILE] = join(self.target, cfg[OUTPUT_FILE])
cfg[FMT] = fmt
cfg[TO_FMT] = LATEX if fmt == PDF else fmt
cfg[MD_TEMP_DIR] = self.temp_dir
cfg[MD_CFG_DIR] = CONFIG_DIR
return cfg
def get_styles(self, style, fmt):
"""
Gets the data for all inherited styles
"""
if not style.get(MD_INHERITS):
return self.style_to_cfg(style, fmt)
cfg = dict()
for extra_style in make_list(style[MD_INHERITS]):
extra_style = self.get_styles(self.styles[extra_style], fmt)
self.update_dict(cfg, extra_style)
self.update_dict(cfg, self.style_to_cfg(style, fmt))
return cfg
def get_pandoc_args(self):
"""Build the command line for pandoc out of the given configuration"""
pandoc_args = [f'-t {self.cfg[TO_FMT]} -o "{self.cfg[OUTPUT_FILE]}"']
if self.from_format:
pandoc_args.append(f'--from {self.from_format}')
# add pandoc_styles cfg, so that filters can use it
pandoc_args.append(f'-M {MD_PANDOC_STYLES_MD}="{self.make_cfg_file()}"')
complex_data = {}
for group, prefix in [(MD_CMD_LINE, "--"), (MD_METADATA, "-V ")]:
if group in self.cfg:
for key, value in self.cfg[group].items():
for item in make_list(value):
if not item:
continue
elif item is True:
pandoc_args.append(f'{prefix}{key}')
elif isinstance(item, dict):
complex_data[key] = value
break
else:
item = expand_directories(item, key)
pandoc_args.append(f'{prefix}{key}="{item}"')
for ffile in self.cfg[MD_CURRENT_FILES]:
pandoc_args.append(f'"{ffile}"')
if self.metadata:
pandoc_args.append(f'"{self.metadata}"')
if complex_data:
complex_data = f'---\n{yaml.dump(complex_data)}\n...\n'
complex_data = file_write("cur_metadata.yaml", complex_data, self.temp_dir)
pandoc_args.append(f'"{complex_data}"')
return " ".join(pandoc_args)
def preflight(self):
"""Run all preflight scripts given in the style definition"""
if MD_PREFLIGHT not in self.cfg:
return
self.cfg[MD_CURRENT_FILES] = [copy(f, self.temp_dir)
for f in self.cfg[MD_CURRENT_FILES]]
for script in make_list(self.cfg[MD_PREFLIGHT]):
if self.run_pandoc_styles_script(script, MD_PREFLIGHT):
continue
script = script.replace("", "{}")
script = script.format(" ".join(self.cfg[MD_CURRENT_FILES]))
run_process(script)
def postflight(self):
"""Run all postflight scripts given in the style definition"""
if MD_POSTFLIGHT not in self.cfg:
return
for script in make_list(self.cfg[MD_POSTFLIGHT]):
if self.run_pandoc_styles_script(script, MD_POSTFLIGHT):
continue
script = script.replace("", "{}").format(self.cfg[OUTPUT_FILE])
run_process(script)
def run_pandoc_styles_script(self, script, flight_type):
if len(script.split(" ")) > 1 or not has_extension(script, "py"):
return False
cfg = self.make_cfg_file()
script = expand_directories(script, flight_type)
if self.python_path:
script = f'{self.python_path} "{script}" '
run_process(script, f'--cfg "{cfg}"')
self.read_cfg_file()
return True
def process_sass(self):
"""Build the css out of the sass informations given in the style definition"""
if MD_SASS not in self.cfg:
return
css = [f'${var}: {str(val).lower() if isinstance(val, bool) else str(val)};'
for var, val in self.cfg[MD_SASS].get(MD_SASS_VARS, {}).items()]
sass_files = make_list(self.cfg[MD_SASS][MD_SASS_FILES])
css_name = f"{basename(sass_files[0]).rpartition('.')[0]}.{CSS}"
css.extend([file_read(expand_directories(f, MD_SASS)) for f in sass_files])
css.extend(make_list(self.cfg[MD_SASS].get(MD_SASS_APPEND, [])))
css = "\n".join(css)
css = sass.compile(string=css, output_style='expanded',
include_paths=[join(CONFIG_DIR, PATH_SASS)])
css_file_path = self.cfg[MD_SASS].get(MD_SASS_OUTPUT_PATH)
temp = css_file_path == PATH_TEMP
if temp:
css_file_path = self.temp_dir
elif css_file_path == USER_DIR_PREFIX:
css_file_path = join(CONFIG_DIR, PATH_CSS)
elif css_file_path:
css_file_path = join(self.target, css_file_path)
else:
css_file_path = self.target if self.target else "."
if not isdir(css_file_path):
mkdir(css_file_path)
css_file_path = file_write(css_name, css, css_file_path)
if not temp:
try:
css_file_path = relpath(css_file_path, self.target).replace("\\", "/")
except ValueError:
pass
self.update_dict(self.cfg, {MD_CMD_LINE: {CSS: [css_file_path]}})
def add_to_template(self):
"""Add code to the template given in the style definition"""
if MD_ADD_TO_TEMPLATE not in self.cfg:
return
self.modify_template(
r'(\$for\(header-includes\)\$\n\$header-includes\$\n\$endfor\$)',
self.cfg[MD_ADD_TO_TEMPLATE], True)
def replace_in_template(self):
"""Replace code in the template with other code given in the style definition"""
if MD_REPL_IN_TEMPLATE not in self.cfg:
return
for item in make_list(self.cfg[MD_REPL_IN_TEMPLATE]):
self.modify_template(item[MD_REPL_PATTERN], item.get(MD_REPL_TEXT, ""),
item.get(MD_REPL_ADD, False), item.get(MD_REPL_COUNT, 0))
def modify_template(self, pattern, repl, add=False, count=0):
"""Helper method to do the actual replacement"""
try:
template = file_read(self.cfg[MD_CMD_LINE][MD_TEMPLATE])
except (KeyError, FileNotFoundError):
try:
template = subprocess.run(f'{PANDOC_CMD} -D {self.cfg[TO_FMT]}',
stdout=subprocess.PIPE, encoding="utf-8",
check=True)
template = template.stdout
except (subprocess.CalledProcessError, FileNotFoundError):
return
original_template = template
template = self.replace_in_text(pattern, repl, template, add, count)
if original_template != template:
template = file_write("new.template", template, self.temp_dir)
self.update_dict(self.cfg, {MD_CMD_LINE: {MD_TEMPLATE: template}})
def replace_in_output(self):
"""Replace text in the output with text given in the style definition"""
if MD_REPL_IN_OUTPUT not in self.cfg:
return
original_text = text = file_read(self.cfg[OUTPUT_FILE])
for item in self.cfg[MD_REPL_IN_OUTPUT]:
text = self.replace_in_text(item[MD_REPL_PATTERN], item.get(MD_REPL_TEXT, ""),
text, item.get(MD_REPL_ADD), item.get(MD_REPL_COUNT, 0))
if original_text != text:
file_write(self.cfg[OUTPUT_FILE], text)
def replace_in_text(self, pattern, repl, text, add=False, count=0):
"""Helper method to replace text"""
repl = "\n".join(item for item in make_list(repl))
repl = repl.replace("\\", '\\\\')
repl = fr"{repl}\n\1" if add else repl
text = re.sub(pattern, repl, text, count, re.DOTALL)
return text
def style_to_cfg(self, style, fmt):
"""Transform a style to the configuration for the current format"""
cfg = dict()
for group in [ALL_FMTS, fmt]:
if group in style:
self.update_dict(cfg, style[group])
return cfg
def update_dict(self, dictionary, new):
"""
Merge dictionary with new. Single keys are replaces, but nested dictionaries
and list are appended
"""
# we deepcopy new, so that it stays independent from the source
new = deepcopy(new)
for key, value in new.items():
if not dictionary.get(key):
dictionary[key] = value
elif isinstance(value, dict):
self.update_dict(dictionary[key], value)
elif isinstance(value, list) and isinstance(dictionary[key], list):
dictionary[key].extend(value)
else:
dictionary[key] = value
def make_cfg_file(self):
"""
Dump the configuration for a format into a file. This way filter and flight
scripts can read the configuration.
"""
return file_write(CFG_TEMP_FILE, yaml.dump(self.cfg), self.temp_dir)
def read_cfg_file(self):
"""Read the cfg file"""
self.cfg = yaml.safe_load(file_read(CFG_TEMP_FILE, self.temp_dir))
def main():
"""Parse the command line arguments and run PandocStyles with the given args"""
parser = ArgumentParser(description="Runs pandoc with options defined in styles")
parser.add_argument('files', nargs='*',
help='The source files to be converted')
parser.add_argument('-f', '--folder', nargs='?', const=True,
help='All files in the folder are converted together.')
parser.add_argument('--extensions', nargs='+', default=["md", "markdown"],
metavar="EXT",
help='If the folder option is used, only convert files '
'with the given extensions.')
parser.add_argument('-t', '--to', nargs='+', default=[], metavar="FMT",
help='The formats that should be produced.')
parser.add_argument('--from-format', metavar="FMT",
help='The format of the source files.')
parser.add_argument('-d', '--destination', metavar="FOLDER",
help='The target folder')
parser.add_argument('-o', '--output-name',
help='The name of the output file without an extension. '
'Defaults to the name of the first input file.')
parser.add_argument('-s', '--styles', nargs='+', default=[], metavar="STYLE",
help='Styles to use for the conversion. Replaces styles given '
'in the file.')
parser.add_argument('-a', '--add-styles', nargs='+', default=[], metavar="STYLE",
help='Styles to use for the conversion. Add the styles given '
'to the styles given in the file.')
parser.add_argument('--style-file',
help='Path to the style file that should be used. '
'Defaults to the style file in the configuration folder.')
parser.add_argument('-m', '--metadata',
help='Path to the metadata file that should be used.')
parser.add_argument('-p', '--print', action='store_true',
help='Print the output to stdout. Accepts only one format.')
parser.add_argument('-w', '--working-dir', default=getcwd(), type=str,
metavar="FOLDER",
help='The folder of the source files, for use in macros etc.')
parser.add_argument('-q', '--quiet', action='store_true',
help='Run quiet. Sets logging to ERROR and shows no warnings '
'from pandoc.')
parser.add_argument('--init', action='store_true',
help='Create the user configuration folder.')
parser.add_argument('--log', default="INFO",
choices=["INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL"],
help='The logging level. '
'Defaults to "INFO"')
args = parser.parse_args()
# logging
logging.basicConfig(format='%(levelname)s: %(message)s',
level=getattr(logging, "ERROR" if args.quiet or args.print else
args.log))
# initialize config directory
if args.init:
if not isdir(CONFIG_DIR):
copytree(resource_filename(MODULE_NAME, 'config_dir'), CONFIG_DIR)
logging.info(f"Created configuration directory: {CONFIG_DIR}!")
return
if args.folder:
if args.folder is True:
args.folder = getcwd()
args.files = [f for f in listdir(args.folder)
if has_extension(f, args.extensions)]
args.files.sort()
if not args.files:
parser.print_help()
return
with change_dir(args.working_dir):
ps = PandocStyles(args.files, args.to, args.from_format, args.styles,
args.add_styles, args.metadata, args.destination,
args.output_name, args.style_file, args.quiet)
if args.print:
ps.print_output(args.to[0])
return
ps.run()
if __name__ == '__main__':
main()
PK ! ['fF F pandoc_styles/utils.py'''Some utility functions'''
import logging
import subprocess
import shlex
from os import chdir, getcwd
from os.path import join, isfile, normpath
from contextlib import contextmanager
from .constants import CONFIG_DIR, USER_DIR_PREFIX, PATH_MISC
def file_read(file_name, *path, encoding="utf-8"):
'''Just a wrapper, since nearly always only read or write are used in this script'''
if path:
path = path + (file_name,)
file_name = join(path[0], *path[1:])
with open(file_name, encoding=encoding) as ffile:
return ffile.read()
def file_write(file_name, string, *path, mode="w", encoding="utf-8"):
'''Just a wrapper, since nearly always only read or write are used in this script'''
if path:
path = path + (file_name,)
file_name = join(path[0], *path[1:])
with open(file_name, mode, encoding=encoding) as ffile:
ffile.write(string)
return file_name
def run_process(name, args="", quiet=False):
"""Run a process with the given args and return True if successfull """
try:
if quiet:
subprocess.run(shlex.split(f"{name} {args}"),
check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return True
subprocess.run(shlex.split(f"{name} {args}"), check=True)
return True
except subprocess.CalledProcessError:
logging.error(f"{name} failed!")
logging.debug(f"{name} command-line:\n{name} {args}!")
return False
except FileNotFoundError:
logging.error(f'{name} not found!')
return False
def has_extension(ffile, extensions):
'''Check if ffile has an extension given in extensions. Extensions can be
a string or a list of strings.'''
if ffile.rpartition('.')[-1] in make_list(extensions):
return True
return False
def make_list(item):
"""Make a list with item as its member, if item isn't a list already"""
if not isinstance(item, list):
return [item]
return item
@contextmanager
def change_dir(new_dir):
"""Changes to the given directory, returns to the current one after"""
current_dir = getcwd()
chdir(new_dir)
yield
chdir(current_dir)
def expand_directories(item, key=""):
"""
Look if item is a file in the configuration directory and return the path if
it is. Searches first for the given path, then looks into a subfolder given by
key and finally in the "misc" subfolder. If no file is found, just return item.
"""
if isinstance(item, str) and USER_DIR_PREFIX in item:
for folder in ["", key, PATH_MISC]:
test_file = normpath(item.replace("~", join(CONFIG_DIR, folder)))
if isfile(test_file):
return test_file.replace("\\", "/")
return item
PK !H);- 9 . pandoc_styles-0.8.1.dist-info/entry_points.txtN+I/N.,()*HKO/.I-E&fY.. PK ! s½-A A ( pandoc_styles-0.8.1.dist-info/LICENSE.mdMIT License
Copyright (c) 2018 dickloraine
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.
PK !H ST T # pandoc_styles-0.8.1.dist-info/WHEEL
1
0нR.\I$ơ7.ZON
`h6oi14m,b4>4ɛpK>X;baP>PK !H, 0 &