, 5 min read
Converting Markdown to Springer Nature LaTeX Format
I created a blog post Tendler-like Formulas for Stiff ODEs which I wanted to get published in Springer "Numerical Algorithms".
Springer "Numerical Algorithms" first published starting in 1991. Its editor in chief is Claude Brezisnki.
Blog post on this very blog are created in Markdown with MathJax, i.e., LaTeX formulas, sprinkled in. The static site generator Simplified Saaze then converts this into HTML. Obviously, I didn't want to create two documents, i.e., one for the blog, and another for the journal. Also, the journal might reject the submission. In that case I would at least retain the blog post.
The solution is to use a small Perl script blog2springer to automatically convert the Markdown from the blog to the LaTeX required for the journal.
I had done the reverse thing here: Converting Journal Article from LaTeX to Markdown, i.e., take LaTeX as input and produce a blog post in Markdown format.
1. Perl script blog2springer
Here we run down the Perl script called blog2springer.
Bibliographic references in a blog post are done using [reftext](hyperlink), while the journal LaTeX format is still very oldstyle and uses numbers.
I use a hash to convert reftext to numbers.
#!/bin/perl -W
# Reformat Markdown with MathJax to Springer Nature LaTeX format
# Elmar Klausmeier, 31-Dec-2025
use strict;
my ($skip,$summary,$ref,$refcnt,$sec,$eq,$ineq,$cnt,$enum,$itemize) = (0,0,0,0,0,0,0,0,0,0);
my %L = (
'Akrivis/Katsoprinakis (2020)' => 1,
'Albrecht (1978)' => 2,
'Albrecht (1985)' => 3,
'Bickart/Picel (1973)' => 4,
'Butcher (2016)' => 5,
'Gaffney (1984)' => 6,
'Gohberg/Lancaster/Rodman (1978)' => 7,
'Gohberg/Lancaster/Rodman (2009)' => 8,
'Gupta (1985)' => 9,
'Hairer/Wanner/Nørsett (2008)' => 10,
'Hairer/Wanner (2010)' => 11,
'Mihelcic/Wingerath (1981)' => 12,
'Montenbruck/Gill (2000)' => 13,
'Norsett/Thomsen (1986)' => 14,
'Petzold (1983)' => 15,
'Rubin (1973)' => 16,
'Shampine (1982)' => 17,
'Skeel (1976)' => 18,
'St\"adter et al (2021)' => 19,
'Tendler (1973)' => 20,
'Tendler/Bickart/Picel (1976)' => 21,
'Tendler/Bickart/Picel (1978)' => 22,
'Tischer (1983)' => 23,
'Tischer/Sacks-Davis (1983)' => 24,
'Tischer/Gupta (1985)' => 25,
'Werner/Arndt (1986)' => 26,
);
Springer Nature preloads a number of LaTeX packages.
It seems that it has difficulties with \usepackage{algorithmicx}, although I didn't follow through this.
The script has some values hardcoded, which are specific to the article, like author, etc.
print << "EOF";
\\documentclass[pdflatex,sn-mathphys-num]{sn-jnl}% Math and Physical Sciences Numbered Reference Style
\\usepackage{graphicx}%
\\usepackage{multirow}%
\\usepackage{amsmath,amssymb,amsfonts}%
\\usepackage{amsthm}%
\\usepackage{mathdots}%
\\usepackage{mathrsfs}%
\\usepackage[title]{appendix}%
\\usepackage{xcolor}%
\\usepackage{textcomp}%
\\usepackage{manyfoot}%
\\usepackage{booktabs}%
\\usepackage{algorithm}%
\\usepackage{algpseudocode}%
\\usepackage{listings}%
\\theoremstyle{thmstylethree}%
\\newtheorem{definition}{Definition}%
\\raggedbottom
\\graphicspath{ {./} }
\\setcounter{MaxMatrixCols}{15}
\\renewcommand{\\thesection}{\\arabic{section}.}
\\newcommand{\\dcol}{\\operatorname*{col}}
\\newcommand{\\drow}{\\operatorname*{row}}
\\newcommand{\\diag}{\\operatorname*{diag}}
\\newcommand{\\bov}[2]{\\overline{\\mathbf #1}_{#2}} % boldface and overlined
\\newcommand{\\bopo}{\\bov P1}
\\newcommand{\\boro}{\\bov R1}
\\newcommand{\\bfR}{{\\mathbf{R}}}
\\newcommand{\\bovy}[1]{\\bov Y{\\!#1}}
\\newcommand{\\ovbf}[1]{\\overline{\\mathbf{#1}}}
\\author{\\fnm{Elmar} \\sur{Klausmeier}}
\\email{Elmar.Klausmeier\@gmail.com}
\\date{\\today}
\\begin{document}
\\keywords{cyclic linear multistep methods, matrix polynomials, stiff differential equations, convergence analysis, Widlund-wedge}
\\pacs[Mathematics Subject Classification]{65L04 65L06}
\\pacs[CR]{G.1.7}
EOF
The loop reads each line of the blog post and reformats it.
- The journal wants German Umlaute to be escaped with LaTeX codes
- HTML codes are converted to LaTeX codes
- Numbering of paragraphs and theorems is converted from PHP to fixed numbers.
- Enumerations are converted to the respective format in LaTeX
The Markdown contains some PHP code like so:
__<?=++$c?>.__ Consider the multistep method
That is converted using the $cnt variable.
while (<>) {
s/_Proof:_/\\begin{proof}/;
s/ ☐/\\end{proof}/;
s/°/\\textdegree{}/g;
s/“/``/g;
s/”/''/g;
s/–/--/g;
s/—/---/g;
s/ /~/g;
s/&/\\&/g;
s/\\unicode\{x22F0\}/\\iddots/g;
s/Ä/\\"A/g;
s/Ö/\\"O/g;
s/Ü/\\"U/g;
s/ä/\\"a/g;
s/ö/\\"o/g;
s/ü/\\"u/g;
s/ß/\\ss{}/g;
if (/<\?php if \(false\) \{ \?>/) { $skip = 1; next; }
if (/<\?php \} \?>/) { $skip = 0; next; }
if (/<\?php if \(\$c === 0\) \{ \?>/) { $skip = 0; next; }
if (/<\?php \} else \{ \?>/) { $skip = 1; next; }
next if ($skip == 1);
next if (/<\?php \$c=0; \?>/);
print "\\title[$1]{$1}\n\n" if (/^title: "([^"]+)"/);
if (/^__Abstract.__/) { $summary = 1; print "\\abstract{"; next; }
if ($summary == 1) {
if (length($_) < 2) { $summary = 2; print "}\n\\maketitle\n\n"; next; }
print;
next;
}
next if ($summary != 2);
next if (/^\\def\\/);
if (/^## \d\. References<a id/) { $ref=1; print "\n\n\\begin{thebibliography}{90}\n\n"; next; }
if ($ref == 1) {
if ( $refcnt > 1 && length($_) < 2) { $ref = 0; print "\n\\end{thebibliography}\n\n"; next; }
s/\[([^\]]+?)\]\([^\)]+?\)/$1/g;
if (/^1\. /) {
s/^1\. //;
printf("\n\\bibitem{b%d}\n",++$refcnt);
}
}
if (/^## (\d)\. ([^<]+)<a id/) { $sec=1; print "\n\n\\section{$2}\\label{sec$1}\n\n"; next; }
next if ($sec != 1);
if (/^\$\$/) {
if ($eq % 2 == 0) { $ineq = 1; print "\\begin{align*}\n"; }
else { $ineq = 0; print "\\end{align*}\n"; }
++$eq;
next;
}
s/__(\d+)__/\\textbf{$1}/;
s/__(\w+ \w+ \w+:)__/\\textbf{$1}/;
s/__\((\d+)\)__/\\textbf{($1)}/;
s/`(\w+ \w+)`/\\texttt{$1}/g;
if ($ineq == 0) {
s/ _(\w+)_( |\+)/ \\emph{$1}$2/g;
s/ _(\w+ \w+)_( |\.)/ \\emph{$1}$2/g;
s/ _(\w+ \w+ \w+)_( |\.)/ \\emph{$1}$2/g;
}
#s/!\[\]\(\*<\?=\$rbase\?>\*\/img\/([-\w]+)\.jpg\)/\\includegraphics[scale=0.4]{$1}/;
if (/!\[\]\(\*<\?=\$rbase\?>\*\/img\/([-\w]+)\.jpg "([^"]+?)"\)/) {
print "\\begin{figure}[H]\n\\begin{center}\n\\includegraphics[scale=0.4]{$1}\n\\caption{$2}\n\\end{center}\\end{figure}\n";
next;
}
foreach my $l (keys %L) {
s/\[\Q$l\E\]\([^\)]*?\)/\[$L{$l}]/g;
}
s/\[([^\]]+?)\]\(\*<\?=\$rbase\?>[^\)]+?\)/$1/g;
s/\[([^\]]+?)\]\([^\)]+?\)/$1/g;
if (/__<\?=\+\+\$c\?>\.__/) { my $t = sprintf("\\textbf{%d.}",++$cnt); s/__<\?=\+\+\$c\?>\.__/${t}/; }
#if (/__<\?=\+\+\$c\?>\. (Definition\.|Examples\.|Theorem:|Main theorem:|Notation\.)__/) {
if (/__<\?=\+\+\$c\?>\. (\w+|['\w]+ \w+)(\.|:)__/) {
my $t = sprintf("\\textbf{%d. %s%s}",++$cnt,$1,$2);
s/__<\?=\+\+\$c\?>\. (\w+|['\w]+ \w+)(\.|:)__/${t}/;
}
if (/^1\. /) {
if ($enum == 0) { $enum = 1; print "\\begin{enumerate}\n"; }
s/^1\. /\\item /;
} elsif ($enum == 1 && length($_) < 2) { $enum = 0; print "\\end{enumerate}\n\n"; }
if (/^\* /) {
if ($itemize == 0) { $itemize = 1; print "\\begin{itemize}\n"; }
s/^\* /\\item /;
} elsif ($itemize == 1 && length($_) < 2) { $itemize = 0; print "\\end{itemize}\n\n"; }
print;
}
Finally we add the footer.
print "\\end{document}\n\n";
2. Usage
I downloaded the journal article template. That zip-file contains the following:
$ unzip -l "Download+the+journal+article+template+package+(December+2024+version).zip"
Archive: Download+the+journal+article+template+package+(December+2024+version).zip
Length Date Time Name
--------- ---------- ----- ----
0 2024-12-13 05:44 sn-article-template/
0 2024-12-13 05:01 sn-article-template/bst/
151345 2024-12-13 05:01 sn-article-template/bst/sn-apacite.bst
29828 2024-12-13 05:01 sn-article-template/bst/sn-aps.bst
35515 2024-12-13 05:19 sn-article-template/bst/sn-basic.bst
33968 2024-12-13 05:01 sn-article-template/bst/sn-chicago.bst
64023 2024-12-13 05:01 sn-article-template/bst/sn-mathphys-ay.bst
64164 2024-12-13 05:01 sn-article-template/bst/sn-mathphys-num.bst
39056 2024-12-13 05:01 sn-article-template/bst/sn-nature.bst
39951 2024-12-13 05:01 sn-article-template/bst/sn-vancouver-ay.bst
40758 2024-12-13 05:01 sn-article-template/bst/sn-vancouver-num.bst
2890 2024-12-13 05:01 sn-article-template/empty.eps
91593 2024-12-13 05:01 sn-article-template/fig.eps
421391 2024-12-13 05:20 sn-article-template/sn-article.pdf
34686 2024-12-13 05:45 sn-article-template/sn-article.tex
5123 2024-12-13 05:01 sn-article-template/sn-bibliography.bib
55857 2024-12-13 05:01 sn-article-template/sn-jnl.cls
418495 2024-12-13 05:01 sn-article-template/user-manual.pdf
--------- -------
1528643 18 files
For my article I only needed sn-jnl.cls.
I did not use BibTeX as the blog post points to external references via HTML links, while the journal just uses numbers for citations.
Converting the blog post goes like this:
blog2springer ~/php/sndsaaze/content/blog/2026/01-20-tendler-like-formulas-for-stiff-odes.md > tendler-like-formulas-for-stiff-odes.tex
Then compile with LaTeX:
pdflatex tendler-like-formulas-for-stiff-odes.tex
Then view the result:
mupdf tendler-like-formulas-for-stiff-odes.pdf
I use mupdf for viewing PDFs.