diff --git a/README b/README deleted file mode 100644 index 629bfaf..0000000 --- a/README +++ /dev/null @@ -1,9 +0,0 @@ -jemdoc is a light text-based markup language designed for creating websites. It -takes a text file written with jemdoc markup, an optional configuration file and -an optional menu file, and makes static websites that look something like -http://jemdoc.jaboc.net/. - -It was written by me, Jacob Mattingley, in 2007, and definitely isn't the type -of code I would put on my CV. Lots of people use jemdoc, especially in academia. - -Much more info at http://jemdoc.jaboc.net/. diff --git a/README.md b/README.md new file mode 100644 index 0000000..959afa3 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +jemdoc+MathJax +============== +*jemdoc* is a light text-based markup language designed for creating websites. See http://jemdoc.jaboc.net/ for more information and the detailed usage of jemdoc. + +*jemdoc+MathJax* adds the MathJax support to jemdoc. You can use the same jemdoc syntax (and therefore no need to make any changes in your jemdoc scripts if you are an original jemdoc user), but the equations will be beautifully rendered by MathJax. See http://web.stanford.edu/~wsshin/jemdoc+mathjax.html for more information and examples. + +System requirements +------------------- +Python 2 or Python 3 + +(Many thanks to [Ganesh Ajjanagadde](http://www.mit.edu/~gajjanag/), who made most of the changes for Python 3 compatibility.) + +What's new in jemdoc+MathJax +---------------------------- +- MathJax support +- Underscore +- Control of the behavior of links: open in the current web broswer tab or in a new tab +- Works on both Python 2 and 3 + +How to use jemdoc+MathJax +------------------------- +The only major difference from the original jemdoc in usage is the mechanism to fetch the javascript engine for MathJax. The recommended way of doing this is to specify the URL of the javascript engine inside a configuration file (`mysite.conf` in the following example) and to provide the file to the jemdoc executable as + + jemdoc -c mysite.conf YOUR_JEMDOC_SCRIPT.jemdoc + +An example `mysite.conf` can be found in the `example/` directory. + +The `example/` directory also contains jemdoc script files that demonstrate the usage of the additional features implemented in jemdoc+MathJax. You can build a website out of these jemdoc scripts by executing the following command inside the `example/` directory: + + ../jemdoc -c mysite.conf *.jemdoc + +To see the resulting website, open any HTML files generated by the above command inside a web browser. + +Except for the MathJax support and the few additional features mentioned previously, jemdoc+MathJax is almost exactly the same as the original jemdoc. To learn the usage of the original jemdoc, see the [jemdoc user guide](http://jemdoc.jaboc.net/using.html), expecially the [example page](http://jemdoc.jaboc.net/example.html). + +Disclaimer +---------- +The focus of the implementation of the additional features was to "make them just work," so the implementation is suboptimal, both in terms of performance and style. + +Still, several users and I find jemdoc+MathJax is quite stable and does the job correctly :-) + +Wonseok Shin + +README of the original jemdoc +----------------------------- +> jemdoc is a light text-based markup language designed for creating websites. It +> takes a text file written with jemdoc markup, an optional configuration file and +> an optional menu file, and makes static websites that look something like +> http://jemdoc.jaboc.net/. +> +> It was written by me, Jacob Mattingley, in 2007, and definitely isn't the type +> of code I would put on my CV. Lots of people use jemdoc, especially in academia. +> +> Much more info at http://jemdoc.jaboc.net/. + diff --git a/css/example.css b/css/example.css index e206d6a..997cc5a 100644 --- a/css/example.css +++ b/css/example.css @@ -1,25 +1,25 @@ table.dual-mode { - padding: 0; - margin-top, margin-bottom: 0.5em; + padding: 0; + margin-top, margin-bottom: 0.5em; border-width: 0; } table.dual-mode tr { - vertical-align: top; + vertical-align: top; } -table.dual-mode h1, tr h2{ - padding-top: 0em; +table.dual-mode h1, tr h2 { + padding-top: 0em; margin-top: 0; } td { - text-align: left; - border: none; + text-align: left; + border: none; } td.rightcell tt { - background: none; + background: none; } td.rightcell div.blockcontent { @@ -35,7 +35,7 @@ td.rightcell div.codeblock { td.leftcell { padding-right: 10px; - padding-top: 10px; + padding-top: 10px; width: 50%; } diff --git a/css/exp.css b/css/exp.css index 6623186..ac3d57e 100644 --- a/css/exp.css +++ b/css/exp.css @@ -1,84 +1,84 @@ body { - font: 80% Verdana, sans-serif; + font: 80% Verdana, sans-serif; } pre, tt { - font-size: 110%; + font-size: 110%; } tt { - background: #ffffdd; - color: #000050; + background: #ffffdd; + color: #000050; } pre { - color: black; + color: black; } a { - border-bottom: 1px solid #bbbbbb; + border-bottom: 1px solid #bbbbbb; } a:hover { - border-bottom: 1px solid #bbbbbb; + border-bottom: 1px solid #bbbbbb; } h1 { - font-size: 150%; - border: none; + font-size: 150%; + border: none; } h2 { - font-size: 115%; - border: none; + font-size: 115%; + border: none; } h3 { - font-size: 100%; - border: none; + font-size: 100%; + border: none; } div.infoblock > div.blockcontent { - background: #ffffdd; + background: #ffffdd; } div.blockcontent { - padding-left: 10px; - padding-right: 10px; - padding-top: 6px; - padding-bottom: 7px; + padding-left: 10px; + padding-right: 10px; + padding-top: 6px; + padding-bottom: 7px; } p { - line-height: 1.5em; + line-height: 1.5em; margin-bottom: 1.2em; } #layout-menu { - padding-left: 15px; - line-height: 1.7em; - text-align: right; - padding-top: 0.5em; + padding-left: 15px; + line-height: 1.7em; + text-align: right; + padding-top: 0.5em; } b { - font-weight: normal; + font-weight: normal; } p b { - font-style: italic; + font-style: italic; } div.menu-item { - padding-left: 0; - text-indent: 0; - padding-bottom: 2px; + padding-left: 0; + text-indent: 0; + padding-bottom: 2px; } #layout-menu a:link, #layout-menu a:visited, #layout-menu a:hover { - color: black; + color: black; border-bottom: 1px gray solid; } @@ -88,13 +88,13 @@ div.menu-item { div#footer { border-top: 1px solid #e0e0e0; - font-size: 80%; - padding-bottom: 0; + font-size: 80%; + padding-bottom: 0; } div#footer a { color: #aaaaaa; - border-bottom: 1px solid #cccccc; + border-bottom: 1px solid #cccccc; } #fwtitle div#toptitle { @@ -103,7 +103,7 @@ div#footer a { #layout-content { - padding-top: 1.3em; - padding-left: 30px; - padding-right: 30px; + padding-top: 1.3em; + padding-left: 30px; + padding-right: 30px; } diff --git a/css/jacob.css b/css/jacob.css index 52e7902..2ba613b 100644 --- a/css/jacob.css +++ b/css/jacob.css @@ -34,5 +34,5 @@ div.blockcontent { } div#footer-text { - padding-bottom: 8px; + padding-bottom: 8px; } diff --git a/css/jemdoc.css b/css/jemdoc.css index 00e05f0..aa9923d 100644 --- a/css/jemdoc.css +++ b/css/jemdoc.css @@ -1,9 +1,9 @@ /* Default css file for jemdoc. */ table#tlayout { - border: none; - border-collapse: separate; - background: white; + border: none; + border-collapse: separate; + background: white; } body { @@ -22,23 +22,23 @@ body { font-size: 1.0em; width: auto; white-space: nowrap; - text-align: left; - vertical-align: top; + text-align: left; + vertical-align: top; } #layout-menu td { background: #f4f4f4; - vertical-align: top; + vertical-align: top; } #layout-content { padding-top: 0.0em; padding-left: 1.0em; padding-right: 1.0em; - border: none; - background: white; - text-align: left; - vertical-align: top; + border: none; + background: white; + text-align: left; + vertical-align: top; } #layout-menu a { @@ -47,7 +47,7 @@ body { } tt { - background: #ffffdd; + background: #ffffdd; } pre, tt { @@ -136,7 +136,7 @@ h2 { } h2 + h3 { - padding-top: 0.2em; + padding-top: 0.2em; } h3 { @@ -297,7 +297,10 @@ span.comment, span.comment > *, span.string, span.string > * { } @media print { - #layout-menu { display: none; } + #layout-menu { + display: none; + } + } #fwtitle { @@ -336,32 +339,32 @@ img.eqwl { } table { - border: 2px solid black; - border-collapse: collapse; + border: 2px solid black; + border-collapse: collapse; } td { - padding: 2px; - padding-left: 0.5em; - padding-right: 0.5em; - text-align: center; - border: 1px solid gray; + padding: 2px; + padding-left: 0.5em; + padding-right: 0.5em; + text-align: center; + border: 1px solid gray; } table + table { - margin-top: 1em; + margin-top: 1em; } tr.heading { - font-weight: bold; - border-bottom: 2px solid black; + font-weight: bold; + border-bottom: 2px solid black; } img { - border: none; + border: none; } table.imgtable, table.imgtable td { - border: none; - text-align: left; + border: none; + text-align: left; } diff --git a/css/page.css b/css/page.css index dcbbe68..65c25b9 100644 --- a/css/page.css +++ b/css/page.css @@ -1,47 +1,47 @@ -#fwtitle { - margin: 0; - padding: 0; +#fwtitle { + margin: 0; + padding: 0; } #fwtitle div#toptitle { - background-color: #303050; - padding: 1em; - margin: 0; - border: none; + background-color: #303050; + padding: 1em; + margin: 0; + border: none; } div#toptitle h1 { - margin-top: 0.1em; + margin-top: 0.1em; } #fwtitle div#toptitle h1, div#subtitle, div#subtitle a { - color: white; - font-weight: normal; - text-align: left; + color: white; + font-weight: normal; + text-align: left; } #layout-menu { - border: none; - border-right: 1px dashed #aaaaaa; - margin: 0; - padding-top: 0; + border: none; + border-right: 1px dashed #aaaaaa; + margin: 0; + padding-top: 0; } div.menu-category { - border-bottom: none; - padding-bottom: 0; + border-bottom: none; + padding-bottom: 0; } #layout-content { - border: none; - padding: 8px; - padding-left: 16px; - padding-right: 16px; - padding-bottom: 0; - margin: 0; + border: none; + padding: 8px; + padding-left: 16px; + padding-right: 16px; + padding-bottom: 0; + margin: 0; } body { - padding: 0; - padding-bottom: 8px; + padding: 0; + padding-bottom: 8px; } diff --git a/css/prob.css b/css/prob.css index f19758c..e06d12e 100644 --- a/css/prob.css +++ b/css/prob.css @@ -1,56 +1,56 @@ div.codeblock pre { - font-size: 0.2em; + font-size: 0.2em; } p b { - font-style: normal; - font-weight: bold; + font-style: normal; + font-weight: bold; } td.c1 { - text-align: right; + text-align: right; } td.c2 { - text-align: left; - font-weight: bold; + text-align: left; + font-weight: bold; } table { - border: 1px solid black; - margin-top: 0.5em; - margin-bottom: 1em; + border: 1px solid black; + margin-top: 0.5em; + margin-bottom: 1em; } p + table { - margin-top: -0.3em; + margin-top: -0.3em; } a.imglink { - border: none; + border: none; } /* Exceedingly lame hack to eliminate borders with figure images. */ a.imglink > img { - margin-left: -55px; + margin-left: -55px; } .red { - color: red; + color: red; } .green { - color: green; + color: green; } h1 { - padding-top: 1em; + padding-top: 1em; } table#allprobs td { - font-weight: normal; + font-weight: normal; } table#allprobs td.c1, table#allprobs tr.r1 td, table#allprobs tr.r1 td.c1 { - font-weight: bold; + font-weight: bold; } diff --git a/css/table.css b/css/table.css index ee59050..9c1be3f 100644 --- a/css/table.css +++ b/css/table.css @@ -1,4 +1,4 @@ #countries tr.r1 { - border-bottom: 2px solid black; - font-weight: bold; + border-bottom: 2px solid black; + font-weight: bold; } diff --git a/css/white.css b/css/white.css index ec4dec9..4ee5dd2 100644 --- a/css/white.css +++ b/css/white.css @@ -1,52 +1,52 @@ body { - font: 80% Verdana; - margin-left: 2em; - margin-top: 1em; + font: 80% Verdana; + margin-left: 2em; + margin-top: 1em; } pre, tt { - font-size: 110%; - background: #ffffdd; + font-size: 110%; + background: #ffffdd; } tt { - color: #700000; + color: #700000; } pre { - color: black; + color: black; } a { - border-bottom: 1px solid #bbbbbb; - color: black; + border-bottom: 1px solid #bbbbbb; + color: black; } h1 { - font-size: 150%; - border: none; + font-size: 150%; + border: none; } h2 { - font-size: 115%; - border: none; + font-size: 115%; + border: none; } h3 { - font-size: 100%; - border: none; + font-size: 100%; + border: none; } h1, h2, h3, div.blocktitle { - color: #990000; + color: #990000; } div.blockcontent { - border: none; + border: none; } div.infoblock > div.blockcontent { - background: #ffffdd; + background: #ffffdd; } div.codeblock > div.blockcontent, div.blockcontent pre { @@ -54,48 +54,48 @@ div.codeblock > div.blockcontent, div.blockcontent pre { } body, p { - line-height: 1.5em; + line-height: 1.5em; margin-bottom: 1.2em; } #layout-menu { - padding-left: 20px; - padding-right: 20px; - background: none; - text-align: right; - border: none; - padding-top: 3.0em; + padding-left: 20px; + padding-right: 20px; + background: none; + text-align: right; + border: none; + padding-top: 3.0em; } #layout-content { - padding-left: 25px; - padding-top: 1em; - width: 600px; + padding-left: 25px; + padding-top: 1em; + width: 600px; } b { - font-weight: normal; + font-weight: normal; } p b { - font-style: italic; + font-style: italic; } div.menu-category { - border: none; - border-bottom: 1px solid - margin-top: 1.0em; - padding-bottom: 0; + border: none; + border-bottom: 1px solid + margin-top: 1.0em; + padding-bottom: 0; } div.menu-item { - padding-left: 0; - text-indent: 0; - padding-bottom: 2px; + padding-left: 0; + text-indent: 0; + padding-bottom: 2px; } #layout-menu a:link, #layout-menu a:visited, #layout-menu a:hover { - color: black; + color: black; border-bottom: 1px gray solid; } @@ -106,16 +106,16 @@ div.menu-item { div#footer { border-top: 1px solid #e0e0e0; - font-size: 80%; - padding-bottom: none; + font-size: 80%; + padding-bottom: none; } div#footer a { color: #bbbbbb; - border-bottom: 1px solid #cccccc; + border-bottom: 1px solid #cccccc; } div#toptitle { - border: none; + border: none; } diff --git a/example/MENU b/example/MENU new file mode 100644 index 0000000..fa78d40 --- /dev/null +++ b/example/MENU @@ -0,0 +1,5 @@ +Additional Features + MathJax [mathjax.html] + Underscore [underscore.html] + Link [link.html] + Open in New Tab [\http://www.google.com] diff --git a/example/jemdoc.css b/example/jemdoc.css new file mode 100644 index 0000000..def76bb --- /dev/null +++ b/example/jemdoc.css @@ -0,0 +1,372 @@ +/* Default css file for jemdoc. */ + +table#tlayout { + border: none; + border-collapse: separate; + background: white; +} + +body { + background: white; + font-family: Georgia, serif; + padding-bottom: 8px; + margin: 0; +} + +#layout-menu { + background: #f6f6f6; + border: 1px solid #dddddd; + padding-top: 0.5em; + padding-left: 8px; + padding-right: 8px; + font-size: 1.0em; + width: auto; + white-space: nowrap; + text-align: left; + vertical-align: top; +} + +#layout-menu td { + background: #f4f4f4; + vertical-align: top; +} + +#layout-content { + padding-top: 0.0em; + padding-left: 1.0em; + padding-right: 1.0em; + border: none; + background: white; + text-align: left; + vertical-align: top; + min-width: 800px; + width: 800px; +} + +#layout-menu a { + line-height: 1.5em; + margin-left: 0.5em; +} + +tt { + background: #ffffdd; +} + +pre, tt { + font-size: 90%; + font-family: monaco, monospace; +} + +a, a > tt { + color: #224b8d; + text-decoration: none; +} + +a:hover { + border-bottom: 1px gray dotted; +} + +#layout-menu a.current:link, #layout-menu a.current:visited { + color: #022b6d; + border-bottom: 1px gray solid; +} +#layout-menu a:link, #layout-menu a:visited, #layout-menu a:hover { + color: #527bbd; + text-decoration: none; +} +#layout-menu a:hover { + text-decoration: none; +} + +div.menu-category { + border-bottom: 1px solid gray; + margin-top: 0.8em; + padding-top: 0.2em; + padding-bottom: 0.1em; + font-weight: bold; +} + +div.menu-item { + padding-left: 16px; + text-indent: -16px; +} + +div#toptitle { + padding-bottom: 0.2em; + margin-bottom: 1.5em; + border-bottom: 3px double gray; +} + +/* Reduce space if we begin the page with a title. */ +div#toptitle + h2, div#toptitle + h3 { + margin-top: -0.7em; +} + +div#subtitle { + margin-top: 0.0em; + margin-bottom: 0.0em; + padding-top: 0em; + padding-bottom: 0.1em; +} + +em { + font-style: italic; +} + +strong { + font-weight: bold; +} + + +h1, h2, h3 { + color: #527bbd; + margin-top: 0.7em; + margin-bottom: 0.3em; + padding-bottom: 0.2em; + line-height: 1.0; + padding-top: 0.5em; + border-bottom: 1px solid #aaaaaa; +} + +h1 { + font-size: 165%; +} + +h2 { + padding-top: 0.8em; + font-size: 125%; +} + +h2 + h3 { + padding-top: 0.2em; +} + +h3 { + font-size: 110%; + border-bottom: none; +} + +p { + margin-top: 0.0em; + margin-bottom: 0.8em; + padding: 0; + line-height: 1.3; +} + +pre { + padding: 0; + margin: 0; +} + +div#footer { + font-size: small; + border-top: 1px solid #c0c0c0; + padding-top: 0.1em; + margin-top: 4.0em; + color: #c0c0c0; +} + +div#footer a { + color: #80a0b0; +} + +div#footer-text { + float: left; + padding-bottom: 8px; +} + +ul, ol, dl { + margin-top: 0.2em; + padding-top: 0; + margin-bottom: 0.8em; +} + +dt { + margin-top: 0.5em; + margin-bottom: 0; +} + +dl { + margin-left: 20px; +} + +dd { + color: #222222; +} + +dd > *:first-child { + margin-top: 0; +} + +ul { + list-style-position: outside; + list-style-type: square; +} + +p + ul, p + ol { + margin-top: -0.5em; +} + +li ul, li ol { + margin-top: -0.3em; +} + +ol { + list-style-position: outside; + list-style-type: decimal; +} + +li p, dd p { + margin-bottom: 0.3em; +} + + +ol ol { + list-style-type: lower-alpha; +} + +ol ol ol { + list-style-type: lower-roman; +} + +p + div.codeblock { + margin-top: -0.6em; +} + +div.codeblock, div.infoblock { + margin-right: 0%; + margin-top: 1.2em; + margin-bottom: 1.3em; +} + +div.blocktitle { + font-weight: bold; + color: #cd7b62; + margin-top: 1.2em; + margin-bottom: 0.1em; +} + +div.blockcontent { + border: 1px solid silver; + padding: 0.3em 0.5em; +} + +div.infoblock > div.blockcontent { + background: #ffffee; +} + +div.blockcontent p + ul, div.blockcontent p + ol { + margin-top: 0.4em; +} + +div.infoblock p { + margin-bottom: 0em; +} + +div.infoblock li p, div.infoblock dd p { + margin-bottom: 0.5em; +} + +div.infoblock p + p { + margin-top: 0.8em; +} + +div.codeblock > div.blockcontent { + background: #f6f6f6; +} + +span.pycommand { + color: #000070; +} + +span.statement { + color: #008800; +} +span.builtin { + color: #000088; +} +span.special { + color: #990000; +} +span.operator { + color: #880000; +} +span.error { + color: #aa0000; +} +span.comment, span.comment > *, span.string, span.string > * { + color: #606060; +} + +@media print { + #layout-menu { + display: none; + } + +} + +#fwtitle { + margin: 2px; +} + +#fwtitle #toptitle { + padding-left: 0.5em; + margin-bottom: 0.5em; +} + +#layout-content h1:first-child, #layout-content h2:first-child, #layout-content h3:first-child { + margin-top: -0.7em; +} + +div#toptitle h1, #layout-content div#toptitle h1 { + margin-bottom: 0.0em; + padding-bottom: 0.1em; + padding-top: 0; + margin-top: 0.5em; + border-bottom: none; +} + +img.eq { + padding: 0; + padding-left: 0.1em; + padding-right: 0.1em; + margin: 0; +} + +img.eqwl { + padding-left: 2em; + padding-top: 0.6em; + padding-bottom: 0.2em; + margin: 0; +} + +table { + border: 2px solid black; + border-collapse: collapse; +} + +td { + padding: 2px; + padding-left: 0.5em; + padding-right: 0.5em; + text-align: center; + border: 1px solid gray; +} + +table + table { + margin-top: 1em; +} + +tr.heading { + font-weight: bold; + border-bottom: 2px solid black; +} + +img { + border: none; +} + +table.imgtable, table.imgtable td { + border: none; + text-align: left; +} diff --git a/example/link.jemdoc b/example/link.jemdoc new file mode 100644 index 0000000..73817f3 --- /dev/null +++ b/example/link.jemdoc @@ -0,0 +1,8 @@ +# jemdoc: menu{MENU}{link.html}, nofooter +== Underscore Example + +You can control the behavior of a link: by default the link opens in a new web broswer tab, but by putting a slash (+\/+) character at the beginning of the link address you can make it open in the current web broswer tab. + +For example, [mathjax.html \[mathjax.html\]] opens in a new web broswer tab, but [/mathjax.html \[\/mathjax.html\]] opens in the current web browser tab. The link opening in a new tab is useful for linking an external website (like [http://www.google.com]), whereas the link opening in the current tab is useful for liking your jemdoc page (such as the page linked as a jemdoc menu item on the left panel). + +Unlike the link in the main text, a jemdoc menu item link on the left panel opens in the current tab by default, because you want to stay in the same tab while navigating menu items. However, you can override this default behavior and make it open in a new tab by putting a backslash (+\\+) character in the beginning of the link of the menu item. This is useful when putting an external website as a menu item. See this usage in "Open in New Tab" menu item on the left panel, which is defined in MENU file. diff --git a/example/mathjax.jemdoc b/example/mathjax.jemdoc new file mode 100644 index 0000000..13b46cb --- /dev/null +++ b/example/mathjax.jemdoc @@ -0,0 +1,46 @@ +# jemdoc: menu{MENU}{mathjax.html}, nofooter +== MathJax Example + +In this modified version of +jemdoc+, a LaTeX equation block can be typed in as +\( +\nabla \cdot \mathbf{D} = \rho_f\\ +\nabla \cdot \mathbf{B} = 0,\\ +\nabla \times \mathbf{E} = -\frac{\partial\mathbf{B}}{\partial t}\\ +\nabla \times \mathbf{H} = \mathbf{J}_f - \frac{\partial\mathbf{D}}{\partial t}. +\) + +You can also align equations using LaTeX's +aligned+ block: +\( +\begin{aligned} +\nabla \cdot \mathbf{D} &= \rho_f\\ +\nabla \cdot \mathbf{B} &= 0\\ +\nabla \times \mathbf{E} &= -\frac{\partial\mathbf{B}}{\partial t}\\ +\nabla \times \mathbf{H} &= \mathbf{J}_f - \frac{\partial\mathbf{D}}{\partial t}. +\end{aligned} +\) + +To number the equation block, wrap the equations with LaTeX's +equation+ block: +\( +\begin{equation} +\begin{aligned} +\nabla \cdot \mathbf{D} &= \rho_f\\ +\nabla \cdot \mathbf{B} &= 0\\ +\nabla \times \mathbf{E} &= -\frac{\partial\mathbf{B}}{\partial t}\\ +\nabla \times \mathbf{H} &= \mathbf{J}_f - \frac{\partial\mathbf{D}}{\partial t}. +\end{aligned} +\end{equation} +\) + +Instead, you can use LaTeX's +align+ (not +aligned+) block to number the individual equations: +\( +\begin{align} +\nabla \cdot \mathbf{D} &= \rho_f\label{eq:D}\\ +\nabla \cdot \mathbf{B} &= 0\label{eq:B}\\ +\nabla \times \mathbf{E} &= -\frac{\partial\mathbf{B}}{\partial t}\label{eq:E}\\ +\nabla \times \mathbf{H} &= \mathbf{J}_f - \frac{\partial\mathbf{D}}{\partial t}\label{eq:H} +\end{align} +\) + +You can also type inline equations as $A x = b$. Referencing equations is done as Eqs.~$\eqref{eq:E}$ and $\eqref{eq:H}$. + + diff --git a/example/mysite.conf b/example/mysite.conf new file mode 100644 index 0000000..570e43b --- /dev/null +++ b/example/mysite.conf @@ -0,0 +1,12 @@ +[bodystart] + + + + + + diff --git a/example/underscore.jemdoc b/example/underscore.jemdoc new file mode 100644 index 0000000..8681550 --- /dev/null +++ b/example/underscore.jemdoc @@ -0,0 +1,7 @@ +# jemdoc: menu{MENU}{underscore.html}, nofooter +== Underscore Example + +Like *bold* and /italic/, _underscore_ can be used for emphasis in this modified version of +jemdoc+. Useful for highlighting different parts of a bibliography item as: + +1. _First Author_, Second Author, and *Corresponding Author*, "Amazing Paper," /High-impact Journal/, vol.~1, pp.~1--10 (2014). + diff --git a/jemdoc b/jemdoc index 0e3e25e..a6bd6f4 100755 --- a/jemdoc +++ b/jemdoc @@ -22,25 +22,27 @@ # latexmath2png, by Kamil Kisiel (kamil@kamikisiel.net). # +from __future__ import print_function import sys import os import re import time -import StringIO +import io from subprocess import * +from types import * import tempfile def info(): - print __doc__ - print 'Platform: ' + sys.platform + '.' - print 'Python: %s, located at %s.' % (sys.version[:5], sys.executable) - print 'Equation support:', + print(__doc__) + print('Platform: ' + sys.platform + '.') + print('Python: %s, located at %s.' % (sys.version[:5], sys.executable)) + print('Equation support:', end=' ') (supported, message) = testeqsupport() if supported: - print 'yes.' + print('yes.') else: - print 'no.' - print message + print('no.') + print(message) def testeqsupport(): supported = True @@ -85,7 +87,7 @@ class controlstruct(object): def pushfile(self, newfile): self.otherfiles.insert(0, self.inf) - self.inf = open(newfile, 'rb') + self.inf = io.open(newfile, 'rb') def nextfile(self): self.inf.close() @@ -127,7 +129,7 @@ def showhelp(): else: b += l - print b + print(b) def standardconf(): a = """[firstbit] @@ -190,7 +192,7 @@ def standardconf(): [menuitem] - + [specificcss] @@ -199,7 +201,7 @@ def standardconf(): [currentmenuitem] - + [nomenu]
@@ -252,7 +254,7 @@ def standardconf():
[lastupdated] - Page generated |, by jemdoc. + Page generated |, by jemdoc+MathJax. [sourcelink] (source) @@ -260,7 +262,9 @@ def standardconf(): """ b = '' for l in a.splitlines(True): - if l.startswith(' '): + if l.startswith(' #'): + continue + elif l.startswith(' '): b += l[2:] else: b += l @@ -281,7 +285,7 @@ def raisejandal(msg, line=0): raise JandalError(s) def readnoncomment(f): - l = f.readline() + l = f.readline().decode('utf-8') if l == '': return l elif l[0] == '#': # jem: be a little more generous with the comments we accept? @@ -293,9 +297,9 @@ def parseconf(cns): syntax = {} warn = False # jem. make configurable? # manually add the defaults as a file handle. - fs = [StringIO.StringIO(standardconf())] + fs = [io.BytesIO(standardconf().encode('utf-8'))] for sname in cns: - fs.append(open(sname, 'rb')) + fs.append(io.open(sname, 'rb')) for f in fs: while pc(controlstruct(f)) != '': @@ -318,7 +322,7 @@ def parseconf(cns): return syntax def insertmenuitems(f, mname, current, prefix): - m = open(mname, 'rb') + m = io.open(mname, 'rb') while pc(controlstruct(m)) != '': l = readnoncomment(m) l = l.strip() @@ -329,6 +333,12 @@ def insertmenuitems(f, mname, current, prefix): if r: # then we have a menu item. link = r.group(2) + if link[0] == '\\': + option = ' target="blank"' + link = link[1:] + else: + option = '' + # Don't use prefix if we have an absolute link. if '://' not in r.group(2): link = prefix + allreplace(link) @@ -353,9 +363,9 @@ def insertmenuitems(f, mname, current, prefix): menuitem += br(re.sub(r'(?', 'GREATERTHAN65358') +# eqtext = eqtext.replace('\n', ' ') + eqtext = eqtext.replace('_', 'UNDERSCORE65358') + eqtext = eqtext.replace('/', 'SLASH65358') + + return eqtext + +def mathjaxeqresub(r): + r = re.sub('BACKSLASH65358', r'\\', r) + r = re.sub('OPENBRACKET65358', '[', r) + r = re.sub('CLOSEBRACKET65358', ']', r) + r = re.sub('ASTERISK65358', '*', r) + r = re.sub('PLUS65358', '+', r) + r = re.sub('AMPERSAND65358', '&', r) + r = re.sub('LESSTHAN65358', '<', r) + r = re.sub('GREATERTHAN65358', '>', r) + r = re.sub('QUOTATION65358', '"', r) + r = re.sub('UNDERSCORE65358', '_', r) + r = re.sub('SLASH65358', '/', r) + + return r + +def hb(f, tag, content1, content2=None, content3=None): """Writes out a halfblock (hb).""" if content1 is None: content1 = "" + if content3 is None: + content3 = "" + if content2 is None: - out(f, re.sub(r'\|', content1, tag)) +# out(f, re.sub(r'\|', content1, tag)) + r = re.sub(r'\|', content1, tag) + r = re.sub(r'\|3', content3, r) + r = mathjaxeqresub(r) + out(f, r) else: r = re.sub(r'\|1', content1, tag) + r = re.sub(r'\|3', content3, r) r = re.sub(r'\|2', content2, r) + r = mathjaxeqresub(r) out(f, r) def pc(f, ditchcomments=True): """Peeks at next character in the file.""" # Should only be used to look at the first character of a new line. - c = f.inf.read(1) + c = f.inf.read(1).decode('cp1252') if c: # only undo forward movement if we're not at the end. if ditchcomments and c == '#': l = nl(f) @@ -404,12 +467,13 @@ def pc(f, ditchcomments=True): def doincludes(f, l): ir = 'includeraw{' i = 'include{' + l = l.rstrip() if l.startswith(ir): - nf = open(l[len(ir):-2], 'rb') - f.outf.write(nf.read()) + nf = io.open(l[len(ir):-1], 'rb') + f.outf.write(nf.read().decode('utf-8')) nf.close() elif l.startswith(i): - f.pushfile(l[len(i):-2]) + f.pushfile(l[len(i):-1]) else: return False @@ -417,7 +481,7 @@ def doincludes(f, l): def nl(f, withcount=False, codemode=False): """Get input file line.""" - s = f.inf.readline() + s = f.inf.readline().decode('utf-8') if not s and f.otherfiles: f.nextfile() return nl(f, withcount, codemode) @@ -460,17 +524,35 @@ def np(f, withcount=False, eatblanks=True): else: s = nl(f) - while pc(f) not in ('\n', '-', '.', ':', '', '=', '~', '{', '\\(', '\\)'): - s += nl(f) + # Determine if the current line has an open inline equation block or not. + r = re.compile(r'(?&$%\.~[\]-]""", r'\\\g<0>', s) @@ -519,50 +601,27 @@ def replaceequations(b, f): else: fn = str(abs(hash(eq))) - # Find out the baseline when we first encounter an equation (don't - # bother, otherwise). - # Other initialization stuff which we do only once we know we have - # equations. - if f.baseline is None: - # See if the eqdir exists, and if not, create it. - if not os.path.isdir(f.eqdir): - os.mkdir(f.eqdir) - - # Check that the tools we need exist. - (supported, message) = testeqsupport() - if not supported: - print 'WARNING: equation support disabled.' - print message - f.eqsupport = False - return b - - # Calculate the baseline. - eqt = "0123456789xxxXXxX" - (f.baseline, blfn) = geneq(f, eqt, dpi=f.eqdpi, wl=False, - outname='baseline-' + str(f.eqdpi)) - if os.path.exists(blfn): - os.remove(blfn) - - fn = fn + '-' + str(f.eqdpi) - (depth, fullfn) = geneq(f, eq, dpi=f.eqdpi, wl=wl, outname=fn) - fullfn = fullfn.replace('\\', '/') - - offset = depth - f.baseline + 1 - eqtext = allreplace(eq) - eqtext = eqtext.replace('\\', '') - eqtext = eqtext.replace('\n', ' ') +# print eqtext +# eqtext = eqtext.replace('\\', '') + eqtext = mathjaxeqsub(eqtext) # Double braces will cause problems with escaping of image tag. eqtext = eqtext.replace('{{', 'DOUBLEOPENBRACE') eqtext = eqtext.replace('}}', 'DOUBLECLOSEBRACE') if wl: - b = b[:m.start()] + \ - '{{\n
%s\n
}}' % (fullfn, eqtext) + b[m.end():] +# b = b[:m.start()] + \ +# '{{\n
%s\n
}}' % (fullfn, eqtext) + b[m.end():] + #b = b[:m.start()] + 'BACKSLASH65358OPENBRACKET65358\n' + eqtext + '\nBACKSLASH65358CLOSEBRACKET65358'+ b[m.end():] + b = b[:m.start()] + 'BACKSLASH65358OPENBRACKET65358' + eqtext + 'BACKSLASH65358CLOSEBRACKET65358'+ b[m.end():] + #b = b[:m.start()] + 'BACKSLASH(BACKSLASHbegin{equation}\n' + eqtext + '\nBACKSLASHend{equation}BACKSLASH)'+ b[m.end():] + b = '

\n' + b + '\n

' + b = mathjaxeqsub(b) else: - b = b[:m.start()] + \ - '{{%s}}' % (fullfn, eqtext, offset) + b[m.end():] +# b = b[:m.start()] + \ +# '{{%s}}' % (fullfn, eqtext, offset) + b[m.end():] + b = b[:m.start()] + 'BACKSLASH65358(' + eqtext + 'BACKSLASH65358)' + b[m.end():] # jem: also clean out line breaks in the alttext? m = r.search(b, m.start()) @@ -613,6 +672,12 @@ def replacelinks(b): while m: m1 = m.group(1).strip() + if m1[0] == '/': + option = '' + m1 = m1[1:] + else: + option = ' target="blank"' + if '@' in m1 and not m1.startswith('mailto:') and not \ m1.startswith('http://'): link = 'mailto:' + m1 @@ -626,6 +691,7 @@ def replacelinks(b): link = re.sub(r'(\+\{\{|\}\}\+)', r'%', link) link = quote(link) + link = mathjaxussub(link) # to prevent _ in address from changing if m.group(2): linkname = m.group(2).strip() @@ -633,7 +699,7 @@ def replacelinks(b): # remove any mailto before labelling. linkname = re.sub('^mailto:', '', link) - b = b[:m.start()] + r'%s<\/a>' % (link, linkname) + b[m.end():] + b = b[:m.start()] + r'%s<\/a>' % (link, option, linkname) + b[m.end():] m = r.search(b, m.start()) @@ -681,7 +747,12 @@ def br(b, f, tableblock=False): # Deal with *bold*. r = re.compile(r'(?\1', b) - + + # Deal with _underscore_. + r = re.compile(r'(?\1', b) + b = mathjaxusresub(b) + # Deal with +monospace+. r = re.compile(r'(?\1', b) @@ -715,6 +786,7 @@ def br(b, f, tableblock=False): # Deal with non-breaking space ~. r = re.compile(r"(?, < in LaTeX code with &, >, <. Is this necessary? r = re.compile(r"(?\n
  • ') - out(f.outf, '

    ' + br(s, f) + '

    ') + out(f.outf, '

    ' + mathjaxeqresub(br(s, f)) + '

    ') level = newlevel for i in range(level): @@ -1161,7 +1222,7 @@ def codeblock(f, g): if raw: return elif ext_prog: - print 'filtering through %s...' % ext_prog + print('filtering through %s...' % ext_prog) output,_ = Popen(ext_prog, shell=True, stdin=PIPE, stdout=PIPE).communicate(buff) @@ -1201,7 +1262,7 @@ def procfile(f): js = [] title = None while pc(f, False) == '#': - l = f.inf.readline() + l = f.inf.readline().decode('utf-8') f.linenum += 1 if doincludes(f, l[1:]): continue @@ -1365,7 +1426,9 @@ def procfile(f): s += l if l.strip() == '\)': break - out(f.outf, br(s.strip(), f)) + r = br(s.strip(), f) + r = mathjaxeqresub(r) + out(f.outf, r) # look for lists. elif p == '-': @@ -1514,7 +1577,7 @@ def main(): showhelp() raise SystemExit if sys.argv[1] == '--show-config': - print standardconf() + print(standardconf()) raise SystemExit if sys.argv[1] == '--version': info() @@ -1564,9 +1627,10 @@ def main(): else: thisout = outname - infile = open(inname, 'rUb') - outfile = open(thisout, 'w') + infile = io.open(inname, 'rb') + outfile = io.open(thisout, 'w') +# print(infile.read()) f = controlstruct(infile, outfile, conf, inname) procfile(f)