Last active
September 12, 2021 00:30
-
-
Save tylerneylon/6ebf0bbbce622975745c to your computer and use it in GitHub Desktop.
Convert markdown to LaTeX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/python3 | |
# | |
# Usage: | |
# md_to_tex.py <md_filename> > myfile.tex | |
# | |
# Converts simple markdown to a LaTeX file. | |
# Use, for example, "pdflatex myfile.tex" to | |
# generate a pdf file using your output file. | |
# | |
# The current script does *not* parse all | |
# markdown syntax; only a subset so far. | |
# | |
import os | |
import re | |
import sys | |
tex_start = r""" | |
\documentclass[11pt,oneside]{amsart} | |
\usepackage{geometry} | |
\geometry{letterpaper} | |
%\usepackage[parfill]{parskip} % Activate to begin paragraphs with an empty line rather than an indent | |
\usepackage{graphicx} | |
\usepackage{amssymb} | |
\usepackage{epstopdf} | |
\DeclareGraphicsRule{.tif}{png}{.png}{`convert #1 `dirname #1`/`basename #1 .tif`.png} | |
\begin{document} | |
""" | |
tex_end = r"\end{document}" | |
indents = [] | |
is_in_quote = False | |
def repl_quote(quote_match): | |
global is_in_quote | |
repl = r"''" if is_in_quote else r'``' | |
is_in_quote = not is_in_quote | |
return repl | |
# Accepts indent=-1 to indicate that | |
# the current list has ended completely. | |
def move_to_indent(indent): | |
global indents | |
if indent >= 0 and (len(indents) == 0 or indents[-1] < indent): | |
indents.append(indent) | |
print(r'\begin{itemize}') | |
return | |
while len(indents) > 0 and indents[-1] > indent: | |
indents.pop() | |
print(r'\end{itemize}') | |
def handle_line(line): | |
global indents | |
line = line.rstrip() | |
always_subs = [[r'\*\*(\S.*?)\*\*', r'{\\bf \1}'], | |
[r'\*(\S.*?)\*', r'{\\it \1}'], | |
[r'^---\s*$', r'\\hrule' ], | |
[r'"', repl_quote ]] | |
for s in always_subs: line = re.sub(s[0], s[1], line) | |
m = re.search(r'^( *)\* (.*)', line) | |
if m: | |
move_to_indent(len(m.group(1))) | |
line = r'\item ' + m.group(2) | |
else: | |
indent = -1 | |
if re.search(r'^( +)\S', line) and len(indents): indent = indents[-1] | |
move_to_indent(indent) | |
normal_subs = [[r'^# (.*)', r'\\rightline{\\Large \1}'], | |
[r'^## (.*)', r'\\section{\1}' ], | |
[r'^### (.*)', r'\\subsection{\1}' ], | |
[r'^#### (.*)', r'\\subsubsection{\1}' ], | |
[r'^#####+ (.*)', r'{\\bf \1}' ]] | |
for s in normal_subs: line = re.sub(s[0], s[1], line) | |
print(line) | |
if __name__ == '__main__': | |
if len(sys.argv) < 2: | |
print('Usage: %s <md_filename>' % os.path.basename(sys.argv[0])) | |
print('Output is sent to stdout.') | |
exit(2) | |
print(tex_start) | |
with open(sys.argv[1]) as f: | |
for line in f: | |
handle_line(line) | |
print(tex_end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment