# Editorial Workflows

PDF (LaTeX)

public workflow

This workflow contains at least one Python script. Only use it if you trust the person who shared this with you, and if you know exactly what it does.

This is a workflow for Editorial, a Markdown and plain text editor for iOS. To download it, you need to view this page on a device that has the app installed.

Description: The best way I've found to convert Markdown to PDF. This converts the Markdown file being edited to LaTeX and puts it on the clipboard. Then switch to the iOS app Texpad, paste the LaTeX into an empty .tex file and tap typeset to convert to PDF.

The workflow supports basic Markdown syntax except links, plus you can write LaTeX commands in the Markdown to do tables, equations and anything else. You have precise control over page design. The PDFs look great, because LaTeX knows about all the bits (letters, words ... pages) and optimises spacings. It all happens on the iPad, including images.

Shared by: Peter Hopcroft (peterh)

Jeremy Kidwell — 14 Oct 2014
I installed this workflow and gave it a spin, particularly since I like the idea of typesetting MD-->LaTeX-->PDF. There's only one limitation that I can see, and this is that there are a few features I'm using from MMD, i.e. footnotes in particular (https://github.com/fletcher/MultiMarkdown/wiki/MultiMarkdown-Syntax-Guide#footnotes) and the script simply doesn't parse them. Peter, do you have an alternative arrangement for formatting footnotes in your workflow, or do they simply not come up in the kind of writing you're doing? Thanks for sharing the workflow - it would be great to enhance with some MMD features if you have any ideas in this direction, happy to help.
anonymous — 16 Jan 2015
Texpad natively supports markdown formatting on an equal footing with Latex anyway, so you don't gain much by using editorial here.

Workflow Preview
Using this workflow ?
Source Code
#coding: utf-8
"""
PDF (LaTeX) - Peter Hopcroft, February 2014

The best way I've found to convert Markdown to PDF. This converts the Markdown file being edited to LaTeX and puts it on the clipboard. Then switch to the iOS app Texpad, paste the LaTeX into an empty .tex file and tap typeset to convert to PDF.

The workflow supports basic Markdown syntax except links, plus you can write LaTeX commands in the Markdown to do tables, equations and anything else. You have precise control over page design. The PDFs look great, because LaTeX knows about all the bits (letters, words ... pages) and optimises spacings. It all happens on the iPad, including images.

You'll need:
http://tobi.oetiker.ch/lshort/lshort.pdf
http://ctan.unsw.edu.au/macros/latex/contrib/memoir/memman.pdf
grit

MEMOIR: The LaTeX uses the Memoir class.

LaTeX COMMANDS IN MARKDOWN: The workflow converts Markdown to html, then to LaTeX. To write LaTeX commands in Markdown requires \ { and } characters, and you are supposed to backslash escape them in Markdown. But Python Markdown does not seem to need this. The workflow loads the Tabulary package for writing tables.

CONVERSION:
from		to
#				title: same as ##, but no number
##			numbered chapter heading: starts on new page unless at start of text
######	same as #####
---			\pfbreak
code span elements: | is the end delimiter for now
code block elements: \end{verbatim} is the end delimiter

ENCODING: The workflow encodes the LaTeX as utf-8 to send to Texpad. But you can only use the less-than-256 characters listed in LaTeX's T1 encoding, see:
http://www.tex.ac.uk/tex-archive/macros/latex/doc/encguide.pdf
For a character outside this, Texpad gives an 'package inputenc error'.

PICTURES: Before you run the workflow, import your picture files into Texpad (use +). They are imported as .png, about three times the size of .jpg. The workflow turns a Markdown image element into an equivalent LaTeX graphic element. My extensions:
- LaTeX requires a width. You can write a width in the alt text; if you don't the default is \textwidth.
- If you write a caption in the title text, the workflow puts the picture in a figure (floating) envoronment, with the caption under the picture.

For example:

![](picture.png) -> \includegraphics[width=\textwidth]{picture.png}

![100mm](picture.png) -> \includegraphics[width=100mm]{picture.png}

![100mm](picture.png 'Caption text here') ->

\begin{figure}[!hbtp]
\includegraphics[width=100mm]{picture.png}
\par{}Caption text here
\end{figure}

The .png in the image file name is optional. Texpad has a bug, and sometimes says it can't find the image file when it is there. Try again.

LIGATURES: Texpad's local typesetter has a bug with some fonts (with utopia): Some ligatures are typeset wrong, eg 'ff' appears as 'f '. To avoid this, the E dictionary in the python script can put a zero-width space between faulty ligature character pairs; see the example for 'ff'. If you find more faulty pairs, add them to the E dictionary.

BEWARE:
- Don't use \ or & in regular text, because LaTeX assumes they are parts of commands.
- Some LaTeX commands conflict with Markdown and won't work. Eg LaTeX speech marks are  ... ' and  ... '', but you can't use them because Markdown uses  to mark span code.
- I haven't tested all the valid combinations of Markdown syntax. Some will probably fail or look bad. For example, you can't nest block quotes.
- The faulty ligature pairs have the zero-width space inserted throughout the Markdown, including picture file names (rename if necessary) and LaTeX commands (I don't know if any are affected).

AND: I gleaned LaTeX from tex.stackoverflow. LaTeX can be sweatier than latex. The workflow has the sin of nonzero parskip nonzero and zero parindent. Texpad has a lot of rough edges.

"""

Convert markdown to LaTeX for Texpad ?
Source Code
#coding: utf-8

# PDF (LaTeX) - Peter Hopcroft, February 2014

import clipboard
import console
import editor
import markdown
import re
import os
import workflow

# constants -------------------------------------

# start of a LaTeX document, defines the page design- \\ is an escaped \
LSTART = """
\\documentclass[a4paper,12pt,openany,oneside]{memoir}

\\usepackage[T1]{fontenc}
\\usepackage[utf8]{inputenc}
\\usepackage{utopia}
%\\usepackage{palatino}	% this works
%\\raggedright
\\usepackage{graphicx}
\\usepackage{enumitem}
\\usepackage{tabulary}

%\\usepackage{microtype} % does not help with ligature bug
%\\DisableLigatures[f]{encoding=T1, family=*}

% my global lengths
\\newlength{\\myparskip}
\\setlength{\\myparskip}{1.0ex plus 0.2ex minus 0.2ex}
\\newlength{\\myindent}
\\setlength{\\myindent}{3ex}
\\setlength{\\myskipbig}{5ex plus 1.0ex minus 1.0ex}
\\setlength{\\myskipsmall}{1.5ex plus 0.3ex minus 0.3ex}

% page layout
\\pagestyle{plain}
\\setlrmarginsandblock{35mm}{35mm}{*}
\\setulmarginsandblock{25mm}{25mm}{*}
\\setlength{\\footskip}{8mm}
\\checkandfixthelayout

% paragraphs
\\setlength{\\parindent}{0pt}
\\abnormalparskip{\\myparskip}

\\setsecnumdepth{chapter} % number chapters but not lesser headings

% h1 - same as chapter heading but no number
\\newcommand{\\mytitle}[1]%
{{\\newpage\\vspace*{-1.2\\topskip}%
\\Large\\mdseries\\raggedright{#1}%
\\vspace{\\myskipbig}}} % is a group

\\chapterstyle{section}
\\renewcommand*{\\chapnumfont}{\\Large\\mdseries\\raggedright}
\\renewcommand*{\\afterchapternum}{\\hspace{1.0ex}} % space after number
\\renewcommand*{\\chaptitlefont}{\\Large\\mdseries\\raggedright}
\\setlength{\\afterchapskip}{\\myskipbig} % space after

\\setbeforesecskip{-\\myskipbig} % - for no hdr indent
\\setaftersecskip{\\myskipsmall}

\\setbeforesubsecskip{-\\myskipbig} % - for no hdr indent
\\setaftersubsecskip{\\myskipsmall}

% h5 & h6 subsubsection heading - runin
\\setbeforesubsubsecskip{-\\myskipbig} % - for no hdr indent

% lists, using enumitem
\\newenvironment{myul}%   % unordered list
{\\begin{itemize} [topsep=0pt, partopsep=0pt, itemsep=0pt, %
parsep=\\parskip, leftmargin=\\myindent, labelindent=1.0pt, %
labelsep=*, label={\\rule[0.2ex]{0.7ex}{0.7ex}}]}%
{\\end{itemize} \\vspace{0ex} }

\\newenvironment{myol}%   % ordered list
{\\begin{enumerate} [topsep=0pt, partopsep=0pt, itemsep=0pt, %
parsep=\\parskip, leftmargin=\\myindent, labelindent=0.5pt, %
labelsep=*, label=\\arabic*]}%
{\\end{enumerate} \\vspace{0ex} }

% miscellaneous
\\newenvironment{myblockquote}%
{\\leftskip=\\myindent}%
{}

% verbatim: zero the space above and below trivlists, for verbatim
% caution: affects all trivlist environments (eg centering) beneficially
\\zerotrivseps
\\verbatimindent=0ex		% for memoir verbatim
\\newenvironment{myverbatim}%
{\\verbatim\\leftskip=\\myindent}%
{\\endverbatim}

\\pfbreakskip=\\myskipbig	% hr -> \pfbreak; set the gap
%\\newcommand{\\myhr}%    old hr
%    {{\\centering\\rule[0.4ex]{10ex}{0.3pt}\\par}} % inner set {} is group

\\begin{document}
"""

# end of a LaTeX document
LEND = """
\\end{document}
"""

# dictionaries -------------------------------------

# html -> latex equivalents - \\ is an escaped \
D = {'<p>':'\n',
'</p>': '',
'<h1>':'\n\\mytitle{',
'</h1>':'}',
'<h2>':'\n\\chapter{',
'</h2>':'}',
'<h3>':'\n\\section{',
'</h3>':'}',
'<h4>':'\n\\subsection{',
'</h4>':'}',
'<h5>':'\n\\subsubsection{',
'</h5>':'}',
'<h6>':'\n\\subsubsection{',
'</h6>':'}',
'<blockquote>':'\n\\begin{myblockquote}',
'</blockquote>':'\n\\end{myblockquote}',
'<ul>':'\n\\begin{myul}',
'</ul>':'\\end{myul}',
'<ol>':'\n\\begin{myol}',
'</ol>': '\\end{myol}',
'<li>':'\\item ',
'</li>':'',
'<pre><code>':'\n\\begin{myverbatim}',
'</code></pre>':'\\end{myverbatim}',
'<hr />':'\n\\pfbreak',
'<em>':'\\emph{',
'</em>':'}',
'<strong>':'\\textbf{',
'</strong>':'}',
'<code>':'\\verb|',
'</code>':'|',
}

# html entities -> LaTeX characters or commands
# texpad has a bug with local typesetting: some ligatures, eg 'ff',
# can typeset wrongly as 'f '; the lines below with \kern insert a
# zero-size gap between two characters so they typeset properly
E = {'&amp;':'&',
'&lt;':'<',
'ff':'f\kern0pt{}f'
}

# functions -------------------------------------

# convert one html img element into a latex img element
def latex_img (html_img):
# extract img file name
mo = re.search('src="(.*?)"', html_img) # src="anychars"
if (not mo) or (mo.group(1) == ''):
f = 'No image file name found' # default
else:
f = mo.group(1)

# extract img width
mo = re.search('alt="(.*?)"', html_img) # alt="anychars"
if (not mo) or (mo.group(1) == ''):
w = '\\textwidth' # default
else:
w = mo.group(1)

li = '\\includegraphics[width=' + w + ']{' + f + '}'

# extract title
mo = re.search('title="(.*?)"', html_img)	# get title="anychars"
if (mo) and (mo.group(1) != ''):					# put in float
li = '\n\\begin{figure}[!hbtp]\n' + li + '\n\\par{}' + mo.group(1) + '\n\\end{figure}\n'
return li

# convert all html img elements to latex img elements
def do_imgs (txt):
new_txt = ''
for el in els:
if '/>' in el:
i_r = el.split('/>', 1)	# split into img element and the rest
new_txt += latex_img(i_r[0]) + i_r[1]
else:
new_txt += el # no img element
return new_txt

# main -------------------------------------

console.clear()
txt = editor.get_text()

if '\\' in txt:
'These can only be in LaTeX commands, not in ordinary text',
'Continue')
if '&' in txt:
'These can only be in LaTeX lists, not in ordinary text',
'Continue')

txt = markdown.markdown (txt)			# convert to html, no extensions
for k, v in D.iteritems():				# convert most html to LaTeX
txt = txt.replace(k, v)
txt = do_imgs(txt)								# convert html imgs to latex imgs

if '<a' in txt and '</a>' in txt:	# check for unsupported html
'This workflow does not suport links in LaTeX',
'Continue')
elif '<' in txt or '>' in txt:
console.alert('Warning:\nThe LaTeX file has < or > brackets',
"This could be HTML that hasn't been converted to laTeX",
'Continue')

for k, v in E.iteritems():				# convert minor things to LaTeX
txt = txt.replace(k, v)

txt = LSTART + txt + LEND					# add preamble and postamble
clipboard.set(txt.encode('utf_8', 'replace'))
console.alert('The LaTeX is on the clipboard', 'Switch to Texpad, paste into an empty .tex file, tap typeset, then tap the eye button to see the PDF', 'OK')

# -------------------------------------