scholdoc (empty) → 0.1.3
raw patch · 148 files changed
+44504/−0 lines, 148 filesdep +Diffdep +HTTPdep +HUnitbuild-type:Customsetup-changedbinary-added
Dependencies added: Diff, HTTP, HUnit, JuicyPixels, QuickCheck, SHA, aeson, base, base64-bytestring, binary, blaze-html, blaze-markup, bytestring, containers, criterion, data-default, directory, executable-path, extensible-exceptions, filepath, highlighting-kate, hslua, http-client, http-client-tls, http-types, mtl, network, network-uri, old-locale, old-time, parsec, process, random, scholdoc, scholdoc-texmath, scholdoc-types, scientific, syb, tagsoup, temporary, test-framework, test-framework-hunit, test-framework-quickcheck2, text, time, unordered-containers, vector, wai, wai-extra, xml, yaml, zip-archive, zlib
Files
- BUGS +7/−0
- CHANGELOG-pandoc +7362/−0
- CHANGELOG.md +89/−0
- CONTRIBUTING.md +71/−0
- COPYING +346/−0
- COPYRIGHT +95/−0
- INSTALL.md +250/−0
- Makefile +47/−0
- README-pandoc +3191/−0
- README.md +74/−0
- Setup.hs +51/−0
- benchmark/benchmark-scholdoc.hs +57/−0
- data/LaTeXMathML.js +198/−0
- data/MathMLinHTML.js +70/−0
- data/dzslides/template.html +585/−0
- data/reference.docx binary
- data/sample.lua +314/−0
- data/templates/default.asciidoc +26/−0
- data/templates/default.beamer +177/−0
- data/templates/default.context +87/−0
- data/templates/default.docbook +32/−0
- data/templates/default.dokuwiki +13/−0
- data/templates/default.dzslides +123/−0
- data/templates/default.epub +50/−0
- data/templates/default.epub3 +56/−0
- data/templates/default.haddock +1/−0
- data/templates/default.html +61/−0
- data/templates/default.html5 +64/−0
- data/templates/default.icml +43/−0
- data/templates/default.latex +196/−0
- data/templates/default.man +18/−0
- data/templates/default.markdown +21/−0
- data/templates/default.mediawiki +13/−0
- data/templates/default.opendocument +30/−0
- data/templates/default.opml +11/−0
- data/templates/default.org +24/−0
- data/templates/default.plain +21/−0
- data/templates/default.revealjs +108/−0
- data/templates/default.rst +42/−0
- data/templates/default.rtf +30/−0
- data/templates/default.s5 +70/−0
- data/templates/default.slideous +79/−0
- data/templates/default.slidy +63/−0
- data/templates/default.texinfo +64/−0
- data/templates/default.textile +9/−0
- data/templates/scholmdTemplate.html5 +136/−0
- data/templates/scholmdTemplate.latex +307/−0
- data/templates/scholmdTemplate_bodyOnly.html5 +86/−0
- scholdoc.cabal +340/−0
- scholdoc.hs +1432/−0
- src/Text/Pandoc.hs +273/−0
- src/Text/Pandoc/Asciify.hs +422/−0
- src/Text/Pandoc/Compat/Directory.hs +21/−0
- src/Text/Pandoc/Compat/Except.hs +37/−0
- src/Text/Pandoc/Compat/Monoid.hs +20/−0
- src/Text/Pandoc/Compat/TagSoupEntity.hs +15/−0
- src/Text/Pandoc/Data.hsb +7/−0
- src/Text/Pandoc/Highlighting.hs +154/−0
- src/Text/Pandoc/ImageSize.hs +399/−0
- src/Text/Pandoc/MIME.hs +524/−0
- src/Text/Pandoc/MediaBag.hs +107/−0
- src/Text/Pandoc/Options.hs +419/−0
- src/Text/Pandoc/PDF.hs +208/−0
- src/Text/Pandoc/Parsing.hs +1309/−0
- src/Text/Pandoc/Pretty.hs +534/−0
- src/Text/Pandoc/Process.hs +104/−0
- src/Text/Pandoc/Readers/HTML.hs +965/−0
- src/Text/Pandoc/Readers/LaTeX.hs +1294/−0
- src/Text/Pandoc/Readers/Markdown.hs +2407/−0
- src/Text/Pandoc/Readers/Native.hs +76/−0
- src/Text/Pandoc/Readers/TeXMath.hs +48/−0
- src/Text/Pandoc/Scholarly.hs +283/−0
- src/Text/Pandoc/SelfContained.hs +139/−0
- src/Text/Pandoc/Shared.hs +913/−0
- src/Text/Pandoc/Slides.hs +63/−0
- src/Text/Pandoc/Templates.hs +328/−0
- src/Text/Pandoc/UTF8.hs +120/−0
- src/Text/Pandoc/UUID.hs +77/−0
- src/Text/Pandoc/Writers/Custom.hs +336/−0
- src/Text/Pandoc/Writers/Docx.hs +1025/−0
- src/Text/Pandoc/Writers/HTML.hs +1053/−0
- src/Text/Pandoc/Writers/Haddock.hs +351/−0
- src/Text/Pandoc/Writers/LaTeX.hs +1226/−0
- src/Text/Pandoc/Writers/Man.hs +370/−0
- src/Text/Pandoc/Writers/Markdown.hs +887/−0
- src/Text/Pandoc/Writers/Native.hs +78/−0
- src/Text/Pandoc/Writers/Shared.hs +165/−0
- src/Text/Pandoc/XML.hs +110/−0
- tests/Tests/Arbitrary.hs +193/−0
- tests/Tests/Helpers.hs +85/−0
- tests/Tests/Old.hs +193/−0
- tests/Tests/Readers/LaTeX.hs +177/−0
- tests/Tests/Readers/Markdown.hs +290/−0
- tests/Tests/Shared.hs +61/−0
- tests/Tests/Walk.hs +47/−0
- tests/Tests/Writers/HTML.hs +43/−0
- tests/Tests/Writers/LaTeX.hs +79/−0
- tests/Tests/Writers/Markdown.hs +38/−0
- tests/Tests/Writers/Native.hs +21/−0
- tests/Tests/Writers/Plain.hs +21/−0
- tests/bodybg.gif binary
- tests/insert +1/−0
- tests/lalune.jpg binary
- tests/lhs-test-markdown.native +8/−0
- tests/lhs-test.html +42/−0
- tests/lhs-test.html+lhs +42/−0
- tests/lhs-test.latex +100/−0
- tests/lhs-test.latex+lhs +79/−0
- tests/lhs-test.markdown +21/−0
- tests/lhs-test.markdown+lhs +19/−0
- tests/lhs-test.native +8/−0
- tests/markdown-citations.native +17/−0
- tests/markdown-citations.txt +39/−0
- tests/markdown-reader-more.native +154/−0
- tests/markdown-reader-more.txt +267/−0
- tests/movie.jpg binary
- tests/pipe-tables.native +78/−0
- tests/pipe-tables.txt +52/−0
- tests/s5-basic.html +54/−0
- tests/s5-fancy.html +255/−0
- tests/s5-fragment.html +9/−0
- tests/s5-inserts.html +34/−0
- tests/s5.native +8/−0
- tests/scholdoc.html +334/−0
- tests/scholdoc.latex +366/−0
- tests/scholdoc.native +87/−0
- tests/scholdoc.txt +330/−0
- tests/tables-rstsubset.native +117/−0
- tests/tables.haddock +77/−0
- tests/tables.html +204/−0
- tests/tables.latex +168/−0
- tests/tables.man +267/−0
- tests/tables.markdown +78/−0
- tests/tables.native +114/−0
- tests/tables.plain +78/−0
- tests/tables.txt +75/−0
- tests/test-scholdoc.hs +41/−0
- tests/testsuite.native +401/−0
- tests/testsuite.txt +730/−0
- tests/writer.haddock +660/−0
- tests/writer.html +557/−0
- tests/writer.latex +963/−0
- tests/writer.man +794/−0
- tests/writer.markdown +747/−0
- tests/writer.native +401/−0
- tests/writer.plain +696/−0
- tryscholdoc/index.html +96/−0
- tryscholdoc/tryscholdoc.hs +81/−0
@@ -0,0 +1,7 @@+Scholdoc is fork of Pandoc. While additional capabilities have been added to recognize and output ScholarlyMarkdown-specific features, Scholdoc strives to use most of Pandoc's original code. If you encounter a bug that is not related to features specific to ScholarlyMarkdown, please first check to see if it is already reported in Pandoc's issue tracker <https://github.com/jgm/pandoc/issues>, or on the official Pandoc discussion group <https://groups.google.com/forum/#!forum/pandoc-discuss>.++If you feel confident that a bug is directly related to ScholarlyMarkdown features, you can file a report in the Scholdoc issue tracker: <https://github.com/timtylin/scholdoc/issues>.++Any bugs that are also deemed to impact Pandoc itself will be referred to Pandoc's issue tracker. The official policy is to merge in the fixes only after it has been made in Pandoc.++See also CONTRIBUTING.md.
@@ -0,0 +1,7362 @@+pandoc (1.13.1)++ * Fixed `--self-contained` with Windows paths (#1558).+ Previously `C:\foo.js` was being wrongly interpreted as a URI.++ * HTML reader: improved handling of tags that can be block or inline.+ Previously a section like this would be enclosed in a paragraph,+ with RawInline for the video tags (since video is a tag that can+ be either block or inline):++ <video controls="controls">+ <source src="../videos/test.mp4" type="video/mp4" />+ <source src="../videos/test.webm" type="video/webm" />+ <p>+ The videos can not be played back on your system.<br/>+ Try viewing on Youtube (requires Internet connection):+ <a href="http://youtu.be/etE5urBps_w">Relative Velocity on+ Youtube</a>.+ </p>+ </video>++ This change will cause the video and source tags to be parsed+ as RawBlock instead, giving better output.+ The general change is this: when we're parsing a "plain" sequence+ of inlines, we don't parse anything that COULD be a block-level tag.++ * Docx reader:++ + Be sensitive to user styles. Note that "Hyperlink" is+ "blacklisted," as we don't want the default underline styling to be+ inherited by all links by default (Jesse Rosenthal).+ + Read single paragraph in table cell as `Plain` (Jesse Rosenthal).+ This makes to docx reader's native output fit with the way the markdown+ reader understands its markdown output.++ * Textile writer: Extended the range of cases where native textile+ tables will be used (as opposed to raw HTML): we now handle any+ alignment type, but only for simple tables with no captions.++ * Txt2Tags reader:++ + Header is now parsed only if standalone flag is set (Matthew Pickering).+ + The header is now parsed as meta information. The first line is the+ `title`, the second is the `author` and third line is the `date`+ (Matthew Pickering).+ + Corrected formatting of `%%mtime` macro (Matthew Pickering).+ + Fixed crash when reading from stdin.++ * EPUB writer: Don't use page-progression-direction in EPUB2, which+ doesn't support it. Also, if page-progression-direction not specified+ in metadata, don't include the attribute even in EPUB3; not including it+ is the same as including it with the value "default", as we did before.+ (#1550)++ * Org writer: Accept example lines with indentation at the beginning+ (Calvin Beck).++ * DokuWiki writer:++ + Refactor to use Reader monad (Matthew Pickering).+ + Avoid using raw HTML in table cells; instead, use `\\`+ instead of newlines (Jesse Rosenthal).+ + Properly handle HTML table cell alignments, and use spacing+ to make the tables look prettier (#1566).++ * Docx writer:++ + Bibliography entries get `Bibliography` style (#1559).+ + Implement change tracking (Jesse Rosenthal).++ * LaTeX writer:++ + Fixed a bug that caused a table caption to repeat across all pages+ (Jose Luis Duran).+ + Improved vertical spacing in tables and made it customizable using+ standard lengths set by booktab. See+ <https://groups.google.com/forum/#!msg/pandoc-discuss/qMu6_5lYy0o/ZAU7lzAIKw0J>+ (Jose Luis Duran).+ + Added `\strut` to fix spacing in multiline tables (Jose Luis Duran).+ + Use `\tabularnewline` instead of `\\` in table cells (Jose Luis Duran).+ + Made horizontal rules more flexible (Jose Luis Duran).++ * Text.Pandoc.MIME:++ + Added `MimeType` (type synonym for `String`) and `getMimeTypeDef`.+ Code cleanups (Artyom Kazak).++ * Templates:++ + LaTeX template: disable microtype protrusion for typewriter font (#1549,+ thanks lemzwerg).++ * Improved OSX build procedure.++ * Added `network-uri` flag, to deal with split of `network-uri` from+ `network`.++ * Fix build dependencies for the `trypandoc` flag, so that they are+ ignored if `trypandoc` flag is set to False (Gabor Pali).++ * Updated README to remove outdated claim that `--self-contained`+ looks in the user data directory for missing files.++pandoc (1.13.0.1)++ * Docx writer:++ + Fixed regression which bungled list numbering (#1544), causing+ all lists to appear as basic ordered lists.+ + Include row width in table rows (Christoffer Ackelman, Viktor Kronvall).+ Added a property to all table rows where the sum of column widths+ is specified in pct (fraction of 5000). This helps persuade Word+ to lay out the table with the widths we specify.++ * Fixed a bug in Windows 8 which caused pandoc not to find the+ `pandoc-citeproc` filter (#1542).++ * Docx reader: miscellaneous under-the-hood improvements (Jesse Rosenthal).+ Most significantly, the reader now uses Builder, leading to some+ performance improvements.++ * HTML reader: Parse appropriately styled span as SmallCaps.++ * Markdown writer: don't escape `$`, `^`, `~` when `tex_math_dollars`,+ `superscript`, and `subscript` extensions, respectively, are+ deactivated (#1127).++ * Added `trypandoc` flag to build CGI executable used in the online+ demo.++ * Makefile: Added 'quick', 'osxpkg' targets.++ * Updated README in templates to indicate templates license.+ The templates are dual-licensed, BSD3 and GPL2+.++pandoc (1.13)++ [new features]++ * Added `docx` as an input format (Jesse Rosenthal). The docx+ reader includes conversion of native Word equations to pandoc+ LaTeX `Math` elements. Metadata is taken from paragraphs at the+ beginning of the document with styles `Author`, `Title`, `Subtitle`,+ `Date`, and `Abstract`.++ * Added `epub` as an input format (Matthew Pickering). The epub+ reader includes conversion of MathML to pandoc LaTeX `Math`+ elements.++ * Added `t2t` (Txt2Tags) as an input format (Matthew Pickering).+ Txt2tags is a lightweight markup format described at+ <http://txt2tags.org/>.++ * Added `dokuwiki` as an output format (Clare Macrae).++ * Added `haddock` as an output format.++ * Added `--extract-media` option to extract media contained in a zip+ container (docx or epub) while adjusting image paths to point to the+ extracted images.++ * Added a new markdown extension, `compact_definition_lists`, that+ restores the syntax for definition lists of pandoc 1.12.x, allowing+ tight definition lists with no blank space between items, and+ disallowing lazy wrapping. (See below under behavior changes.)++ * Added an extension `epub_html_exts` for parsing HTML in EPUBs.++ * Added extensions `native_spans` and `native_divs` to activate+ parsing of material in HTML span or div tags as Pandoc Span+ inlines or Div blocks.++ * `--trace` now works with the Markdown, HTML, Haddock, EPUB,+ Textile, and MediaWiki readers. This is an option intended+ for debugging parsing problems; ordinary users should not need+ to use it.++ [behavior changes]++ * Changed behavior of the `markdown_attribute` extension, to bring+ it in line with PHP markdown extra and multimarkdown. Setting+ `markdown="1"` on an outer tag affects all contained tags,+ recursively, until it is reversed with `markdown="0"` (#1378).++ * Revised markdown definition list syntax (#1429). Both the reader+ and writer are affected. This change brings pandoc's definition list+ syntax into alignment with that used in PHP markdown extra and+ multimarkdown (with the exception that pandoc is more flexible about+ the definition markers, allowing tildes as well as colons). Lazily+ wrapped definitions are now allowed. Blank space is required+ between list items. The space before a definition is used to determine+ whether it is a paragraph or a "plain" element. **WARNING: This change+ may break existing documents!** Either check your documents for+ definition lists without blank space between items, or use+ `markdown+compact_definition_lists` for the old behavior.++ * `.numberLines` now works in fenced code blocks even if no language+ is given (#1287, jgm/highlighting-kate#40).++ * Improvements to `--filter`:++ + Don't search PATH for a filter with an explicit path.+ This fixed a bug wherein `--filter ./caps.py` would run `caps.py` from+ the system path, even if there was a `caps.py` in the working directory.+ + Respect shebang if filter is executable (#1389).+ + Don't print misleading error message.+ Previously pandoc would say that a filter was not found,+ even in a case where the filter had a syntax error.++ * HTML reader:++ + Parse `div` and `span` elements even without `--parse-raw`,+ provided `native_divs` and `native_spans` extensions are set.+ Motivation: these now generate native pandoc Div and Span+ elements, not raw HTML.+ + Parse EPUB-specific elements if the `epub_html_exts`+ extension is enabled. These include `switch`, `footnote`,+ `rearnote`, `noteref`.++ * Org reader:++ + Support for inline LaTeX. Inline LaTeX is now accepted and parsed by the+ org-mode reader. Both math symbols (like `\tau`) and LaTeX commands (like+ `\cite{Coffee}`), can be used without any further escaping (Albert+ Krewinkel).++ * Textile reader and writer:++ + The `raw_tex` extension is no longer set by default. You can+ enable it with `textile+raw_tex`.++ * DocBook reader:++ + Support `equation`, `informalequation`, `inlineequation` elements with+ `mml:math` content. This is converted into LaTeX and put into a Pandoc+ Math inline.++ * Revised `plain` output, largely following the style of Project+ Gutenberg:++ + Emphasis is rendered with `_underscores_`, strong emphasis+ with ALL CAPS.+ + Headings are rendered differently, with space to set them off,+ not with setext style underlines. Level 1 headers are ALL CAPS.+ + Math is rendered using unicode when possible, but without the+ distracting emphasis markers around variables.+ + Footnotes use a regular `[n]` style.++ * Markdown writer:++ + Horizontal rules are now a line across the whole page.+ + Prettier pipe tables. Columns are now aligned (#1323).+ + Respect the `raw_html` extension. `pandoc -t markdown-raw_html`+ no longer emits any raw HTML, including span and div tags+ generated by Span and Div elements.+ + Use span with style for `SmallCaps` (#1360).++ * HTML writer:++ + Autolinks now have class `uri`, and email autolinks have class+ `email`, so they can be styled.++ * Docx writer:++ + Document formatting is carried over from `reference.docx`.+ This includes margins, page size, page orientation, header,+ and footer, including images in headers and footers.+ + Include abstract (if present) with `Abstract` style (#1451).+ + Include subtitle (if present) with `Subtitle` style, rather+ than tacking it on to the title (#1451).++ * Org writer:++ + Write empty span elements with an id attribute as org anchors.+ For example `Span ("uid",[],[]) []` becomes `<<uid>>`.++ * LaTeX writer:++ + Put table captions above tables, to match the conventional+ standard. (Previously they appeared below tables.)+ + Use `\(..\)` instead of `$..$` for inline math (#1464).+ + Use `\nolinkurl` in email autolinks. This allows them to be styled+ using `\urlstyle{tt}`. Thanks to Ulrike Fischer for the solution.+ + Use `\textquotesingle` for `'` in inline code. Otherwise we get+ curly quotes in the PDF output (#1364).+ + Use `\footnote<.>{..}` for notes in beamer, so that footnotes+ do not appear before the overlays in which their markers appear+ (#1525).+ + Don't produce a `\label{..}` for a Div or Span element. Do produce+ a `\hyperdef{..}` (#1519).++ * EPUB writer:++ + If the metadata includes `page-progression-direction` (which can be+ `ltr` or `rtl`, the `page-progression-direction` attribute will+ be set in the EPUB spine (#1455).++ * Custom lua writers:++ + Custom writers now work with `--template`.+ + Removed HTML header scaffolding from `sample.lua`.+ + Made citation information available in lua writers.++ * `--normalize` and `Text.Pandoc.Shared.normalize` now consolidate+ adjacent `RawBlock`s when possible.++ [API changes]++ * Added `Text.Pandoc.Readers.Docx`, exporting `readDocx` (Jesse Rosenthal).++ * Added `Text.Pandoc.Readers.EPUB`, exporting `readEPUB` (Matthew+ Pickering).++ * Added `Text.Pandoc.Readers.Txt2Tags`, exporting `readTxt2Tags` (Matthew+ Pickering).++ * Added `Text.Pandoc.Writers.DokuWiki`, exporting `writeDokuWiki`+ (Clare Macrae).++ * Added `Text.Pandoc.Writers.Haddock`, exporting `writeHaddock`.++ * Added `Text.Pandoc.MediaBag`, exporting `MediaBag`, `lookupMedia`,+ `insertMedia`, `mediaDirectory`, `extractMediaBag`. The docx and epub+ readers return a pair of a `Pandoc` document and a `MediaBag` with+ the media resources they contain. This can be extracted using+ `--extract-media`. Writers that incorporate media (PDF, Docx,+ ODT, EPUB, RTF, or HTML formats with `--self-contained`) will look+ for resources in the `MediaBag` generated by the reader, in addition to+ the file system or web.++ * `Text.Pandoc.Readers.TexMath`: Removed deprecated `readTeXMath`.+ Renamed `readTeXMath'` to `texMathToInlines`.++ * `Text.Pandoc`: Added `Reader` data type (Matthew Pickering).+ `readers` now associates names of readers with `Reader`+ structures. This allows inclusion of readers, like the docx+ reader, that take binary rather than textual input.++ * `Text.Pandoc.Shared`:++ + Added `capitalize` (Artyom Kazak), and replaced uses of+ `map toUpper` (which give bad results for many languages).+ + Added `collapseFilePath`, which removes intermediate `.` and+ `..` from a path (Matthew Pickering).+ + Added `fetchItem'`, which works like `fetchItem` but searches+ a `MediaBag` before looking on the net or file system.+ + Added `withTempDir`.+ + Added `removeFormatting`.+ + Added `extractSpaces` (from HTML reader) and generalized its type+ so that it can be used by the docx reader (Matthew Pickering).+ + Added `ordNub`.+ + Added `normalizeInlines`, `normalizeBlocks`.+ + `normalize` is now `Pandoc -> Pandoc` instead of+ `Data a :: a -> a`. Some users may need to change their uses of+ `normalize` to the newly exported `normalizeInlines` or+ `normalizeBlocks`.++ * `Text.Pandoc.Options`:++ + Added `writerMediaBag` to `WriterOptions`.+ + Removed deprecated and no longer used `readerStrict` in+ `ReaderOptions`. This is handled by `readerExtensions` now.+ + Added `Ext_compact_definition_lists`.+ + Added `Ext_epub_html_exts`.+ + Added `Ext_native_divs` and `Ext_native_spans`.+ This allows users to turn off the default pandoc behavior of+ parsing contents of div and span tags in markdown and HTML+ as native pandoc Div blocks and Span inlines.++ * `Text.Pandoc.Parsing`:++ + Generalized `readWith` to `readWithM` (Matthew Pickering).+ + Export `runParserT` and `Stream` (Matthew Pickering).+ + Added `HasQuoteContext` type class (Matthew Pickering).+ + Generalized types of `mathInline`, `smartPunctuation`, `quoted`,+ `singleQuoted`, `doubleQuoted`, `failIfInQuoteContext`,+ `applyMacros` (Matthew Pickering).+ + Added custom `token` (Matthew Pickering).+ + Added `stateInHtmlBlock` to `ParserState`. This is used to keep+ track of the ending tag we're waiting for when we're parsing inside+ HTML block tags.+ + Added `stateMarkdownAttribute` to `ParserState`. This is used+ to keep track of whether the markdown attribute has been set in+ an enclosing tag.+ + Generalized type of `registerHeader`, using new type classes+ `HasReaderOptions`, `HasIdentifierList`, `HasHeaderMap` (Matthew+ Pickering). These allow certain common functions to be reused+ even in parsers that use custom state (instead of `ParserState`),+ such as the MediaWiki reader.+ + Moved `inlineMath`, `displayMath` from Markdown reader to Parsing,+ and generalized their types (Matthew Pickering).++ * `Text.Pandoc.Pretty`:++ + Added `nestle`.+ + Added `blanklines`, which guarantees a certain number of blank lines+ (and no more).++ [bug fixes]++ * Markdown reader:++ + Fixed parsing of indented code in list items. Indented code+ at the beginning of a list item must be indented eight spaces+ from the margin (or edge of the container), or four spaces+ from the list marker, whichever is greater.+ + Fixed small bug in HTML parsing with `markdown_attribute`, which+ caused incorrect tag nesting for input like+ `<aside markdown="1">*hi*</aside>`.+ + Fixed regression with intraword underscores (#1121).+ + Improved parsing of inline links containing quote characters (#1534).+ + Slight rewrite of `enclosure`/`emphOrStrong` code.+ + Revamped raw HTML block parsing in markdown (#1330).+ We no longer include trailing spaces and newlines in the+ raw blocks. We look for closing tags for elements (but without+ backtracking). Each block-level tag is its own `RawBlock`;+ we no longer try to consolidate them (though `--normalize` will do so).+ + Combine consecutive latex environments. This helps when you have+ two minipages which can't have blank lines between them (#690, #1196).+ + Support smallcaps through span.+ `<span style="font-variant:small-caps;">foo</span>` will be+ parsed as a `SmallCaps` inline, and will work in all output+ formats that support small caps (#1360).+ + Prevent spurious line breaks after list items (#1137). When the+ `hard_line_breaks` option was specified, pandoc would formerly+ produce a spurious line break after a tight list item.+ + Fixed table parsing bug (#1333).+ + Handle `c++` and `objective-c` as language identifiers in+ github-style fenced blocks (#1318).+ + Inline math must have nonspace before final `$` (#1313).++ * LaTeX reader:++ + Handle comments at the end of tables. This resolves the issue+ illustrated in <http://stackoverflow.com/questions/24009489>.+ + Correctly handle table rows with too few cells. LaTeX seems to+ treat them as if they have empty cells at the end (#241).+ + Handle leading/trailing spaces in `\emph` better.+ `\emph{ hi }` gets parsed as `[Space, Emph [Str "hi"], Space]`+ so that we don't get things like `* hi *` in markdown output.+ Also applies to `\textbf` and some other constructions (#1146).+ + Don't assume preamble doesn't contain environments (#1338).+ + Allow (and discard) optional argument for `\caption` (James Aspnes).++ * HTML reader:++ + Fixed major parsing problem with HTML tables. Table cells were+ being combined into one cell (#1341).+ + Fixed performance issue with malformed HTML tables.+ We let a `</table>` tag close an open `<tr>` or `<td>` (#1167).+ + Allow space between `<col>` and `</col>`.+ + Added `audio` and `source` in `eitherBlockOrInline`.+ + Moved `video`, `svg`, `progress`, `script`, `noscript`, `svg` from+ `blockTags` to `eitherBlockOrInline`.+ + `map` and `object` were mistakenly in both lists; they have been removed+ from `blockTags`.+ + Ignore `DOCTYPE` and `xml` declarations.++ * MediaWiki reader:++ + Don't parse backslash escapes inside `<source>` (#1445).+ + Tightened up template parsing.+ The opening `{{` must be followed by an alphanumeric or `:`.+ This prevents the exponential slowdown in #1033.+ + Support "Bild" for images.++ * DocBook reader:++ + Better handle elements inside code environments. Pandoc's document+ model does not allow structure inside code blocks, but at least this way+ we preserve the text (#1449).+ + Support `<?asciidoc-br?>` (#1236).++ * Textile reader:++ + Fixed list parsing. Lists can now start without an intervening+ blank line (#1513).+ + HTML block-level tags that do not start a line are parsed as+ inline HTML and do not interrupt paragraphs (as in RedCloth).++ * Org reader:++ + Make tildes create inline code (#1345). Also relabeled `code` and+ `verbatim` parsers to accord with the org-mode manual.+ + Respect `:exports` header argument in code blocks (Craig Bosma).+ + Fixed tight lists with sublists (#1437).++ * EPUB writer:++ + Avoid excess whitespace in `nav.xhtml`. This should improve+ TOC view in iBooks (#1392).+ + Fixed regression on cover image.+ In 1.12.4 and 1.12.4.2, the cover image would not appear properly,+ because the metadata id was not correct. Now we derive the id from the+ actual cover image filename, which we preserve rather than using+ "cover-image."+ + Keep newlines between block elements. This allows+ easier diff-ability (#1424).+ + Use `stringify` instead of custom `plainify`.+ + Use `renderTags'` for all tag rendering. This properly handles tags+ that should be self-closing. Previously `<hr/>` would appear in EPUB+ output as `<hr></hr>` (#1420).+ + Better handle HTML media tags.+ + Handle multiple dates with OPF `event` attributes. Note: in EPUB3 we+ can have only one dc:date, so only the first one is used.++ * LaTeX writer:++ + Correctly handle figures in notes. Notes can't contain figures in+ LaTeX, so we fake it to avoid an error (#1053).+ + Fixed strikeout + highlighted code (#1294).+ Previously strikeout highlighted code caused an error.++ * ConTeXt writer:++ + Improved detection of autolinks with URLs containing escapes.++ * RTF writer:++ + Improved image embedding: `fetchItem'` is now used to get the+ images, and calculated image sizes are indicated in the RTF.+ + Avoid extra paragraph tags in metadata (#1421).++ * HTML writer:++ + Deactivate "incremental" inside slide speaker notes (#1394).+ + Don't include empty items in the table of contents for+ slide shows. (These would result from creating a slide+ using a horizontal rule.)++ * MediaWiki writer:++ + Minor renaming of `st` prefixed names.++ * AsciiDoc writer:++ + Double up emphasis and strong emphasis markers in intraword+ contexts, as required by asciidoc (#1441).++ * Markdown writer:++ + Avoid wrapping that might start a list, blockquote, or header (#1013).+ + Use Span instead of (hackish) `SmallCaps` in `plainify`.+ + Don't use braced attributes for fenced code (#1416).+ If `Ext_fenced_code_attributes` is not set, the first class+ attribute will be printed after the opening fence as a bare word.+ + Separate adjacent lists of the same kind with an HTML comment (#1458).++ * PDF writer:++ + Fixed treatment of data uris for images (#1062).++ * Docx writer:++ + Use Compact style for empty table cells (#1353).+ Otherwise we get overly tall lines when there are empty+ table cells and the other cells are compact.+ + Create overrides per-image for `media/` in reference docx.+ This should be somewhat more robust and cover more types of images.+ + Improved `entryFromArchive` to avoid an unneeded parse.+ + Section numbering carries over from reference.docx (#1305).+ + Simplified `abstractNumId` numbering. Instead of sequential numbering,+ we assign numbers based on the list marker styles.++ * `Text.Pandoc.Options`:++ + Removed `Ext_fenced_code_attributes` from `markdown_github`+ extensions.++ * `Text.Pandoc.ImageSize`:++ + Use default instead of failing if image size not found+ in exif header (#1358).+ + ignore unknown exif header tag rather than crashing.+ Some images seem to have tag type of 256, which was causing+ a runtime error.++ * `Text.Pandoc.Shared`:++ + `fetchItem`: unescape URI encoding before reading local file (#1427).+ + `fetchItem`: strip a fragment like `?#iefix` from the extension before+ doing mime lookup, to improve mime type guessing.+ + Improved logic of `fetchItem`: absolute URIs are fetched from the net;+ other things are treated as relative URIs if `sourceURL` is `Just _`,+ otherwise as file paths on the local file system.+ + `fetchItem` now properly handles links without a protocol (#1477).+ + `fetchItem` now escapes characters not allowed in URIs before trying+ to parse the URIs.+ + Fixed runtime error with `compactify'DL` on certain lists (#1452).++ * `pandoc.hs`: Don't strip path off of `writerSourceURL`: the path is+ needed to resolve relative URLs when we fetch resources (#750).++ * `Text.Pandoc.Parsing`++ + Simplified `dash` and `ellipsis` (#1419).+ + Removed `(>>~)` in favor of the equivalent `(<*)` (Matthew Pickering).+ + Generalized functions to use `ParsecT` (Matthew Pickering).+ + Added `isbn` and `pmid` to list of recognized schemes (Matthew+ Pickering).++ [template changes]++ * Added haddock template.+ * EPUB3: Added `type` attribute to `link` tags. They are supposed to+ be "advisory" in HTML5, but kindlegen seems to require them.+ * EPUB3: Put title page in section with `epub:type="titlepage"`.+ * LaTeX: Made `\subtitle` work properly (#1327).+ * LaTeX/Beamer: remove conditional around date (#1321).+ * LaTeX: Added `lot` and `lof` variables, which can be set to+ get `\listoftables` and `\listoffigures` (#1407). Note that+ these variables can be set at the command line with `-Vlot -Vlof`+ or in YAML metadata.++ [under the hood improvements]++ * Rewrote normalize for efficiency (#1385).++ * Rewrote Haddock reader to use `haddock-library` (#1346).++ + This brings pandoc's rendering of haddock markup in line+ with the new haddock.+ + Fixed line breaks in `@` code blocks.+ + alex and happy are no longer build-depends.++ * Added `Text.Pandoc.Compat.Directory` to allow building against+ different versions of the `directory` library.++ + Added `Text.Pandoc.Compat.Except` to allow building against+ different verions of `mtl`.++ * Code cleanup in some writers, using Reader monad to avoid+ passing options parameter around (Matej Kollar).++ * Improved readability in `pandoc.hs`.++ * Miscellaneous code cleanups (Artyom Kazak).++ * Avoid `import Prelude hiding (catch)` (#1309, thanks to Michael+ Thompson).++ * Changed `http-conduit` flag to `https`. Depend on `http-client`+ and `http-client-tls` instead of `http-conduit`. (Note: pandoc still+ depends on `conduit` via `yaml`.)++ * Require `highlighting-kate >= 0.5.8.5` (#1271, #1317, Debian #753299).+ This change to highlighting-kate means that PHP fragments no longer need+ to start with `<?php`. It also fixes a serious bug causing failures with+ ocaml and fsharp.++ * Require latest `texmath`. This fixes `\tilde{E}` and allows+ `\left` to be used with `]`, `)` etc. (#1319), among many other+ improvements.++ * Require latest `zip-archive`. This has fixes for unicode path names.++ * Added tests for plain writer.++ * `Text.Pandoc.Templates`:++ + Fail informatively on template syntax errors.+ With the move from parsec to attoparsec, we lost good error+ reporting. In fact, since we weren't testing for end of input,+ malformed templates would fail silently. Here we revert back to+ Parsec for better error messages.+ + Use `ordNub` (#1022).++ * Benchmarks:++ + Made benchmarks compile again (Artyom Kazak).+ + Fixed so that the failure of one benchmark does not prevent others+ from running (Artyom Kazak).+ + Use `nfIO` instead of the `getLength` trick to force full evaluation.+ + Changed benchmark to use only the test suite, so that benchmarks+ run more quickly.++ * Windows build script:++ + Add `-windows` to file name.+ + Use one install command for pandoc, pandoc-citeproc.+ + Force install of pandoc-citeproc.++ * `make_osx_package`: Call zip file `pandoc-VERSION-osx.zip`.+ The zip should not be named `SOMETHING.pkg.zip`, or OSX finder+ will extract it into a folder named `SOMETHING.pkg`, which it+ will interpret as a defective package (#1308).++ * `README`:++ + Made headers for all extensions so they have IDs and can be+ linked to (Beni Cherniavsky-Paskin).+ + Fixed typos (Phillip Alday).+ + Fixed documentation of attributes (#1315).+ + Clarified documentation on small caps (#1360).+ + Better documentation for `fenced_code_attributes` extension+ (Caleb McDaniel).+ + Documented fact that you can put YAML metadata in a separate file+ (#1412).+++pandoc (1.12.4.2)++ * Require highlighting-kate >= 0.5.8. Fixes a performance regression.++ * Shared: `addMetaValue` now behaves slightly differently:+ if both the new and old values are lists, it concatenates their+ contents to form a new list.++ * LaTeX reader:++ + Set `bibliography` in metadata from `\bibliography` or+ `\addbibresource` command.+ + Don't error on `%foo` with no trailing newline.++ * Org reader:++ + Support code block headers (`#+BEGIN_SRC ...`) (Albert Krewinkel).+ + Fix parsing of blank lines within blocks (Albert Krewinkel).+ + Support pandoc citation extension (Albert Krewinkel). This can+ be turned off by specifying `org-citations` as the input format.++ * Markdown reader:++ + `citeKey` moved to `Text.Pandoc.Parsing` so it can be used by+ other readers (Albert Krewinkel).++ * `Text.Pandoc.Parsing`:++ + Added `citeKey` (see above).+ + Added `HasLastStrPosition` type class and `updateLastStrPos`+ and `notAfterString` functions.++ * Updated copyright notices (Albert Krewinkel).++ * Added default.icml to data files so it installs with the package.++ * OSX package:++ + The binary is now built with options to ensure that it can be+ used with OSX 10.6+.+ + Moved OSX package materials to osx directory.+ + Added OSX package uninstall script, included in the zip container+ (thanks to Daniel T. Staal).++pandoc (1.12.4)++ * Made it possible to run filters that aren't executable (#1096).+ Pandoc first tries to find the executable (searching the path+ if path isn't given). If it fails, but the file exists and has+ a `.py`, `.pl`, `.rb`, `.hs`, or `.php` extension, pandoc runs the filter+ using the appropriate interpreter. This should make it easier to+ use filters on Windows, and make it more convenient for everyone.++ * Added Emacs org-mode reader (Albert Krewinkel).++ * Added InDesign ICML Writer (mb21).++ * MediaWiki reader:++ + Accept image links in more languages (Jaime Marquínez Ferrándiz).+ + Fixed bug in certain nested lists (#1213). If a level 2 list was+ followed by a level 1 list, the first item of the level 1 list+ would be lost.+ + Handle table rows containing just an HTML comment (#1230).++ * LaTeX reader:++ + Give better location information on errors, pointing to line+ numbers within included files (#1274).+ + LaTeX reader: Better handling of `table` environment (#1204).+ Positioning options no longer rendered verbatim.+ + Better handling of figure and table with caption (#1204).+ + Handle `@{}` and `p{length}` in tabular. The length is not actually+ recorded, but at least we get a table (#1180).+ + Properly handle `\nocite`. It now adds a `nocite` metadata+ field. Citations there will appear in the bibliography but not+ in the text (unless you explicitly put a `$nocite$` variable+ in your template).++ * Markdown reader:++ + Ensure that whole numbers in YAML metadata are rendered without+ decimal points. (This became necessary with changes to aeson+ and yaml libraries. aeson >= 0.7 and yaml >= 0.8.8.2 are now required.)+ + Fixed regression on line breaks in strict mode (#1203).+ + Small efficiency improvements.+ + Improved parsing of nested `div`s. Formerly a closing `div` tag+ would be missed if it came right after other block-level tags.+ + Avoid backtracking when closing `</div>` not found.+ + Fixed bug in reference link parsing in `markdown_mmd`.+ + Fixed a bug in list parsing (#1154). When reading a raw list+ item, we now strip off up to 4 spaces.+ + Fixed parsing of empty reference link definitions (#1186).+ + Made one-column pipe tables work (#1218).++ * Textile reader:++ + Better support for attributes. Instead of being ignored, attributes+ are now parsed and included in Span inlines. The output will be a bit+ different from stock textile: e.g. for `*(foo)hi*`, we'll get+ `<em><span class="foo">hi</span></em>` instead of+ `<em class="foo">hi</em>`. But at least the data is not lost.+ + Improved treatment of HTML spans (%) (#1115).+ + Improved link parsing. In particular we now pick up on attributes.+ Since pandoc links can't have attributes, we enclose the whole link in+ a span if there are attributes (#1008).+ + Implemented correct parsing rules for inline markup (#1175, Matthew+ Pickering).+ + Use Builder (Matthew Pickering).+ + Fixed list parsing bug (#1500).+ + Don't allow inline formatting to extend over newlines.+ This matches the behavior of RedCarpet, avoids some ugly bugs,+ and improves performance.++ * DocBook reader:++ + Better treatment of `formalpara`. We now emit the title (if present)+ as a separate paragraph with boldface text (#1215).+ + Set metadata `author` not `authors`.+ + Added recognition of `authorgroup` and `releaseinfo` elements (#1214,+ Matthew Pickering).+ + Converted current meta information parsing in DocBook to a more+ extensible version which is aware of the more recent meta+ representation (Matthew Pickering).++ * HTML reader:++ + Require tagsoup 0.13.1, to fix a bug with parsing of script tags+ (#1248).+ + Treat processing instructions & declarations as block. Previously+ these were treated as inline, and included in paragraph tags in HTML+ or DocBook output, which is generally not what is wanted (#1233).+ + Updated `closes` with rules from HTML5 spec.+ + Use Builder (Matthew Pickering, #1162).++ * RST reader:++ + Remove duplicate `http` in PEP links (Albert Krewinkel).+ + Make rst figures true figures (#1168, CasperVector)+ + Enhanced Pandoc's support for rST roles (Merijn Verstaaten).+ rST parser now supports: all built-in rST roles, new role definition,+ role inheritance, though with some limitations.+ + Use `author` rather than `authors` in metadata.+ + Better handling of directives. We now correctly handle field+ lists that are indented more than three spaces. We treat an+ `aafig` directive as a code block with attributes, so it can be+ processed in a filter (#1212).++ * LaTeX writer:++ + Mark span contents with label if span has an ID (Albert Krewinkel).+ + Made `--toc-depth` work well with books in latex/pdf output (#1210).+ + Handle line breaks in simple table cells (#1217).+ + Workaround for level 4-5 headers in quotes. These previously produced+ invalid LaTeX: `\paragraph` or `\subparagraph` in a `quote` environment.+ This adds an `mbox{}` in these contexts to work around the problem.+ See <http://tex.stackexchange.com/a/169833/22451> (#1221).+ + Use `\/` to avoid en-dash ligature instead of `-{}-` (Vaclav Zeman).+ This is to fix LuaLaTeX output. The `-{}-` sequence does not avoid the+ ligature with LuaLaTeX but `\/` does.+ + Fixed string escaping in `hyperref` and `hyperdef` (#1130).++ * ConTeXt writer: Improved autolinks (#1270).++ * DocBook writer:++ + Improve handling of hard line breaks in Docbook writer+ (Neil Mayhew). Use a `<literallayout>` for the entire paragraph, not+ just for the newline character.+ + Don't let line breaks inside footnotes influence the enclosing+ paragraph (Neil Mayhew).+ + Distinguish tight and loose lists in DocBook output, using+ `spacing="compact"` (Neil Mayhew, #1250).++ * Docx writer: When needed files are not present in the user's+ `reference.docx`, fall back on the versions in the `reference.docx`+ in pandoc's data files. This fixes a bug that occurs when a+ `reference.docx` saved by LibreOffice is used. (#1185)++ * EPUB writer:++ + Include extension in epub ids. This fixes a problem with duplicate+ extensions for fonts and images with the same base name but different+ extensions (#1254).+ + Handle files linked in raw `img` tags (#1170).+ + Handle media in `audio` source tags (#1170).+ Note that we now use a `media` directory rather than `images`.+ + Incorporate files linked in `video` tags (#1170). `src` and `poster`+ will both be incorporated into `content.opf` and the epub container.++ * HTML writer:++ + Add colgroup around col tags (#877). Also affects EPUB writer.+ + Fixed bug with unnumbered section headings. Unnumbered section+ headings (with class `unnumbered`) were getting numbers.+ + Improved detection of image links. Previously image links with+ queries were not recognized, causing `<embed>` to be used instead+ of `<img>`.++ * Man writer: Ensure that terms in definition lists aren't line wrapped+ (#1195).++ * Markdown writer:++ + Use proper escapes to avoid unwanted lists (#980). Previously we used+ 0-width spaces, an ugly hack.+ + Use longer backtick fences if needed (#1206). If the content contains a+ backtick fence and there are attributes, make sure longer fences are+ used to delimit the code. Note: This works well in pandoc, but github+ markdown is more limited, and will interpret the first string of three+ or more backticks as ending the code block.++ * RST writer: Avoid stack overflow with certain tables (#1197).++ * RTF writer: Fixed table cells containing paragraphs.++ * Custom writer:++ + Correctly handle UTF-8 in custom lua scripts (#1189).+ + Fix bugs with lua scripts with mixed-case filenames and+ paths containing `+` or `-` (#1267). Note that `getWriter`+ in `Text.Pandoc` no longer returns a custom writer on input+ `foo.lua`.++ * AsciiDoc writer: Handle multiblock and empty table cells+ (#1245, #1246). Added tests.++ * `Text.Pandoc.Options`: Added `readerTrace` to `ReaderOptions`++ * `Text.Pandoc.Shared`:++ + Added `compactify'DL` (formerly in markdown reader) (Albert Krewinkel).+ + Fixed bug in `toRomanNumeral`: numbers ending with '9' would+ be rendered as Roman numerals ending with 'IXIV' (#1249). Thanks to+ Jesse Rosenthal.+ + `openURL`: set proxy with value of http_proxy env variable (#1211).+ Note: proxies with non-root paths are not supported, due to+ limitations in `http-conduit`.++ * `Text.Pandoc.PDF`:++ + Ensure that temp directories deleted on Windows (#1192). The PDF is+ now read as a strict bytestring, ensuring that process ownership will+ be terminated, so the temp directory can be deleted.+ + Use `/` as path separators in a few places, even on Windows.+ This seems to be necessary for texlive (#1151, thanks to Tim Lin).+ + Use `;` for `TEXINPUTS` separator on Windows (#1151).+ + Changes to error reporting, to handle non-UTF8 error output.++ * `Text.Pandoc.Templates`:++ + Removed unneeded datatype context (Merijn Verstraaten).++ + YAML objects resolve to "true" in conditionals (#1133).+ Note: If `address` is a YAML object and you just have `$address$`+ in your template, the word `true` will appear, which may be+ unexpected. (Previously nothing would appear.)++ * `Text.Pandoc.SelfContained`:++ + `mkSelfContained` now takes just two arguments, `WriterOptions` and+ the string.+ * It no longer looks in data files. This only made sense when we+ had copies of slidy and S5 code there.+ * `fetchItem'` is used instead of the nearly duplicate `getItem`.+ + Handle `poster` attribute in `video` tags (#1188).++ * `Text.Pandoc.Parsing`:++ + Made `F` an instance of Applicative (#1138).+ + Added `stateCaption`.+ + Added `HasMacros`, simplified other typeclasses.+ Removed `updateHeaderMap`, `setHeaderMap`, `getHeaderMap`,+ `updateIdentifierList`, `setIdentifierList`, `getIdentifierList`.+ + Changed the smart punctuation parser to return `Inlines`+ rather than `Inline` (Matthew Pickering).+ + Changed `HasReaderOptions`, `HasHeaderMap`, `HasIdentifierList`+ from typeclasses of monads to typeclasses of states. This simplifies+ the instance definitions and provides more flexibility. Generalized+ type of `getOption` and added a default definition. Removed+ `askReaderOption`. Added `extractReaderOption`. Added+ `extractHeaderMap` and `updateHeaderMap` in `HasHeaderMap`.+ Gave default definitions for `getHeaderMap`, `putHeaderMap`,+ `modifyHeaderMap`. Added `extractIdentifierList` and+ `updateIdentifierList` in `HasIdentifierList`. Gave defaults+ for `getIdentifierList`, `putIdentifierList`, and+ `modifyIdentifierList`. The ultimate goal here is to allow different+ parsers to use their own, tailored parser states (instead of+ `ParserState`) while still using shared functions.++ * Template changes:++ + LaTeX template: Use `fontenc` package only with `pdflatex` (#1164).+ + LaTeX template: Add `linestretch` and `fontfamily` variables.+ + LaTeX template: Conditionalize author and date commands.+ + Beamer template: Consistent styles for figure and table captions+ (aaronwolen).+ + LaTeX and beamer template: Adjust widths correctly for oversized+ images. Use `\setkeys{Gin}{}` to set appropriate defaults for+ `\includegraphics` (Yihui Xie, Garrick Aden-Buie). Load+ `upquote` only after `fontenc` (Yihui Xie).+ + Beamer template: Added caption package (#1200).+ + Beamer template: changes for better unicode handling (KarolS).+ + DocBook template: use `authorgroup` if there are authors.+ + revealjs template: Move `include-after` to end (certainlyakey).+ + revealjs template: Fixed PDF print function (#1220, kevinkenan).++ * Bumped version bounds of dependencies.++ * Added a `--trace` command line option, for debugging backtracking+ bugs. So far this only works with the markdown reader.++ * MathMLinHTML: Fixed deprecation warning (#362, gwern, Albert Krewinkel).++ * Updated travis script to test with multiple GHC versions.++ * Force failure of a Travis build if GHC produces warnings (Albert+ Krewinkel).++ * Add `.editorconfig` (Albert Krewinkel).+ See <http://editorconfig.org/> for details.++ * Give more useful error message if '-t pdf' is specified (#1155).++ * Added `Cite`, `SmallCaps` to `Arbitrary` instance (#1269).++ * Allow `html4` as a synonym of `html` as a reader (it already works+ as a writer).++ * README:++ + Added an explanation of how to use YAML metadata to+ force items to appear in the bibliography without citations in+ the text (like LaTeX `\nocite`).+ + Added note to `--bibtex/--natbib`: not for use in making PDF+ (#1194, thanks to nahoj).+ + Added explanatory notes about `--natbib` and `--biblatex`.+ + Added specification of legal syntax for citation keys.+ + Fixed variable defaults documentation (Albert Krewinkel).++ * Removed copyright statements for files that have been removed+ (Albert Krewinkel).++ * Moved some doc files from `data-files` to `extra-source-files` (#1123).+ They aren't needed at runtime. We keep README and COPYRIGHT in data+ to ensure that they'll be available on all systems on which pandoc+ is installed.++ * Use cabal sandboxes in Windows build script.++pandoc (1.12.3.3)++ * To changes to source; recompiled tarball with latest alex and+ happy, so they will work with GHC 7.8.++pandoc (1.12.3.2)++ * Bumped version bounds for blaze-html, blaze-markup.++ * ImageSize: Avoid use of lookAhead, which is not in binary >= 0.6+ (#1124).++ * Fixed mediawiki ordered list parsing (#1122).++ * HTML reader: Fixed bug reading inline math with `$$` (#225).++ * Added support for LaTeX style literate Haskell code blocks in rST+ (Merijn Verstraaten).++pandoc (1.12.3.1)++ * Relaxed version constraint on binary, allowing the use of binary 0.5.++pandoc (1.12.3)++ * The `--bibliography` option now sets the `biblio-files` variable.+ So, if you're using `--natbib` or `--biblatex`, you can just use+ `--bibliography=foo.bib` instead of `-V bibliofiles=foo`.++ * Don't run pandoc-citeproc filter if `--bibliography` is+ used together with `--natbib` or `--biblatex` (Florian Eitel).++ * Template changes:++ + Updated beamer template to include booktabs.+ + Added `abstract` variable to LaTeX template.+ + Put `header-includes` after `title` in LaTeX template (#908).+ + Allow use of `\includegraphics[size]` in beamer.+ This just required porting a macro definition from the default+ LaTeX template to the default beamer template.++ * `reference.docx`: Include `FootnoteText` style.+ Otherwise Word ignores the style, even when specified in the `pPr`.+ (#901)++ * `reference.odt`: Tidied `styles.xml`.++ * Relaxed version bounds for dependencies.++ * Added `withSocketsDo` around http conduit code in `openURL`,+ so it works on Windows (#1080).++ * Added `Cite` function to `sample.lua`.++ * Markdown reader:++ + Fixed regression in title blocks (#1089).+ If author field was empty, date was being ignored.+ + Allow backslash-newline hard line breaks in grid and+ multiline table cells.+ + Citation keys may now start with underscores, and may contain+ underscores adjacent to internal punctuation.++ * LaTeX reader:++ + Add support for `Verb` macro (jrnold) (#1090).+ + Support babel-style quoting: `` "`..."' ``.++ * Properly handle script blocks in strict mode. (That is,+ `markdown-markdown_in_html_blocks`.) Previously a spurious+ `<p>` tag was being added (#1093).++ * Docbook reader: Avoid failure if `tbody` contains no `tr` or `row`+ elements.++ * LaTeX writer:++ + Factored out function for table cell creation.+ + Better treatment of footnotes in tables.+ Notes now appear in the regular sequence, rather than in the+ table cell. (This was a regression in 1.10.)++ * HTML reader: Parse name/content pairs from meta tags as metadata.+ Closes #1106.++ * Moved `fixDisplayMath` from Docx writer to `Writer.Shared`.++ * OpenDocument writer: Fixed `RawInline`, `RawBlock` so they don't escape.++ * ODT writer: Use mathml for proper rendering of formulas.+ Note: LibreOffice's support for this seems a bit buggy. But+ it should be better than what we had before.++ * RST writer: Ensure no blank line after def in definition list (#992).++ * Markdown writer: Don't use tilde code blocks with braced attributes in+ `markdown_github` output. A consequence of this change is that the+ backtick form will be preferred in general if both are enabled. That+ is good, as it is much more widespread than the tilde form. (#1084)++ * Docx writer: Fixed problem with some modified reference docx files.+ Include `word/_rels/settings.xml.rels` if it exists, as well as other+ `rels` files besides the ones pandoc generates explicitly.++ * HTML writer:++ + With `--toc`, headers no longer link to themselves (#1081).+ + Omit footnotes from TOC entries. Otherwise we get doubled+ footnotes when headers have notes!++ * EPUB writer:++ + Avoid duplicate notes when headings contain notes.+ This arose because the headings are copied into the metadata+ "title" field, and the note gets rendered twice. We strip the+ note now before putting the heading in "title".+ + Strip out footnotes from toc entries.+ + Fixed bug with `--epub-stylesheet`. Now the contents of+ `writerEpubStylesheet` (set by `--epub-stylesheet`)+ should again work, and take precedence over a stylesheet specified+ in the metadata.++ * `Text.Pandoc.MIME`: Added `wmf`, `emf`.++ * `Text.Pandoc.Shared`: `fetchItem` now handles image URLs beginning+ with `//`.++ * `Text.Pandoc.ImageSize`: Parse EXIF format JPEGs. Previously+ we could only get size information for JFIF format, which led+ to squished images in Word documents. Closes #976.++ * Removed old `MarkdownTest_1.0.3` directory (#1104).++pandoc (1.12.2.1)++ * Markdown reader: Fixed regression in list parser, involving+ continuation lines containing raw HTML (or even verbatim raw HTML).++pandoc (1.12.2)++ * Metadata may now be included in YAML blocks in a markdown document.+ For example,++ ---+ title:+ - type: main+ text: My Book+ - type: subtitle+ text: An investigation of metadata+ creator:+ - role: author+ text: John Smith+ - role: editor+ text: Sarah Jones+ identifier:+ - scheme: DOI+ text: doi:10.234234.234/33+ publisher: My Press+ rights: (c) 2007 John Smith, CC BY-NC+ cover-image: img/mypic.jpg+ ...++ Metadata may still be provided using `--epub-metadata`; it will+ be merged with the metadata in YAML blocks.++ * EPUB writer:++ + `meta` tags are now used instead of `opf` attributes for EPUB3.+ + Insert "svg" property as needed in opf (EPUB 3).+ + Simplify `imageTypeOf` using `getMimeType`.+ + Add properties attribute to `cover-image` item for EPUB 3.+ + Don't include node for `cover.xhtml` if no cover!+ + Ensure that same identifier is used throughout (#1044).+ If an identifier is given in metadata, we use that; otherwise+ we generate a random uuid.+ + Add cover reference to guide element (EPUB 2) (Shaun Attfield).+ Fixes an issue with Calibre putting the cover at the end of the book+ if the spine has `linear="no"`. Apparently this is best practice+ for other converters as well:+ <http://www.idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.6>.+ + Allow `stylesheet` in metadata. The value is a path to the stylesheet.+ + Allow partial dates: `YYYY`, `YYYY-MM`.++ * Markdown writer: Fix rendering of tight sublists (#1050).+ Previously a spurious blank line was included after a tight sublist.++ * ODT writer: Add `draw:name` attribute to `draw:frame` elements (#1069).+ This is reported to be necessary to avoid an error from recent+ versions of Libre Office when files contain more than one image+ Thanks to wmanley for reporting and diagnosing the problem.++ * ConTeXt writer: Don't hardcode figure/table placement and numbering.+ Instead, let this be set in the template, using `\setupfloat`.+ Thanks to on4aa and Aditya Mahajan for the suggestion (#1067).++ * Implemented CSL flipflopping spans in DOCX, LaTeX, and HTML writers.++ * Fixed bug with markdown intraword emphasis. Closes #1066.++ * Docbook writer: Hierarchicalize block content in metadata.+ Previously headers just disappeared from block-level metadata+ when it was used in templates. Now we apply the 'hierarchicalize'+ transformation. Note that a block headed by a level-2 header will+ turn into a `<sect1>` element.++ * OpenDocument writer: Skip raw HTML (#1035).+ Previously it was erroneously included as verbatim text.++ * HTML/EPUB writer, footnotes: Put `<sup>` tag inside `<a>` tags.+ This allows better control of formatting, since the `<a>`+ tags have a distinguishing class (#1049).++ * Docx writer:++ + Use mime type info returned by fetchItem.+ + Fixed core metadata (#1046).+ Don't create empty date nodes if no date given.+ Don't create multiple `dc:creator` nodes; instead separate by+ semicolons.+ + Fix URL for core-properties in `_rels/.rels` (#1046).++ * Plain writer: don't print `<span>` tags.++ * LaTeX writer:++ + Fix definition lists with internal links in terms (#1032).+ This fix puts braces around a term that contains an internal+ link, to avoid problems with square brackets.+ + Properly escape pdftitle, pdfauthor (#1059).+ + Use booktabs package for tables (thanks to Jose Luis Duran).++ * Updated beamer template. Now references should work properly+ (in a slide) when `--biblatex` or `--natbib` is used.++ * LaTeX reader:++ + Parse contents of curly quotes or matched `"` as quotes.+ + Support `\textnormal` as span with class `nodecor`.+ This is needed for pandoc-citeproc.+ + Improved citation parsing. This fixes a run-time error that occured+ with `\citet{}` (empty list of keys). It also ensures that empty keys+ don't get produced.++ * MediaWiki reader: Add automatic header identifiers.++ * HTML reader:++ + Use pandoc `Div` and `Span` for raw `<div>`, `<span>` when+ `--parse-raw`.+ + Recognize `svg` tags as block level content (thanks to MinRK).+ + Parse LaTeX math if appropriate options are set.++ * Markdown reader:++ + Yaml block must start immediately after `---`. If there's a blank+ line after `---`, we interpreted it as a horizontal rule.+ + Correctly handle empty bullet list items.+ + Stop parsing "list lines" when we hit a block tag.+ This fixes exponential slowdown in certain input, e.g.+ a series of lists followed by `</div>`.++ * Slides: Preserve `<div class="references">` in references slide.++ * `Text.Pandoc.Writer.Shared`:++ + Fixed bug in `tagWithAttrs`. A space was omitted before key-value+ attributes, leading to invalid HTML.+ + `normalizeDate`: Allow dates with year only (thanks to Shaun Attfield).+ + Fixed bug in `openURL` with `data:` URIs. Previously the base-64+ encoded bytestring was returned. We now decode it so it's a proper+ image!++ * DocBook reader: Handle numerical attributes starting with decimal.+ Also use `safeRead` instead of `read`.++ * `Text.Pandoc.Readers.TexMath`: Export `readTeXMath'`, which attends+ to display/inline. Deprecate `readTeXMath`, and use `readTeXMath'`+ in all the writers. Require `texmath >= 0.6.5.2`.++ * `Text.Pandoc.MIME`:++ + Add entry for `jfif`.+ + In looking up extensions, drop the encoding info.+ E.g. for 'image/jpg;base64' we should lookup 'image/jpg'.++ * Templates: Changed how array variables are resolved. Previously if+ `foo` is an array (which might be because multiple values were set on+ the command line), `$foo$` would resolve to the concatenation of the+ elements of foo. This is rarely useful behavior. It has been changed+ so that the first value is rendered. Of course, you can still iterate+ over the values using `$for(foo)$`. This has the result that you can+ override earlier settings using `-V` by putting new values later on the+ command line, which is useful for many purposes.++ * `Text.Pandoc`: Don't default to `pandocExtensions` for all writers.++ * Allow "epub2" as synonym for "epub", "html4" for "html".++ * Don't look for slidy files in data files with `--self-contained`.++ * Allow `https:` command line arguments to be downloaded.++ * Fixed `make_osx_package.sh` so data files embedded in `pandoc-citeproc`.++pandoc (1.12.1)++ * `Text.Pandoc.Definition`: Changed default JSON serialization format.+ Instead of `{"Str": "foo"}`, for example, we now have `{"t": "Str",+ "c": "foo"}`. This new format is easier to work with outside of Haskell.+ Incidentally, "t" stands for "tag", "c" for "contents".++ * MediaWiki reader: Trim contents of `<math>` tags, to avoid problems+ when converting to markdown (#1027).++ * LaTeX reader:++ + Ensure that preamble doesn't contribute to the text of+ the document.+ + Fixed character escaping in \url{}. Previously `\~` wasn't handled+ properly, among others.+ + Parse `{groups}` as `Span`. This is needed for accurate conversion of+ bibtex titles, since we need to know what was protected from+ titlecase conversions.++ * LaTeX writer:++ + Specially escape non-ascii characters in labels.+ Otherwise we can get compile errors and other bugs when+ compiled with pdflatex (#1007). Thanks to begemotv2718 for the fix.+ + Add link anchors for code blocks with identifiers (#1025).++ * Throughout the code, use `isURI` instead of `isAbsoluteURI`.+ It allows fragments identifiers.++ * Slide formats:++ + A Div element with class "notes" is treated as speaker+ notes. Currently beamer goes to `\note{}`, revealjs to+ `<aside class="notes">`, and the notes are simply suppressed in+ other formats (#925).+ + Fixed `. . .` (pause) on HTML slide formats. Closes #1029.+ The old version caused a pause to be inserted before the first+ material on a slide. This has been fixed.+ + Removed data files for s5, slideous, slidy.+ Users of s5 and slideous will have to download the needed+ files, as has been documented for some time in the README.+ By default, slidy code will be sought on the web, as before.++ * HTML writer: Insert command to typeset mathjax only in slideous output+ (#966, #1012).++ * RST writer: Skip spaces after display math. Otherwise we get indentation+ problems, and part of the next paragraph may be rendered as part of the+ math.++ * OpenDocument writer: Fix formatting of strikeout code (#995),+ thanks to wilx. don't use `font-face-decls` variable.++ * Fixed test suite so it works with cabal sandboxes.++pandoc (1.12.0.2)++ * Removed `stringable` dependency.++pandoc (1.12.0.1)++ * Allow `--metadata` to be repeated for the same key to form a list.+ This also has the effect that `--bibliography` can be repeated,+ as before.++ * Handle boolean values in `--metadata`. Note that anything not parseable+ as a YAML boolean or string is treated as a literal string.+ You can get a string value with "yes", or any of the strings interpretable+ as booleans, by quoting it:++ -M boolvalue=yes -M stringvalue='"yes"'++ * LaTeX writer: Don't print references if `--natbib` or `--biblatex`+ option used.++ * DOCX writer: Add `settings.xml` to the zip container. Fixes a bug+ in which docx files could not be read by some versions of Word+ and LibreOffice (#990).++ * Fixed a regression involving slide shows with bibliographies.+ The Div container around references messed up the procedure for carving+ a document into slides. So we now remove the surrounding Div in+ `prepSlides`.++ * More informative error message when a filter is not found in path.++ * Depend on pandoc-types 1.12.1. This provide `ToJSONFilter`+ instances for `Data a => a -> [a]` and `Data a => a -> IO [a]`.++ * Don't use unicode_collation in building OSX package:+ it adds something like 50MB of dependencies to the package.++ * Declare alex and happy as build-tools (#986).++pandoc (1.12)++ [new features]++ * Much more flexible metadata, including arbitrary fields and structured+ values. Metadata can be specified flexibly in pandoc markdown using+ YAML metadata blocks, which may occur anywhere in the document:++ ---+ title: Here is my title.+ abstract: |+ This is the abstract.++ 1. It can contain+ 2. block content+ and *inline markup*++ tags: [cat, dog, animal]+ ...++ Metadata fields automatically populate template variables.++ * Added `opml` (OPML) as input and output format. The `_note` attribute,+ used in OmniOutliner and supported by multimarkdown, is supported.+ We treat the contents as markdown blocks under a section header.++ * Added `haddock` (Haddock markup) as input format (David Lazar).++ * Added `revealjs` output format, for reveal.js HTML 5 slide shows.+ (Thanks to Jamie F. Olson for the initial patch.)+ Nested vertical stacks are used for hierarchical structure.+ Results for more than one level of nesting may be odd.++ * Custom writers can now be written in lua.++ pandoc -t data/sample.lua++ will load the script sample.lua and use it as a custom writer.+ (For a sample, do `pandoc --print-default-data-file sample.lua`.)+ Note that pandoc embeds a lua interpreter, so lua need not be+ installed separately.++ * New `--filter/-F` option to make it easier to run "filters"+ (Pandoc AST transformations that operate on JSON serializations).+ Filters are always passed the name of the output format, so their+ behavior can be tailored to it. The repository+ <https://github.com/jgm/pandocfilters> contains+ a python module for writing pandoc filters in python, with+ a number of examples.++ * Added `--metadata/-M` option.+ This is like `--variable/-V`, but actually adds to metadata, not+ just variables.++ * Added `--print-default-data-file` option, which allows printing+ of any of pandoc's data files. (For example,+ `pandoc --print-default-data-file reference.odt` will print+ `reference.odt`.)++ * Added syntax for "pauses" in slide shows:++ This gives++ . . .++ me pause.++ * New markdown extensions:++ + `ignore_line_breaks`: causes intra-paragraph line breaks to be ignored,+ rather than being treated as hard line breaks or spaces. This is useful+ for some East Asian languages, where spaces aren't used between words,+ but text is separated into lines for readability.+ + `yaml_metadata_block`: Parse YAML metadata blocks. (Default.)+ + `ascii_identifiers`: This will force `auto_identifiers` to use ASCII+ only. (Default for `markdown_github`.) (#807)+ + `lists_without_preceding_blankline`: Allow lists to start without+ preceding blank space. (Default for `markdown_github`.) (#972)++ [behavior changes]++ * `--toc-level` no longer implies `--toc`.+ Reason: EPUB users who don't want a visible TOC may still want+ to set the TOC level for in the book navigation.++ * `--help` now prints in and out formats in alphabetical order, and+ says something about PDF output (#720).++ * `--self-contained` now returns less verbose output (telling you+ which URLs it is fetching, but not giving the full header). In+ addition, there are better error messages when fetching a URL fails.++ * Citation support is no longer baked in to core pandoc. Users who+ need citations will need to install and use a separate filter+ (`--filter pandoc-citeproc`). This filter will take `bibliography`,+ `csl`, and `citation-abbreviations` from the metadata, though it+ may still be specified on the command line as before.++ * A `Cite` element is now created in parsing markdown whether or not+ there is a matching reference.++ * The `pandoc-citeproc` script will put the bibliography at the+ end of the document, as before. However, it will be put inside a `Div`+ element with class "references", allowing users some control+ over the styling of references. A final header, if any, will+ be included in the `Div`.++ * The markdown writer will not print a bibliography if the+ `citations` extension is enabled. (If the citations are formatted+ as markdown citations, it is redundant to have a bibliography,+ since one will be generated automatically.)++ * Previously we used to store the directory of the first input file,+ even if it was local, and used this as a base directory for finding+ images in ODT, EPUB, Docx, and PDF. This has been confusing to many+ users. So we now look for images relative to the current+ working directory, even if the first file argument is in another+ directory. Note that this change may break some existing workflows.+ If you have been assuming that relative links will be interpreted+ relative to the directory of the first file argument, you'll need+ to make that the current directory before running pandoc. (#942)++ * Better error reporting in some readers, due to changes in `readWith`:+ the line in which the error occured is printed, with a caret pointing+ to the column.++ * All slide formats now support incremental slide view for definition lists.++ * Parse `\(..\)` and `\[..\]` as math in MediaWiki reader.+ Parse `:<math>...</math>` as display math. These notations are used with+ the MathJax MediaWiki extension.++ * All writers: template variables are set automatically from metadata+ fields. However, variables specified on the command line with+ `--variable` will completely shadow metadata fields.++ * If `--variable` is used to set many variables with the same name,+ a list is created.++ * Man writer: The `title`, `section`, `header`, and `footer` can now+ all be set individually in metadata. The `description` variable has been+ removed. Quotes have been added so that spaces are allowed in the+ title. If you have a title that begins++ COMMAND(1) footer here | header here++ pandoc will still parse it into a title, section, header, and+ footer. But you can also specify these elements explicitly (#885).++ * Markdown reader++ + Added support for YAML metadata blocks, which can come anywhere+ in the document (not just at the beginning). A document can contain+ multiple YAML metadata blocks.+ + HTML span and div tags are parsed as pandoc Span and Div elements.++ * Markdown writer++ + Allow simple tables to be printed as grid tables,+ if other table options are disabled. This means you can do+ `pandoc -t markdown-pipe_tables-simple_tables-multiline_tables`+ and all tables will render as grid tables.+ + Support YAML title block (render fields in alphabetical order+ to make output predictable).++ [API changes]++ * `Meta` in `Text.Pandoc.Definition` has been changed to allow+ structured metadata. (Note: existing code that pattern-matches+ on `Meta` will have to be revised.) Metadata can now contain+ indefinitely many fields, with content that can be a string,+ a Boolean, a list of `Inline` elements, a list of `Block`+ elements, or a map or list of these.++ * A new generic block container (`Div`) has been added to `Block`,+ and a generic inline container (`Span`) has been added to `Inline`.+ These can take attributes. They will render in HTML, Textile,+ MediaWiki, Org, RST and and Markdown (with `markdown_in_html`+ extension) as HTML `<div>` and `<span>` elements; in other formats+ they will simply pass through their contents. But they can be+ targeted by scripts.++ * `Format` is now a newtype, not an alias for String.+ Equality comparisons are case-insensitive.++ * Added `Text.Pandoc.Walk`, which exports hand-written tree-walking+ functions that are much faster than the SYB functions from+ `Text.Pandoc.Generic`. These functions are now used where possible+ in pandoc's code. (`Tests.Walk` verifies that `walk` and `query`+ match the generic traversals `bottomUp` and `queryWith`.)++ * Added `Text.Pandoc.JSON`, which provides `ToJSON` and `FromJSON`+ instances for the basic pandoc types. They use GHC generics and+ should be faster than the old JSON serialization using+ `Data.Aeson.Generic`.++ * Added `Text.Pandoc.Process`, exporting `pipeProcess`.+ This is a souped-up version of `readProcessWithErrorcode` that+ uses lazy bytestrings instead of strings and allows setting+ environment variables. (Used in `Text.Pandoc.PDF`.)++ * New module `Text.Pandoc.Readers.OPML`.++ * New module `Text.Pandoc.Writers.OPML`.++ * New module `Text.Pandoc.Readers.Haddock` (David Lazar).+ This is based on Haddock's own lexer/parser.++ * New module `Text.Pandoc.Writers.Custom`.++ * In `Text.Pandoc.Shared`, `openURL` and `fetchItem` now return an+ Either, for better error handling.++ * Made `stringify` polymorphic in `Text.Pandoc.Shared`.++ * Removed `stripTags` from `Text.Pandoc.XML`.++ * `Text.Pandoc.Templates`:++ + Simplified `Template` type to a newtype.+ + Removed `Empty`.+ + Changed type of `renderTemplate`: it now takes a JSON context+ and a compiled template.+ + Export `compileTemplate`.+ + Export `renderTemplate'` that takes a string instead of a compiled+ template.+ + Export `varListToJSON`.++ * `Text.Pandoc.PDF` exports `makePDF` instead of `tex2pdf`.++ * `Text.Pandoc`:++ + Made `toJsonFilter` an alias for `toJSONFilter` from `Text.Pandoc.JSON`.+ + Removed `ToJsonFilter` typeclass. `ToJSONFilter` from+ `Text.Pandoc.JSON` should be used instead. (Compiling against+ pandoc-types instead of pandoc will also produce smaller executables.)+ * Removed the deprecated `jsonFilter` function.+ + Added `readJSON`, `writeJSON` to the API (#817).++ * `Text.Pandoc.Options`:++ + Added `Ext_lists_without_preceding_blankline`,+ `Ext_ascii_identifiers`, `Ext_ignore_line_breaks`,+ `Ext_yaml_metadataBlock` to `Extension`.+ + Changed `writerSourceDirectory` to `writerSourceURL` and changed the+ type to a `Maybe`. `writerSourceURL` is set to 'Just url' when the+ first command-line argument is an absolute URL. (So, relative links+ will be resolved in relation to the first page.) Otherwise, 'Nothing'.+ + All bibliography-related fields have been removed from+ `ReaderOptions` and `WriterOptions`: `writerBiblioFiles`,+ `readerReferences`, `readerCitationStyle`.++ * The `Text.Pandoc.Biblio` module has been removed. Users of the+ pandoc library who want citation support will need to use+ `Text.CSL.Pandoc` from `pandoc-citeproc`.+++ [bug fixes]++ * In markdown, don't autolink a bare URI that is followed by `</a>`+ (#937).++ * `Text.Pandoc.Shared`++ + `openURL` now follows redirects (#701), properly handles `data:`+ URIs, and prints diagnostic output to stderr rather than stdout.+ + `readDefaultDataFile`: normalize the paths. This fixes bugs in+ `--self-contained` on pandoc compiled with `embed_data_files` (#833).+ + Fixed `readDefaultDataFile` so it works on Windows.+ + Better error messages for `readDefaultDataFile`. Instead of+ listing the last path tried, which can confuse people who are+ using `--self-contained`, so now we just list the data file name.+ + URL-escape pipe characters. Even though these are legal, `Network.URI`+ doesn't regard them as legal in URLs. So we escape them first (#535).++ * Mathjax in HTML slide shows: include explicit "Typeset" call.+ This seems to be needed for some formats (e.g. slideous) and won't+ hurt in others (#966).++ * `Text.Pandoc.PDF`++ + On Windows, create temdir in working directory, since the system+ temp directory path may contain tildes, which can cause+ problems in LaTeX (#777).+ + Put temporary output directory in `TEXINPUTS` (see #917).+ + `makePDF` tries to download images that are not found locally,+ if the first argument is a URL (#917).+ + If compiling with `pdflatex` yields an encoding error, offer+ the suggestion to use `--latex-engine=xelatex`.++ * Produce automatic header identifiers in parsing textile, RST,+ and LaTeX, unless `auto_identifiers` extension is disabled (#967).++ * `Text.Pandoc.SelfContained`: Strip off fragment, query of relative URL+ before treating as a filename. This fixes `--self-contained` when used+ with CSS files that include web fonts using the method described here:+ <http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/>+ (#739). Handle `src` in `embed`, `audio`, `source`, `input` tags.++ * `Text.Pandoc.Parsing`: `uri` parser no longer treats punctuation before+ percent-encoding, or a `+` character, as final punctuation.++ * `Text.Pandoc.ImageSize`: Handle EPS (#903). This change will make+ EPS images properly sized on conversion to Word.++ * Slidy: Use slidy.js rather than slidy.js.gz.+ Reason: some browsers have trouble with the gzipped js file,+ at least on the local file system (#795).++ * Markdown reader++ + Properly handle blank line at beginning of input (#882).+ + Fixed bug in unmatched reference links. The input+ `[*infile*] [*outfile*]` was getting improperly parsed:+ "infile" was emphasized, but "*outfile*" was literal (#883).+ + Allow internal `+` in citation identifiers (#856).+ + Allow `.` or `)` after `#` in ATX headers if no `fancy_lists`.+ + Do not generate blank title, author, or date metadata elements.+ Leave these out entirely if they aren't present.+ + Allow backtick code blocks not to be preceded by blank line (#975).++ * Textile reader:++ + Correctly handle entities.+ + Improved handling of `<pre>` blocks (#927). Remove internal HTML tags+ in code blocks, rather than printing them verbatim. Parse attributes+ on `<pre>` tag for code blocks.++ * HTML reader: Handle non-simple tables (#893). Column widths are read from+ `col` tags if present, otherwise divided equally.++ * LaTeX reader++ + Support alltt environment (#892).+ + Support `\textasciitilde`, `\textasciicircum` (#810).+ + Treat `\textsl` as emphasized text reader (#850).+ + Skip positional options after `\begin{figure}`.+ + Support `\v{}` for hacek (#926).+ + Don't add spurious ", " to citation suffixes.+ This is added when needed in pandoc-citeproc.+ + Allow spaces in alignment spec in tables, e.g. `{ l r c }`.+ + Improved support for accented characters (thanks to Scott Morrison).+ + Parse label after section command and set id (#951).++ * RST reader:++ + Don't insert paragraphs where docutils doesn't.+ `rst2html` doesn't add `<p>` tags to list items (even when they are+ separated by blank lines) unless there are multiple paragraphs in the+ list. This commit changes the RST reader to conform more closely to+ what docutils does (#880).+ + Improved metadata. Treat initial field list as metadata when+ standalone specified. Previously ALL fields "title", "author",+ "date" in field lists were treated as metadata, even if not at+ the beginning. Use `subtitle` metadata field for subtitle.+ + Fixed 'authors' metadata parsing in reST. Semicolons separate+ different authors.++ * MediaWiki reader++ + Allow space before table rows.+ + Fixed regression for `<ref>URL</ref>`.+ `<` is no longer allowed in URLs, according to the uri parser+ in `Text.Pandoc.Parsing`. Added a test case.+ + Correctly handle indented preformatted text without preceding+ or following blank line.+ + Fixed `|` links inside table cells. Improved attribute parsing.+ + Skip attributes on table rows. Previously we just crashed if+ rows had attributes, now we ignore them.+ + Ignore attributes on headers.+ + Allow `Image:` for images (#971).+ + Parse an image with caption in a paragraph by itself as a figure.++ * LaTeX writer++ + Don't use ligatures in escaping inline code.+ + Fixed footnote numbers in LaTeX/PDF tables. This fixes a bug+ wherein notes were numbered incorrectly in tables (#827).+ + Always create labels for sections. Previously the labels were only+ created when there were links to the section in the document (#871).+ + Stop escaping `|` in LaTeX math.+ This caused problems with array environments (#891).+ + Change `\` to `/` in paths. `/` works even on Windows in LaTeX.+ `\` will cause major problems if unescaped.+ + Write id for code block to label attribute in LaTeX when listings+ is used (thanks to Florian Eitel).+ + Scale LaTeX tables so they don't exceed columnwidth.+ + Avoid problem with footnotes in unnumbered headers (#940).++ * Beamer writer: when creating beamer slides, add `allowframebreaks` option+ to the slide if it is one of the header classes. It is recommended+ that your bibliography slide have this attribute:++ # References {.allowframebreaks}++ This causes multiple slides to be created if necessary, depending+ on the length of the bibliography.++ * ConTeXt writer: Properly handle tables without captions. The old output+ only worked in MkII. This should work in MkIV as well (#837).++ * MediaWiki writer: Use native mediawiki tables instead of HTML (#720).++ * HTML writer:++ + Fixed `--no-highlight` (Alexander Kondratskiy).+ + Don't convert to lowercase in email obfuscation (#839).+ + Ensure proper escaping in `<title>` and `<meta>` fields.++ * AsciiDoc writer:++ + Support `--atx-headers` (Max Rydahl Andersen).+ + Don't print empty identifier blocks `([[]])` on headers (Max+ Rydahl Andersen).++ * ODT writer:++ + Fixing wrong numbered-list indentation in open document format+ (Alexander Kondratskiy) (#369).+ + `reference.odt`: Added pandoc as "generator" in `meta.xml`.+ + Minor changes for ODF 1.2 conformance (#939). We leave the+ nonconforming `contextual-spacing` attribute, which is provided by+ LibreOffice itself and seems well supported.++ * Docx writer:++ + Fixed rendering of display math in lists.+ In 1.11 and 1.11.1, display math in lists rendered as a new list+ item. Now it always appears centered, just as outside of lists,+ and in proper display math style, no matter how far indented the+ containing list item is (#784).+ + Use `w:br` with `w:type` `textWrapping` for linebreaks.+ Previously we used `w:cr` (#873).+ + Use Compact style for Plain block elements, to+ differentiate between tight and loose lists (#775).+ + Ignore most components of `reference.docx`.+ We take the `word/styles.xml`, `docProps/app.xml`,+ `word/theme/theme1.xml`, and `word/fontTable.xml` from+ `reference.docx`, ignoring everything else. This should help+ with the corruption problems caused when different versions of+ Word resave the reference.docx and reorganize things.+ + Made `--no-highlight` work properly.++ * EPUB writer++ + Don't add `dc:creator` tags if present in EPUB metadata.+ + Add `id="toc-title"` to `h1` in `nav.xhtml` (#799).+ + Don't put blank title page in reading sequence.+ Set `linear="no"` if no title block. Addresses #797.+ + Download webtex images and include as data URLs.+ This allows you to use `--webtex` in creating EPUBs.+ Math with `--webtex` is automatically made self-contained.+ + In `data/epub.css`, removed highlighting styles (which+ are no longer needed, since styles are added by the HTML+ writer according to `--highlighting-style`). Simplified+ margin fields.+ + If resource not found, skip it, as in Docx writer (#916).++ * RTF writer:++ + Properly handle characters above the 0000-FFFF range.+ Uses surrogate pairs. Thanks to Hiromi Ishii for the patch.+ + Fixed regression with RTF table of contents.+ + Only autolink absolute URIs. This fixes a regression, #830.++ * Markdown writer:++ + Only autolink absolute URIs. This fixes a regression, #830.+ + Don't wrap attributes in fenced code blocks.+ + Write full metadata in MMD style title blocks.+ + Put multiple authors on separate lines in pandoc titleblock.+ Also, don't wrap long author entries, as new lines get treated+ as new authors.++ * `Text.Pandoc.Templates`:++ + Fixed bug retrieving default template for markdown variants.+ + Templates can now contain "record lookups" in variables;+ for example, `author.institution` will retrieve the `institution`+ field of the `author` variable.+ + More consistent behavior of `$for$`. When `foo` is not a list,+ `$for(foo)$...$endfor$` should behave like $if(foo)$...$endif$.+ So if `foo` resolves to "", no output should be produced.+ See pandoc-templates#39.++ * Citation processing improvements (now part of pandoc-citeproc):++ + Fixed `endWithPunct` The new version correctly sees a sentence+ ending in '.)' as ending with punctuation. This fixes a bug which+ led such sentences to receive an extra period at the end: '.).'.+ Thanks to Steve Petersen for reporting.+ + Don't interfere with Notes that aren't citation notes.+ This fixes a bug in which notes not generated from citations were+ being altered (e.g. first letter capitalized) (#898).+ + Only capitalize footnote citations when they have a prefix.+ + Changes in suffix parsing. A suffix beginning with a digit gets 'p'+ inserted before it before passing to citeproc-hs, so that bare numbers+ are treated as page numbers by default. A suffix not beginning with+ punctuation has a space added at the beginning (rather than a comma and+ space, as was done before for not-author-in-text citations).+ The result is that `\citep[23]{item1}` in LaTeX will be interpreted+ properly, with '23' treated as a locator of type 'page'.+ + Many improvements to citation rendering, due to fixes in citeproc-hs+ (thanks to Andrea Rossato).+ + Warnings are issued for undefined citations, which are rendered+ as `???`.+ + Fixed hanging behavior when locale files cannot be found.++ [template changes]++ * DocBook: Use DocBook 4.5 doctype.++ * Org: '#+TITLE:' is inserted before the title.+ Previously the writer did this.++ * LaTeX: Changes to make mathfont work with xelatex.+ We need the mathspec library, not just fontspec, for this.+ We also need to set options for setmathfont (#734).++ * LaTeX: Use `tex-ansi` mapping for `monofont`.+ This ensures that straight quotes appear as straight, rather than+ being treated as curly. See #889.++ * Made `\includegraphics` more flexible in LaTeX template.+ Now it can be used with options, if needed. Thanks to Bernhard Weichel.++ * LaTeX/Beamer: Added `classoption` variable.+ This is intended for class options like `oneside`; it may+ be repeated with different options. (Thanks to Oliver Matthews.)++ * Beamer: Added `fonttheme` variable. (Thanks to Luis Osa.)++ * LaTeX: Added `biblio-style` variable (#920).++ * DZSlides: title attribute on title section.++ * HTML5: add meta tag to allow scaling by user (Erik Evenson)++ [under-the-hood improvements]++ * Markdown reader:Improved strong/emph parsing, using the strategy of+ <https://github.com/jgm/Markdown>. The new parsing algorithm requires+ no backtracking, and no keeping track of nesting levels. It will give+ different results in some edge cases, but these should not affect normal+ uses.++ * Added `Text.Pandoc.Compat.Monoid`.+ This allows pandoc to compile with `base` < 4.5, where `Data.Monoid`+ doesn't export `<>`. Thanks to Dirk Ullirch for the patch.++ * Added `Text.Pandoc.Compat.TagSoupEntity`.+ This allows pandoc to compile with `tagsoup` 0.13.x.+ Thanks to Dirk Ullrich for the patch.++ * Most of `Text.Pandoc.Readers.TeXMath` has been moved to the+ `texmath` module (0.6.4). (This allows `pandoc-citeproc` to+ handle simple math in bibliography fields.)++ * Added `Text.Pandoc.Writers.Shared` for shared functions used+ only in writers. `metaToJSON` is used in writers to create a+ JSON object for use in the templates from the pandoc metadata+ and variables. `getField`, `setField`, and `defField` are+ for working with JSON template contexts.++ * Added `Text.Pandoc.Asciify` utility module.+ This exports functions to create ASCII-only versions of identifiers.++ * `Text.Pandoc.Parsing`++ + Generalized state type on `readWith` (API change).+ + Specialize readWith to `String` input. (API change).+ + In `ParserState`, replace `stateTitle`, `stateAuthors`, `stateDate`+ with `stateMeta` and `stateMeta'`.++ * `Text.Pandoc.UTF8`: use strict bytestrings in reading. The use of lazy+ bytestrings seemed to cause problems using pandoc on 64-bit Windows+ 7/8 (#874).++ * Factored out `registerHeader` from markdown reader, added to+ `Text.Pandoc.Parsing`.++ * Removed `blaze_html_0_5` flag, require `blaze-html` >= 0.5.+ Reason: < 0.5 does not provide a monoid instance for Attribute,+ which is now needed by the HTML writer (#803).++ * Added `http-conduit` flag, which allows fetching https resources.+ It also brings in a large number of dependencies (`http-conduit`+ and its dependencies), which is why for now it is an optional flag+ (#820).++ * Added CONTRIBUTING.md.++ * Improved INSTALL instructions.++ * `make-windows-installer.bat`: Removed explicit paths for executables.++ * `aeson` is now used instead of `json` for JSON.++ * Set default stack size to 16M. This is needed for some large+ conversions, esp. if pandoc is compiled with 64-bit ghc.++ * Various small documentation improvements.+ Thanks to achalddave and drothlis for patches.++ * Removed comment that chokes recent versions of CPP (#933).++ * Removed support for GHC version < 7.2, since pandoc-types now+ requires at least GHC 7.2 for GHC generics.+++pandoc (1.11.1)++ * Markdown reader:++ + Fixed regression in which parentheses were lost in link URLs.+ Added tests. Closes #786.+ + Better handling of unmatched double quotes in `--smart` mode.+ These occur frequently in fiction, since it is customary not to+ close quotes in dialogue if the speaker does not change between+ paragraphs. The unmatched quotes now get turned into literal+ left double quotes. (No `Quoted` inline is generated, however.)+ Closes #99 (again).++ * HTML writer: Fixed numbering mismatch between TOC and sections.+ `--number-offset` now affects TOC numbering as well+ as section numbering, as it should have all along. Closes #789.++ * Markdown writer: Reverted 1.11 change that caused citations to be rendered+ as markdown citations, even if `--bibliography` was specified, unless+ `citation` extension is disabled. Now, formatted citations are always+ printed if `--bibliography` was specified. If you want to reformat+ markdown keeping pandoc markdown citations intact, don't use+ `--bibliography`. Note that citations parsed from LaTeX documents will+ be rendered as pandoc markdown citations when `--bibliography` is not+ specified.++ * ODT writer: Fixed regression leading to corrupt ODTs.+ This was due to a change in the `Show` instance for+ `Text.Pandoc.Pretty.Doc`. Closes #780.++ * Fixed spacing bugs involving code block attributes in+ RST reader and Markdown writer. Closes #763.++ * Windows package: Various improvements due to Fyodor Sheremetyev.++ + Automatically set installation path (Program Files or Local App Data).+ + Set system PATH environment variable when installing for all users.+ + Pandoc can installed for all users using the following command.+ `msiexec /i pandoc-1.11.msi ALLUSERS=1`.++ * Bumped QuickCheck version bound.++pandoc (1.11)++ * Added `--number-offset` option. (See README for description.)++ * Added `--default-image-extension` option. (See README for description.)++ * `--number-sections` behavior change: headers with class `unnumbered`+ will not be numbered.++ * `--version` now reports the default data directory.++ * `Text.Pandoc.Parsing` is no longer exposed. (API change.)++ * `Text.Pandoc.Highlighting` is no longer exposed. (API change.)++ * `Text.Pandoc.Shared`: Changed type of `Element`. `Sec` now includes+ a field for `Attr` rather than just `String`. (API change.)++ * Added `markdown_github` as input format. This was an accidental+ omission in 1.10.++ * Added `readerDefaultImageExtension` field to `ReaderOptions`. (API+ change.)++ * Added `writerNumberOffset` field in `WriterOptions`. (API change.)++ * Beamer template:++ + Fixed captions with longtable. Thanks to Joost Kremers.+ + Provide `\Oldincludegraphics` as in LaTeX template (Benjamin Bannier).++ * LaTeX template:++ + Load microtype after fonts. Microtype needs to know+ what fonts are being used. Thanks to dfc for the patch.+ + Set `secnumdepth` to 5 if `--number-sections` specified.+ This yields behavior equivalent to the other writers, numbering+ level 4 and 5 headers too. Closes #753.++ * HTML reader:++ + Handle `<colgroup>` tag.+ + Preserve all header attributes.++ * LaTeX reader:++ + Parse `\hrule` as `HorizontalRule`. Closes #746.+ + Parse starred variants of `\section` etc. as headers with+ attribute `unnumbered`.+ + Read optional attributes in `lstlisting` and `Verbatim` environments.+ We convert these to pandoc standard names, e.g. `numberLines`+ for `numbers=left`, `startFrom=100` from `firstnumber=100`.+ + Handle language attribute for lstlistings.+ + Better support for Verbatim and minted environments. Closes #763.++ * Markdown reader:++ + `-` in an attribute context = `.unnumbered`. The point of this+ is to provide a way to specify unnumbered headers in non-English+ documents.+ + Fixed bug parsing key/value attributes. Parsing failed if you+ had an unquoted attribute immediately before the final '}'.+ + Make backslash escape work in attributes.+ + Fix title block parsing. Now if `mmd_title_blocks` is specified,+ pandoc will parse a MMD title block if it sees one, even if+ `pandoc_title_blocks` is enabled.+ + Refactoring: `litChar` now includes entities, so we don't need+ to use `fromEntities` e.g. on titles.+ + Allow spaces around borders in pipe tables. Closes #772.+ + Allow all punctuation in angle-bracket autolinks. Previously+ things like `----` were disallowed, because the uri parser+ treated them as trailing punctuation. Closes #768.+ + Make `implicit_header_references` work properly when+ headers are given explicit identifiers.+ + Check for tables before line blocks. Otherwise some pipe+ tables get treated as line blocks.+ + Allow `&` in emails (for entities).+ + Properly handle entities in titles and links. A markdown link+ `<http://göogle.com>` should be a link to `http://göogle.com`.+ Closes #723.++ * Textile reader:++ + Handle attributes on headers.++ * LaTeX reader:++ + Add `fig:` as title for images with captions.+ This is needed for them to be rendered as figures. Closes #766.+ + Never emit an empty paragraph. See #761.+ + Handle `\caption` for images in figures. Closes #766.+ + Parse `\section*`, etc. as unnumbered sections.++ * HTML writer:++ + Support header attributes. The attributes go on+ the enclosing `section` or `div` tag if `--section-divs` is specified.+ + Fixed a regression (only now noticed) in html+lhs output.+ Previously the bird tracks were being omitted.++ * LaTeX writer:++ + Omit lists with no items to avoid LaTeX errors.+ + Support line numbering with `--listings`.+ If `numberLines` class is present, we add `numbers=left`;+ if `startFrom` is present, we add `firstnumber=`. (#763)++ * ConTeXt writer:++ + Removed `\placecontent`. This produced a duplicate toc,+ in conjunction with `\placelist`.+ + Use `\title`, `\subject` etc. for headers with+ `unnumbered` class.++ * Textile writer:++ + Support header attributes.++ * Markdown writer:++ + Use grid tables when needed, and if enabled. Closes #740.+ + Render citations as pandoc-markdown citations.+ Previously citations were rendered as citeproc-formatted citations+ by default. Now we render them as pandoc citations, e.g. `[@item1]`,+ unless the `citations` extension is disabled.+ If you still want formatted citations in your markdown output,+ use `pandoc -t markdown-citations`.++ * RST writer:++ + Support `:number-lines:` in code blocks.++ * Docx writer:++ + Better treatment of display math. Display math inside a+ paragraph is now put in a separate paragraph, so it will render+ properly (centered and without extra blank lines around it).+ Partially addresses #742.+ + Content types and document rels xml files are now created from+ scratch, rather than being taken over from `reference.docx`.+ This fixes problems that arise when you edit the `reference.docx`+ with Word.+ + We also now encode mime types for each individual image rather+ than using defaults. This should allow us to handle a wider+ range of image types (including PDF). Closes #414.+ + Changed style names in `reference docx`.+ `FootnoteReference` -> `FootnoteRef`, `Hyperlink` -> `Link`.+ The old names got changed by Word when the `reference.docx` was+ edited. Closes #414.++ * EPUB writer:++ + Fix section numbering. Previously the numbering restarted from 1+ in each chapter (with `--number-sections`), though the numbers in+ the table of contents were correct.+ + Headers with "unnumbered" attribute are not numbered. (Nor do they+ cause an increment in running numbering.) Section numbers now work+ properly, even when there is material before the first numbered section.+ + Include HTML TOC, even in epub2. The TOC is included in `<spine>`,+ but `linear` is set to `no` unless the `--toc` option is specified.+ Include `<guide>` element in OPF. This should allow the TOC to+ be useable in Kindles when converted with kindlegen. Closes #773.++ * `Text.Pandoc.Parsing`: Optimized `oneOfStringsCI`.+ This dramatically reduces the speed penalty that comes from enabling the+ `autolink_bare_uris` extension. The penalty is still substantial (in one+ test, from 0.33s to 0.44s), but nowhere near what it used to be.+ The RST reader is also much faster now, as it autodetects URIs.++ * `Text.Pandoc.Shared`: `hierarchicalize` will not number section+ with class "unnumbered". Unnumbered sections get `[]` for their+ section number.++ * `Text.Pandoc.Pretty`:++ + Fixed `chomp` so it works inside `Prefixed` elements.+ + Changed `Show` instance so it is better for debugging.++ * `Text.Pandoc.ImageSize`: Added `Pdf` to `ImageType`.++ * `Text.Pandoc.UTF8`: Strip off BOM if present. Closes #743.++ * Windows installer improvements:++ + The installer is now signed with a certificate (thanks to+ Fyodor Sheremetyev).+ + WiX is used instead of InnoSetup. The installer is now a+ standard msi file.+ + The version number is now auto-detected, and need not be+ updated separately.++ * OSX installer improvements:++ + The package and pandoc executable are now signed with a+ certificate (thanks to Fyodor Sheremetyev).+ + RTF version of license is used.+ + Use full path for sysctl in `InstallationCheck` script (jonahbull).+ Closes #580.++ * Converted COPYING to markdown.++ * pandoc.cabal: Require latest versions of highlighting-kate,+ texmath, citeproc-hs, zip-archive.++pandoc (1.10.1)++ * Markdown reader: various optimizations, leading to a+ significant performance boost.++ * RST reader: Allow anonymous form of inline links:+ `` `hello <url>`__ `` Closes #724.++ * Mediawiki reader: Don't require newlines after tables.+ Thanks to jrunningen for the patch. Closes #733.++ * Fixed LaTeX macro parsing. Now LaTeX macro definitions are preserved+ when output is LaTeX, and applied when it is another format.+ Partially addresses #730.++ * Markdown and RST readers: Added parser to `block` that skips blank+ lines. This fixes a subtle regression involving grid tables with+ empty cells. Also added test for grid table with empty cells.+ Closes #732.++ * RST writer: Use `.. code:: language` for code blocks with language.+ Closes #721.++ * DocBook writer: Fixed output for hard line breaks, adding a newline+ between `<literallayout>` tags.++ * Markdown writer: Use an autolink when link text matches url.+ Previously we also checked for a null title, but this+ test fails for links produced by citeproc-hs in bibliographies.+ So, if the link has a title, it will be lost on conversion+ to an autolink, but that seems okay.++ * Markdown writer: Set title, author, date variables as before.+ These are no longer used in the default template, since we use+ titleblock, but we set them anyway for those who use custom templates.++ * LaTeX writer: Avoid extra space at start/end of table cell.+ Thanks to Nick Bart for the suggestion of using @{}.++ * `Text.Pandoc.Parsing`:++ + More efficient version of `anyLine`.+ + Type of `macro` has changed; the parser now returns `Blocks`+ instead of `Block`.++ * Relaxed old-time version bound, allowing 1.0.*.++ * Removed obsolete `hsmarkdown` script. Those who need `hsmarkdown`+ should create a symlink as described in the README.++pandoc (1.10.0.5)++ * Markdown reader: Try `lhsCodeBlock` before `rawTeXBlock`. Otherwise+ `\begin{code}...\end{code}` isn't handled properly in markdown+lhs.+ Thanks to Daniel Miot for noticing the bug and suggesting the fix.++ * Markdown reader: Fixed bug with headerless grid tables.+ The 1.10 code assumed that each table header cell contains exactly one+ block. That failed for headerless tables (0) and also for tables with+ multiple blocks in a header cell. The code is fixed and tests provided.+ Thanks to Andrew Lee for pointing out the bug.++ * Markdown reader: Fixed regressions in fenced code blocks. Closes #722.++ + Tilde code fences can again take a bare language string+ (`~~~ haskell`), not just curly-bracketed attributes+ (`~~~ {.haskell}`).+ + Backtick code blocks can take the curly-bracketed attributes.+ + Backtick code blocks don't *require* a language.+ + Consolidated code for the two kinds of fenced code blocks.++ * LaTeX template: Use `\urlstyle{same}` to avoid monospace URLs.++ * Markdown writer: Use proportional font for email autolinks with+ obfuscation. Closes #714.++ * Corrected name of `blank_before_blockquote` in README. Closes #718.++ * `Text.Pandoc.Shared`: Fixed bug in `uri` parser.+ The bug prevented an autolink at the end of a string (e.g.+ at the end of a line block line) from counting as a link. Closes #711.++ * Use the `hsb2hs` preprocessor instead of TH for embed_data_files.+ This should work on Windows, unlike the TH solution with+ file-embed.++ * Eliminated use of TH in test suite.++ * Added `Text.Pandoc.Data` (non-exported) to hold the association+ list of embedded data files, if the `embed_data_files` flag is selected.+ This isolates the code that needs special treatment with file-embed or+ `hsb2hs`.++ * Changes to `make-windows-installer.bat`.++ + Exit batch file if any of the cabal-dev installs fail.+ + There's no longer any need to reinstall `highlighting-kate`.+ + Don't start with a `cabal update`; leave that to the user.+ + Force reinstall of pandoc.++ * Fixed EPUB writer so it builds with blaze-html 0.4.x. Thanks to+ Jens Petersen.++pandoc (1.10.0.4)++ * Fixed bug with escaped % in LaTeX reader. Closes #710.++pandoc (1.10.0.3)++ * Added further missing fb2 tests to cabal file.++pandoc (1.10.0.2)++ * Added fb2 tests to cabal file's extra-source-files.++pandoc (1.10.0.1)++ * Bump version bounds on test-framework packages.++pandoc (1.10)++ [new features]++ * New input formats: `mediawiki` (MediaWiki markup).++ * New output formats: `epub3` (EPUB v3 with MathML),+ `fb2` (FictionBook2 ebooks).++ * New `--toc-depth` option, specifying how many levels of+ headers to include in a table of contents.++ * New `--epub-chapter-level` option, specifying the header+ level at which to divide EPUBs into separate files.+ Note that this normally affects only performance, not the+ visual presentation of the EPUB in a reader.++ * Removed the `--strict` option. Instead of using `--strict`,+ one can now use the format name `markdown_strict` for either input+ or output. This gives more fine-grained control that `--strict`+ did, allowing one to convert from pandoc's markdown to strict+ markdown or vice versa.++ * It is now possible to enable or disable specific syntax+ extensions by appending them (with `+` or `-`) to the writer+ or reader name. For example,++ pandoc -f markdown-footnotes+hard_line_breaks++ disables footnotes and enables treating newlines as hard+ line breaks. The literate Haskell extensions are now implemented+ this way as well, using either `+lhs` or `+literate_haskell`.+ For a list of extension names, see the README under+ "Pandoc's Markdown."++ * The following aliases have been introduced for specific+ combinations of markdown extensions: `markdown_phpextra`,+ `markdown_github`, `markdown_mmd`, `markdown_strict`. These aliases+ work just like regular reader and writer names, and can be modified+ with extension modifiers as described above. (Note that conversion+ from one markdown dialect to another does not work perfectly,+ because there are differences in markdown parsers besides+ just the extensions, and because pandoc's internal document model is+ not rich enough to capture all of the extensions.)++ * New `--html-q-tags` option. The previous default was to use `<q>`+ tags for smart quotes in HTML5. But `<q>` tags are also valid HTML4.+ Moreover, they are not a robust way of typesetting quotes, since+ some user agents don't support them, and some CSS resets (e.g.+ bootstrap) prevent pandoc's quotes CSS from working properly.+ We now just insert literal quote characters by default in both+ `html` and `html5` output, but this option is provided for+ those who still want `<q>` tags.++ * The markdown reader now prints warnings (to stderr) about+ duplicate link and note references. Closes #375.++ * Markdown syntax extensions:++ + Added pipe tables. Thanks to François Gannaz for the initial patch.+ These conform to PHP Markdown Extra's pipe table syntax. A subset+ of org-mode table syntax is also supported, which means that you can+ use org-mode's nice table editor to create tables.++ + Added support for RST-style line blocks. These are+ useful for verse and addresses.++ + Attributes can now be specified for headers, using the same+ syntax as in code blocks. (However, currently only the+ identifier has any effect in most writers.) For example,++ # My header {#foo}++ See [the header above](#foo).++ + Pandoc will now act as if link references have been defined+ for all headers without explicit identifiers.+ So, you can do this:++ # My header++ Link to [My header].+ Another link to [it][My header].++ Closes #691.++ * LaTeX reader:++ + Command macros now work everywhere, including non-math.+ Environment macros still not supported.+ + `\input` now works, as well as `\include`. TEXINPUTS is used.+ Pandoc looks recursively into included files for more included files.++ [behavior changes]++ * The Markdown reader no longer puts the text of autolinks in a+ `Code` inline. This means that autolinks will no longer appear+ in a monospace font.++ * The character `/` can now appear in markdown citation keys.++ * HTML blocks in strict_markdown are no longer required to begin+ at the left margin. Technically this is required, according to+ the markdown syntax document, but `Markdown.pl` and other markdown+ processors are more liberal.++ * The `-V` option has been changed so that if there are duplicate+ variables, those specified later on the command line take precedence.++ * Tight lists now work in LaTeX and ConTeXt output.++ * The LaTeX writer no longer relien on the `enumerate` package.+ Instead, it uses standard LaTeX commands to change the list numbering+ style.++ * The LaTeX writer now uses `longtable` instead of `ctable`. This allows+ tables to be split over page boundaries.++ * The RST writer now uses a line block to render paragraphs containing+ linebreaks (which previously weren't supported at all).++ * The markdown writer now applies the `--id-prefix` to footnote IDs.+ Closes #614.++ * The plain writer no longer uses backslash-escaped line breaks+ (which are not very "plain").++ * `Text.Pandoc.UTF8`: Better error message for invalid UTF8.+ Read bytestring and use `Text`'s decodeUtf8 instead of using+ `System.IO.hGetContents`. This way you get a message saying+ "invalid UTF-8 stream" instead of "invalid byte sequence."+ You are also told which byte caused the problem.++ * Docx, ODT, and EPUB writers now download images specified by a URL+ instead of skipping them or raising an error.++ * EPUB writer:++ + The default CSS now left-aligns headers by default, instead of+ centering. This is more consistent with the rest of the writers.+ + A proper multi-level table of contents is now used in `toc.ncx`.+ There is no longer a subsidiary table of contents at the beginning+ of each chapter.+ + Code highlighting now works by default.+ + Section divs are used by default for better semantic markup.+ + The title is used instead of "Title Page" in the table of contents.+ Otherwise we have a hard-coded English string, which looks+ strange in ebooks written in other languages. Closes #572.++ * HTML writer:++ + Put mathjax in span with class "math". Closes #562.+ + Put citations in a span with class "citation." In HTML5, also include+ a `data-cite` attribute with a space-separated list of citation+ keys.++ * `Text.Pandoc.UTF8`: use universalNewlineMode in reading.+ This treats both `\r\n` and `\n` as `\n` on input, no matter+ what platform we're running on.++ * Citation processing is now done in the Markdown and LaTeX+ readers, not in `pandoc.hs`. This makes it easier for library users+ to use citations.++ [template changes]++ * HTML: Added css to template to preserve spaces in `<code>` tags.+ Thanks to Dirk Laurie.++ * Beamer: Remove English-centric strings in section pages.+ Section pages used to have "Section" and a number as well as the+ section title. Now they just have the title. Similarly for part+ and subsection. Closes #566.++ * LaTeX, ConTeXt: Added papersize variable.++ * LaTeX, Beamer templates: Use longtable instead of ctable.++ * LaTeX, Beamer templates: Don't require 'float' package for tables.+ We don't actually seem to use the '[H]' option.++ * LaTeX: Use `upquote` package if it is available. This fixes+ straight quotes in verbatim environments.++ * Markdown, plain: Fixed titleblock so it is just a single string.+ Previously separate title, author, and date variables were used,+ but this didn't allow different kinds of title blocks.++ * EPUB:++ + Rationalized templates. Previously there were three different+ templates involved in epub production. There is now just one+ template, `default.epub` or `default.epub3`. It can now be+ overridden using `--template`, just like other templates.+ The titlepage is now folded into the default template.+ A `titlepage` variable selects it.+ + UTF-8, lang tag, meta tags, title element.++ * Added scale-to-width feature to beamer template++ [API changes]++ * `Text.Pandoc.Definition`: Added `Attr` field to `Header`.+ Previously header identifers were autogenerated by the writers.+ Now they are added in the readers (either automatically or explicitly).++ * `Text.Pandoc.Builder`:++ + `Inlines` and `Blocks` are now synonyms for `Many Inline` and+ `Many Block`. `Many` is a newtype wrapper around `Seq`, with+ custom Monoid instances for `Many Inline` and `Many Block. This+ allows `Many` to be made an instance of `Foldable` and `Traversable`.+ + The old `Listable` class has been removed.+ + The module now exports `isNull`, `toList`, `fromList`.+ + The old `Read` and `Show` instances have been removed; derived+ instances are now used.+ + Added `headerWith`.++ * The readers now take a `ReaderOptions` rather than a `ParserState`+ as a parameter. Indeed, not all parsers use the `ParserState` type;+ some have a custom state. The motivation for this change was to separate+ user-specifiable options from the accounting functions of parser state.++ * New module `Text.Pandoc.Options`. This includes the `WriterOptions`+ formerly in `Text.Pandoc.Shared`, and its associated+ data types. It also includes a new type `ReaderOptions`, which+ contains many options formerly in `ParserState`, and its associated+ data types:++ + `ParserState.stateParseRaw` -> `ReaderOptions.readerParseRaw`.+ + `ParserState.stateColumns` -> `ReaderOptions.readerColumns`.+ + `ParserState.stateTabStop` -> `ReaderOptions.readerTabStop`.+ + `ParserState.stateOldDashes` -> `ReaderOptions.readerOldDashes`.+ + `ParserState.stateLiterateHaskell` -> `ReaderOptions.readerLiterateHaskell`.+ + `ParserState.stateCitations` -> `ReaderOptions.readerReferences`.+ + `ParserState.stateApplyMacros` -> `ReaderOptions.readerApplyMacros`.+ + `ParserState.stateIndentedCodeClasses` ->+ `ReaderOptions.readerIndentedCodeClasses`.+ + Added `ReaderOptions.readerCitationStyle`.++ * `WriterOptions` now includes `writerEpubVersion`, `writerEpubChapterLevel`,+ `writerEpubStylesheet`, `writerEpubFonts`, `writerReferenceODT`,+ `writerReferenceDocx`, and `writerTOCDepth`. `writerEPUBMetadata` has+ been renamed `writerEpubMetadata` for consistency.++ * Changed signatures of `writeODT`, `writeDocx`, `writeEPUB`, since they no+ longer stylesheet, fonts, reference files as separate parameters.++ * Removed `writerLiterateHaskell` from `WriterOptions`, and+ `readerLiterateHaskell` from `ReaderOptions`. LHS is now handled+ by an extension (`Ext_literate_haskell`).++ * Removed deprecated `writerXeTeX`.++ * Removed `writerStrict` from `WriterOptions`. Added `writerExtensions`.+ Strict is now handled through extensions.++ * `Text.Pandoc.Options` exports `pandocExtensions`, `strictExtensions`,+ `phpMarkdownExtraExtensions`, `githubMarkdownExtensions`,+ and `multimarkdownExtensions`, as well as the `Extensions` type.++ * New `Text.Pandoc.Readers.MediaWiki` module, exporting+ `readMediaWiki`.++ * New `Text.Pandoc.Writers.FB2` module, exporting `writeFB2`+ (thanks to Sergey Astanin).++ * `Text.Pandoc`:++ + Added `getReader`, `getWriter` to `Text.Pandoc`.+ + `writers` is now an association list `(String, Writer)`.+ A `Writer` can be a `PureStringWriter`, an `IOStringWriter`, or+ an `IOByteStringWriter`. ALL writers are now in the 'writers'+ list, including the binary writers and FB2 writer. This allows+ code in `pandoc.hs` to be simplified.+ + Changed type of `readers`, so all readers are in IO.+ Users who want pure readers can still get them form the reader+ modules; this just affects the function `getReader` that looks up+ a reader based on the format name. The point of this change is to+ make it possible to print warnings from the parser.++ * `Text.Pandoc.Parsing`:++ + `Text.Parsec` now exports all Parsec functions used in pandoc code.+ No other module directly imports Parsec. This will make it easier+ to change the parsing backend in the future, if we want to.+ + `Text.Parsec` is used instead of `Text.ParserCombinators.Parsec`.+ + Export the type synonym `Parser`.+ + Export `widthsFromIndices`, `NoteTable'`, `KeyTable'`, `Key'`, `toKey'`,+ `withQuoteContext`, `singleQuoteStart`, `singleQuoteEnd`,+ `doubleQuoteStart`, `doubleQuoteEnd`, `ellipses`, `apostrophe`,+ `dash`, `nested`, `F(..)`, `askF`, `asksF`, `runF`, `lineBlockLines`.+ + `ParserState` is no longer an instance of `Show`.+ + Added `stateSubstitutions` and `stateWarnings` to `ParserState`.+ + Generalized type of `withQuoteContext`.+ + Added `guardEnabled`, `guardDisabled`, `getOption`.+ + Removed `failIfStrict`.+ + `lookupKeySrc` and `fromKey` are no longer exported.++ * `Data.Default` instances are now provided for `ReaderOptions`,+ `WriterOptions`, and `ParserState`. `Text.Pandoc` re-exports `def`.+ Now you can use `def` (which is re-exported by `Text.Pandoc`) instead+ of `defaultWriterOptions` (which is still defined). Closes #546.++ * `Text.Pandoc.Shared`:++ + Added `safeRead`.+ + Renamed `removedLeadingTrailingSpace` to `trim`,+ `removeLeadingSpace` to `triml`, and `removeTrailingSpace` to `trimr`.+ + Count `\r` as space in `trim` functions.+ + Moved `renderTags'` from HTML reader and `Text.Pandoc.SelfContained`+ to `Shared`.+ + Removed `failUnlessLHS`.+ + Export `compactify'`, formerly in Markdown reader.+ + Export `isTightList`.+ + Do not export `findDataFile`.+ + `readDataFile` now returns a strict ByteString.+ + Export `readDataFileUTF8` which returns a String, like the+ old `readDataFile`.+ + Export `fetchItem` and `openURL`.++ * `Text.Pandoc.ImageSize`: Use strict, not lazy bytestrings.+ Removed `readImageSize`.++ * `Text.Pandoc.UTF8`: Export `encodePath`, `decodePath`,+ `decodeArg`, `toString`, `fromString`, `toStringLazy`,+ `fromStringLazy`.++ * `Text.Pandoc.UTF8` is now an exposed module.++ * `Text.Pandoc.Biblio`:++ + csl parameter now a `String` rather than a `FilePath`.+ + Changed type of `processBiblio`. It is no longer in the IO monad.+ It now takes a `Maybe Style` argument rather than parameters for CSL+ and abbrev filenames. (`pandoc.hs` now calls the functions to parse+ the style file and add abbreviations.)++ * Markdown reader now exports `readMarkdownWithWarnings`.++ * `Text.Pandoc.RTF` now exports `writeRTFWithEmbeddedImages` instead of+ `rtfEmbedImage`.++ [bug fixes]++ * Make `--ascii` work properly with `--self-contained`. Closes #568.++ * Markdown reader:++ + Fixed link parser to avoid exponential slowdowns. Closes #620.+ Previously the parser would hang on input like this:++ [[[[[[[[[[[[[[[[[[hi++ We fixed this by making the link parser parser characters+ between balanced brackets (skipping brackets in inline code spans),+ then parsing the result as an inline list. One change is that++ [hi *there]* bud](/url)++ is now no longer parsed as a link. But in this respect pandoc behaved+ differently from most other implementations anyway, so that seems okay.++ + Look for raw html/latex blocks before tables.+ Otherwise the following gets parsed as a table:++ \begin{code}+ --------------+ -- My comment.+ \end{code}++ Closes #578.++ * RST reader:++ + Added support for `:target:` on `.. image::` blocks+ and substitutions.+ + Field list fixes:++ - Fixed field lists items with body beginning after a new line+ (Denis Laxalde).+ - Allow any char but ':' in names of field lists in RST reader+ (Denis Laxalde).+ - Don't allow line breaks in field names.+ - Require whitespace after field list field names.+ - Don't create empty definition list for metadata field lists.+ Previously a field list consisting only of metadata fields (author,+ title, date) would be parsed as an empty DefinitionList, which is+ not legal in LaTeX and not needed in any format.++ + Don't recognize inline-markup starts inside words.+ For example, `2*2 = 4*1` should not contain an emphasized+ section. Added test case for "Literal symbols". Closes #569.+ + Allow dashes as separator in simple tables. Closes #555.+ + Added support for `container`, `compound`, `epigraph`,+ `rubric`, `highlights`, `pull-quote`.+ + Added support for `.. code::`.+ + Made directive labels case-insensitive.+ + Removed requirement that directives begin at left margin.+ This was (correctly) not in earlier releases; docutils doesn't+ make the requirement.+ + Added support for `replace::` and `unicode::` substitutions.+ + Ignore unknown interpreted roles.+ + Renamed image parser to `subst`, since it now handles all+ substitution references.++ * Textile reader:++ + Allow newlines before pipes in table. Closes #654.+ + Fixed bug with list items containing line breaks.+ Now pandoc correctly handles hard line breaks inside list items.+ Previously they broke list parsing.+ + Implemented comment blocks.+ + Fixed bug affected words ending in hyphen.+ + Properly handle links with surrounding brackets.+ Square brackets need to be used when the link isn't surrounded by+ spaces or punctuation, or when the URL ending may be ambiguous.+ Closes #564.+ + Removed nullBlock. Better to know about parsing problems than+ to skip stuff when we get stuck.+ + Allow ID attributes on headers.+ + Textile reader: Avoid parsing dashes as strikeout.+ Previously the input++ text--+ text--+ text--+ text--++ would be parsed with strikeouts rather than dashes. This fixes+ the problem by requiring that a strikeout delimiting - not be+ followed by a -. Closes #631.+ + Expanded list of `stringBreakers`.+ This fixes a bug on input like "(_hello_)" which should+ be a parenthesized emphasized "hello".+ The new list is taken from the PHP source of textile 2.4.+ + Fixed autolinks. Previously the textile reader and writer+ incorrectly implented RST-style autolinks for URLs and email+ addresses. This has been fixed. Now an autolink is done this way:+ `"$":http://myurl.com`.+ + Fixed footnotes bug in textile. This affected notes occuring+ before punctuation, e.g. `foo[1].`. Closes #518.++ * LaTeX reader:++ + Better handling of citation commands.+ + Better handling of `\noindent`.+ + Added a 'try' in rawLaTeXBlock, so we can handle `\begin` without `{`.+ Closes #622.+ + Made `rawLaTeXInline` try to parse block commands as well. This+ is usually what we want, given how `rawLaTeXInline` is used in+ the markdown and textile readers. If a block-level LaTeX command+ is used in the middle of a paragraph (e.g. `\subtitle` inside a title),+ we can treat it as raw inline LaTeX.+ + Handle \slash command. Closes #605.+ + Basic `\enquote` support.+ + Fixed parsing of paragraphs beginning with a group. Closes #606.+ + Use curly quotes for bare straight quotes.+ + Support obeylines environment. Closes #604.+ + Guard against "begin", "end" in inlineCommand and+ blockCommand.+ + Better error messages for environments. Now it should tell you that+ it was looking for \end{env}, instead of giving "unknown parse error."++ * HTML reader:++ + Added HTML 5 tags to list of block-level tags.+ + HTML reader: Fixed bug in `htmlBalanced`, which+ caused hangs in parsing certain markdown input using+ strict mode.+ + Parse `<q>` as `Quoted DoubleQuote`.+ + Handle nested `<q>` tags properly.+ + Modified `htmlTag` for fewer false positives.+ A tag must start with `<` followed by `!`,`?`, `/`, or a letter.+ This makes it more useful in the wikimedia and markdown parsers.++ * DocBook reader: Support title in "figure" element. Closes #650.++ * MediaWiki writer:++ + Remove newline after `<br/>` in translation of `LineBreak`+ There's no particular need for a newline (other than making the+ generated MediaWiki source look nice to a human), and in fact+ sometimes it is incorrect: in particular, inside an enumeration, list+ items cannot have embedded newline characters. (Brent Yorgey)+ + Use `<code>` not `<tt>` for Code.++ * Man writer: Escape `-` as `\-`.+ Unescaped `-`'s become hyphens, while `\-`'s are left as ascii minus+ signs. That is preferable for use with command-line options. See+ <http://lintian.debian.org/tags/hyphen-used-as-minus-sign.html>. Thanks+ to Andrea Bolognani for bringing the issue to our attention.++ * RST writer:++ + Improved line block output. Use nonbreaking spaces for+ initial indent (otherwise lost in HTML and LaTeX).+ Allow multiple paragraphs in a single line block.+ Allow soft breaks w continuations in line blocks.+ + Properly handle images with no alt text. Closes #678.+ + Fixed bug with links with duplicate text. We now (a) use anonymous+ links for links with inline URLs, and (b) use an inline link instead+ of a reference link if the reference link would require a label that+ has already been used for a different link. Closes #511.+ + Fixed hyperlinked images. Closes #611. Use `:target:`+ field when you have a simple linked image.+ + Don't add `:align: center` to figures.++ * Texinfo writer: Fixed internal cross-references.+ Now we insert anchors after each header, and use `@ref` instead of `@uref`+ for links. Commas are now escaped as `@comma{}` only when needed;+ previously all commas were escaped. (This change is needed, in part,+ because `@ref` commands must be followed by a real comma or period.) Also+ insert a blank line in from of `@verbatim` environments.++ * DocBook writer:++ + Made --id-prefix work in DocBook as well as HTML.+ Closes #607.+ + Don't include empty captions in figures. Closes #581.++ * LaTeX writer:++ + Use `\hspace*` for nonbreaking space after line break,+ since `~` spaces after a line break are just ignored.+ Closes #687.+ + Don't escape `_` in URLs or hyperref identifiers.+ + Properly escape strings inside \url{}. Closes #576.+ + Use `[fragile]` only for slides containing code rendered+ using listings. Closes #649.+ + Escape `|` as `\vert` in LaTeX math. This avoids a clash with+ highlighting-kate's macros, which redefine `|` as a short verbatim+ delimiter. Thanks to Björn Peemöller for raising this issue.+ + Use minipage rather than parbox for block containers in tables.+ This allows verbatim code to be included in grid tables.+ Closes #663.+ + Prevent paragraphs containing only linebreaks or spaces.++ * HTML writer:++ + Included `highlighting-css` for code spans, too.+ Previously it was only included if used in a code block. Closes #653.+ + Improved line breaks with `<dd>` tags. We now put a newline between+ `</dd>` and `<dd>` when there are multiple definitions.+ + Changed mathjax cdn url so it doesn't use https. (This caused+ problems when used with `--self-contained`.) See #609.++ * EPUB writer:++ + `--number-sections` now works properly.+ + Don't strip meta and link elements in epub metadata.+ Patch from aberrancy. Closes #589.+ + Fixed a couple validation bugs.+ + Use ch001, ch002, etc. for chapter filenames. This improves sorting+ of chapters in some readers, which apparently sort ch2 after ch10.+ Closes #610.++ * ODT writer: properly set title property (Arlo O'Keeffe).++ * Docx writer:++ + Fixed bug with nested lists. Previously a list like++ 1. one+ - a+ - b+ 2. two++ would come out with a bullet instead of "2."+ Thanks to Russell Allen for reporting the bug.+ + Use `w:cr` in `w:r` instead of `w:br` for linebreaks.+ This seems to fix a problem viewing pandoc-generated+ docx files in LibreOffice.+ + Use integer ids for bookmarks. Closes #626.+ + Added nsid to abstractNum elements. This helps when merging+ word documents with numbered or bulleted lists. Closes #627.+ + Use separate footnotes.xml for notes.+ This seems to help LibreOffice convert the file, even though+ it was valid docx before. Closes #637.+ + Use rIdNN identifiers for r:embed in images.+ + Avoid reading image files again when we've already processed them.+ + Fixed typo in `referenc.docx` that prevented image captions from+ working. Thanks to Huashan Chen.++ * `Text.Pandoc.Parsing`:++ + Fixed bug in `withRaw`, which didn't correctly handle the case+ where nothing is parsed.+ + Made `emailAddress` parser more correct. Now it is based on RFC 822,+ though it still doesn't implement quoted strings in email addresses.+ + Revised URI parser. It now allows many more schemes, allows+ uppercase URIs, and better handles trailing punctuation and+ trailing slashes in bare URIs. Added many tests.+ + Simplified and improved singleQuoteStart. This makes `'s'`, `'l'`,+ etc. parse properly. Formerly we had some English-centric heuristics,+ but they are no longer needed. Closes #698.++ * `Text.Pandoc.Pretty`: Added wide punctuation range to `charWidth`.+ This fixes bug with Chinese commas in markdown and reST tables, and+ a bug that caused combining characters to be dropped.++ * `Text.Pandoc.MIME`: Added MIME types for .wof and .eot. Closes #640.++ * `Text.Pandoc.Biblio`:++ + Run `mvPunc` and `deNote` on metadata too.+ This fixed a bug with notes on titles using footnote styles.+ + Fixed bug in fetching CSL files from CSL data directory.++ * `pandoc.hs`: Give correct value to `writerSourceDirectory` when a URL+ is provided. It should be the URL up to the path.++ * Fixed/simplified diff output for tests.+ Biblio: Make sure mvPunc and deNote run on metadata too.+ This fixed a bug with notes on titles using footnote styles.++ [under the hood improvements]++ * We no longer depend on `utf8-string`. Instead we use functions+ defined in `Text.Pandoc.UTF8` that use `Data.Text`'s conversions.++ * Use `safeRead` instead of using `reads` directly (various modules).++ * "Implicit figures" (images alone in a paragraph) are now handled+ differently. The markdown reader gives their titles the prefix `fig:`; the+ writers look for this before treating the image as a figure. Though this+ is a bit of a hack, it has two advantages: (i) implicit figures can be+ limited to the markdown reader, and (ii) they can be deactivated by turning+ off the `implicit_figures` extension.++ * `catch` from `Control.Exception` is now used instead of the+ old Preface `catch`.++ * `Text.Pandoc.Shared`: Improved algorithm for `normalizeSpaces`+ and `oneOfStrings` (which is now non-backtracking).++ * `Text.Pandoc.Biblio`: Remove workaround for `toCapital`.+ Now citeproc-hs is fixed upstream, so this is no longer needed.+ Closes #531.++ * Textile reader: Improved speed of `hyphenedWords`.+ This speeds up the textile reader by about a factor of 4.++ * Use `Text.Pandoc.Builder` in RST reader, for more flexibility,+ better performance, and automatic normalization.++ * Major rewrite of markdown reader:++ + Use `Text.Pandoc.Builder` instead of lists. This also+ means that everything is normalized automatically.+ + Move to a one-pass parsing strategy, returning values in the reader+ monad, which are then run (at the end of parsing) against the final+ parser state.++ * In HTML writer, we now use `toHtml` instead of pre-escaping.+ We work around the problem that blaze-html unnecessarily escapes `'`+ by pre-escaping just the `'` characters, instead of the whole string.+ If blaze-html later stops escaping `'` characters, we can simplify+ `strToHtml` to `toHtml`. Closes #629.++ * Moved code for embedding images in RTFs from `pandoc.hs` to the+ RTF writer (which now exports `writeRTFWithEmbeddedImages`).++ * Moved citation processing from `pandoc.hs` into the readers.+ This makes things more convenient for library users.++ * The man pages are now built by an executable `make-pandoc-man-pages`,+ which has its own stanza in the cabal file so that dependencies can be+ handled by Cabal. Special treatment in `Setup.hs` ensures that this+ executable never gets installed; it is only used to create the man pages.++ * The cabal file has been modified so that the pandoc library is used+ in building the pandoc executable. (This required moving `pandoc.hs`+ from `src` to `.`.) This cuts compile time in half.++ * `-O2` is no longer used in building pandoc. The performance improvement+ it yields is so slight that it is not worth it. (Measured with+ benchmarks on ghc 7.4.)++ * The `executable` and `library` flags have been removed.++ * `-threaded` has been removed from ghc-options.++ * Version bounds of dependencies have been raised, and the+ `blaze_html_0_5` flag now defaults to True. Pandoc now compiles on+ GHC 7.6.++ * We now require base >= 4.2.++ * Integrated the benchmark program into cabal. One can now do:++ cabal configure --enable-benchmarks && cabal build+ cabal bench --benchmark-option='markdown' --benchmark-option='-s 20'++ The benchmark now uses README + testsuite, so benchmark results+ from older versions aren't comparable.++ * Integrated test suite with cabal.+ To run tests, configure with `--enable-tests`, then `cabal test`.+ You can specify particular tests using `--test-options='-t markdown'`.+ No output is shown unless tests fail. The Haskell test modules+ have been moved from `src/` to `tests/`.++ * Moved all data files and templates to the `data/` subdirectory.++ * Added an `embed_data_files` cabal flag. This causes all+ data files to be embedded in the binary, so that the binary+ is self-sufficient and can be relocated anywhere, copied on+ a USB key, etc. The Windows installer now uses this.+ (Since we no longer have the option to build the executable+ without the library, this is the only way to get a relocatable+ binary on Windows.)++ * Removed pcre3.dll from windows package.+ It isn't needed unless highlighting-kate is compilled with the+ `pcre-light` flag. By default, regex-prce-builtin is used.+++pandoc (1.9.4.2)++ * Don't encode/decode file paths if base >= 4.4.+ Prior to base 4.4, filepaths and command line arguments were treated+ as unencoded lists of bytes, not unicode strings, so we had to work+ around that by encoding and decoding them. This commit adds CPP+ checks for the base version that intelligibly enable encoding/decoding+ when needed. Fixes a bug with multilingual filenames when pandoc was+ compiled with ghc 7.4 (#540).++ * Don't generate an empty H1 after hrule slide breaks.+ We now use a slide-level header with contents `[Str "\0"]` to mark+ an hrule break. This avoids creation of an empty H1 in these+ contexts. Closes #484.++ * Docbook reader: Added support for "bold" emphasis. Thanks to mb21.++ * In make_osx_package.sh, ensure citeproc-hs is built with the+ embed_data_files flag.++ * MediaWiki writer: Avoid extra blank lines after sublists (Gavin Beatty).++ * ConTeXt writer: Don't escape `&`, `^`, `<`, `>`, `_`,+ simplified escapes for `}` and `{` to `\{` and `\}` (Aditya Mahajan).++ * Fixed handling of absolute URLs in CSS imports with `--self-contained`.+ Closes #535.++ * Added webm to mime types. Closes #543.++ * Added some missing exports and tests to the cabal file+ (Alexander V Vershilov).++ * Compile with `-rtsopts` and `-threaded` by default.++pandoc (1.9.4.1)++ * Markdown reader: Added `cf.` and `cp.` to list of likely abbreviations.++ * LaTeX template: Added `linkcolor`, `urlcolor` and `links-as-notes`+ variables. Make TOC links black.++ * LaTeX template improvements.++ + Don't print date unless one is given explicitly in the document.+ + Simplified templates.+ + Use fontenc [T1] by default, and lmodern.+ + Use microtype if available.++ * Biblio:++ + Add comma to beginning of bare suffix, e.g. `@item1 [50]`.+ Motivation: `@item1 [50]` should be as close as possible to+ `[@item1, 50]`.+ + Added workaround for a bug in citeproc-hs 0.3.4 that causes footnotes+ beginning with a citation to be empty. Closes #531.++ * Fixed documentation on mixed lists. Closes #533.++pandoc (1.9.4)++ * Simplified `Text.Pandoc.Biblio` and fixed bugs with citations inside+ footnotes and captions. We now handle note citations by inserting+ footnotes during initial citation processing, and doing a separate+ pass later to remove notes inside notes.++ * Added 'zenburn' highlight style from highlighting-kate.++ * Added Slideous writer. Slideous is an HTML + javascript slide show+ format, similar to Slidy, but works with IE 7. (Jonas Smedegaard)++ * LaTeX writer:++ + Ensure we don't have extra blank lines at ends of cells.+ This can cause LaTeX errors, as they are interpreted as new paragraphs.+ + More consistent interblock spacing.+ + Require highlighting-kate >= 0.5.1, for proper highlighted inline+ code in LaTeX. Closes #527.+ + Ensure that a Verbatim at the end of a footnote is followed by+ a newline. (Fixes a regression in the previous version.)+ + In default template, use black for internal links and TOC.+ Added commented-out code to use footnotes for links, as would+ be suitable in print output.++ * Beamer writer: When `--incremental` is used, lists inside+ a block quote should appear all at once. (This makes Beamer+ output consistent with the HTML slide show formats.)++ * ConTeXt writer:++ + Escape `%` as `\letterpercent{}` not `\letterpercent `,+ to avoid gobbling spaces after the `%` sign.+ + Ensure space after `\stopformula`.++ * Markdown writer:++ + Use `:` form instead of `~` in definition lists, for better+ compatibility with other markdown implementations.+ + Don't wrap the term, because it breaks definition lists.+ + Use a nonzero space to prevent false recognition+ of list marker in ordered lists. Closes #516.++ * Org writer: Add space before language name. Closes #523.++ * Docx writer: Simplified bullet characters so they work properly+ with Word 2007. Closes #520.++ * LaTeX reader: Support `\centerline`.++ * RST reader: handle figures. Closes #522.++ * Textile reader: fix for `<notextile>` and `==`. Closes #517.+ (Paul Rivier)++pandoc (1.9.3)++ * Fixed bug in `fromEntities`. The previous version would turn+ `hi & low you know;` into `hi &`.++ * HTML reader:++ + Don't skip nonbreaking spaces.+ Previously a paragraph containing just ` ` would be rendered+ as an empty paragraph. Thanks to Paul Vorbach for pointing out the bug.+ + Support `<col>` and `<caption>` in tables. Closes #486.++ * Markdown reader:++ + Don't recognize references inside delimited code blocks.+ + Allow list items to begin with lists.++ * Added basic docbook reader (John MacFarlane and Mauro Bieg).++ * LaTeX reader:++ + Handle `\bgroup`, `\egroup`, `\begingroup`, `\endgroup`.+ + Control sequences can't be followed by a letter.+ This fixes a bug where `\begingroup` was parsed as `\begin`+ followed by `group`.+ + Parse 'dimension' arguments to unknown commands. e.g. `\parindent0pt`+ + Make `\label` and `\ref` sensitive to `--parse-raw`.+ If `--parse-raw` is selected, these will be parsed as raw latex+ inlines, rather than bracketed text.+ + Don't crash on unknown block commands (like `\vspace{10pt}`)+ inside `\author`; just skip them. Closes #505.++ * Textile reader:++ + Implemented literal escapes with `==` and `<notextile>`. Closes #473.+ + Added support for LaTeX blocks and inlines (Paul Rivier).+ + Better conformance to RedCloth inline parsing (Paul Rivier).+ + Parse '+text+' as emphasized (should be underlined, but this+ is better than leaving literal plus characters in the output.++ * Docx writer: Fixed multi-paragraph list items. Previously they each+ got a list marker. Closes #457.++ * LaTeX writer:++ + Added `--no-tex-ligatures` option to avoid replacing+ quotation marks and dashes with TeX ligatures.+ + Use `fixltx2e` package to provide '\textsubscript'.+ + Improve spacing around LaTeX block environments:+ quote, verbatim, itemize, description, enumerate.+ Closes #502.+ + Use blue instead of pink for URL links in latex/pdf output.++ * ConTeXt writer: Fixed escaping of `%`.+ In text, `%` needs to be escaped as `\letterpercent`, not `\%`+ Inside URLs, `%` needs to be escaped as `\%`+ Thanks to jmarca and adityam for the fix. Closes #492.++ * Texinfo writer: Escape special characters in node titles.+ This fixes a problem pointed out by Joost Kremers. Pandoc used+ to escape an '@' in a chapter title, but not in the corresponding+ node title, leading to invalid texinfo.++ * Fixed document encoding in texinfo template.+ Resolves Debian Bug #667816.++ * Markdown writer:++ + Don't force delimited code blocks to be flush left.+ Fixes bug with delimited code blocks inside lists etc.+ + Escape `<` and `$`.++ * LaTeX writer: Use `\hyperref[ident]{text}` for internal links.+ Previously we used `\href{\#ident}{text}`, which didn't work on+ all systems. Thanks to Dirk Laurie.++ * RST writer: Don't wrap link references. Closes #487.++ * Updated to use latest versions of blaze-html, mtl.+++pandoc (1.9.2)++ * LaTeX reader:++ + Made `lstlisting` work as a proper verbatim environment.+ + Fixed bug parsing LaTeX tables with one column.++ * LaTeX writer:++ + Use `{}` around `ctable` caption, so that formatting can be used.+ + Don't require eurosym package unless document has a €.++ * LaTeX template: Added variables for `geometry`, `romanfont`,+ `sansfont`, `mathfont`, `mainfont` so users can more easily+ customize fonts.++ * PDF writer:++ + Run latex engine at least two times, to ensure+ that PDFs will have hyperlinked bookmarks.+ + Added PDF metadata (title,author) in LaTeX standalone + PDF output.++ * Texinfo writer: retain directories in image paths. (Peter Wang)++ * RST writer: Better handling of inline formatting, in accord+ with docutils' "inline markup recognition rules" (though we don't+ implement the unicode rules fully). Now `hi*there*hi` gets+ rendered properly as `hi\ *there*\ hi`, and unnecessary+ `\ ` are avoided around `:math:`, `:sub:`, `:sup:`.++ * RST reader:++ + Parse `\ ` as null, not escaped space.+ + Allow `` :math:`...` `` even when not followed by blank+ or `\`. This does not implement the complex rule docutils follows,+ but it should be good enough for most purposes.+ + Add support for the rST default-role directive. (Greg Maslov)++ * Text.Pandoc.Parsing: Added `stateRstDefaultRole` field to `ParserState`.+ (Greg Maslov)++ * Markdown reader: Properly handle citations nested in other inline+ elements.++ * Markdown writer: don't replace empty alt in image with "image".++ * DZSlides: Updated template.html and styles in default template.+ Removed bizarre CSS for `q` in dzslides template.++ * Avoid repeated `id` attribute in section and header in HTML slides.++ * README improvements: new instructions on internal links,+ removed misleading note on reST math.++ * Build system:++ + Fixed Windows installer so that dzslides works.+ + Removed stripansi.sh.+ + Added .travis.yml for Travis continuous integration support..+ + Fixed upper bound for zlib (Sergei Trofimovich).+ + Fixed upper bound for test-framework.+ + Updated haddocks for haddock-2.10 (Sergei Trofimovich).++pandoc (1.9.1.2)++ * Added `beamer+lhs` as output format.++ * Don't escape `<` in `<style>` tags with `--self-contained`.+ This fixes a bug which prevented highlighting from working+ when using `--self-contained`.++ * PDF: run latex engine three times if `--toc` specified.+ This fixes page numbers in the table of contents.++ * Docx writer: Added TableNormal style to tables.++ * LaTeX math environment fixes. `aligned` is now used instead of+ the nonexistent `aligned*`. `multline` instead of the nonexistent+ `multiline`.++ * LaTeX writer: Use `\textasciitilde` for literal `~`.++ * HTML writer: Don't escape contents of EQ tags with --gladtex.+ This fixes a regression from 1.8.++ * Use `<q>` tags for Quoted items for HTML5 output.+ The quote style can be changed by modifying the template+ or including a css file. A default quote style is included.++ * LaTeX reader: Fixed accents (\~{a}, `\c{c}`).+ Correctly handle \^{}. Support "minted" as a LaTeX verbatim block.++ * Updated LaTeX template for better language support.+ Use `polyglossia` instead of `babel` with xetex.+ Set `lang` as documentclass option.+ `\setmainlanguage` will use the last of a comma-separated+ list of languages. Thanks to François Gannaz.++ * Fixed default LaTeX template so `\euro` and `€` work. The+ `eurosym` package is needed if you are using pdflatex.++ * Fixed escaping of period in man writer (thanks to Michael Thompson).++ * Fixed list label positions in beamer.++ * Set `mainlang` variable in context writer.+ This parallels behavior of latex writer. `mainlang` is the last+ of a comma-separated list of languages in lang.++ * EPUB language metadat: convert e.g. `en_US` from locale to `en-US`.++ * Changed `-V` so that you can specify a key without a value.+ Such keys get the value `true`.++ * Fixed permissions on installed man pages - thanks Magnus Therning.++ * Windows installer: require XP or higher. The installer is+ now compiled on a Windows 7 machine, which fixes a problem+ using citation functions on Windows 7.++ * OSX package: Check for 64-bit Intel CPU before installing.++pandoc (1.9.1.1)++ * Better handling of raw latex environments in markdown. Now++ \begin{equation}+ a_1+ \end{equation}++ turns into a raw latex block as expected.++ * Improvements to LaTeX reader:++ + Skip options after block commands.+ + Correctly handle `{\\}` in braced.+ + Added a needed 'try'.+ + Citations: add `, ` to suffix if it doesn't start with space or+ punctuation. Otherwise we get no space between the year and the+ suffix in author-date styles.++ * Added two needed data files for S5. This fixes a problem with+ `pandoc -t s5 --self-contained`. Also removed `slides.min.js`,+ which was no longer being used.++ * Fixed some minor problems in `reference.docx`:+ name on "Date" style, `xCs` instead of `xIs`.++ * Fixed a problem creating docx files using a reference docx+ modified using Word. The problem seems to be that Word+ modifies `_rels/.rels`, changing the Type of the Relationship to+ `docProps/core.xml`. Pandoc now changes this back to the correct+ value if it has been altered, fixing the problem.++ * Fixed html5 template so it works properly with highlighting.++pandoc (1.9.1)++ * LaTeX reader:++ + Fixed regression in 1.9; properly handle escaped $ in latex math.+ + Put LaTeX verse environments in blockquotes.++ * Markdown reader:++ + Limit nesting of strong/emph. This avoids exponential lookahead+ in parasitic cases, like `a**a*a**a*a**a*a**a*a**a*a**a*a**a*a**`.+ + Improved attributes syntax (inn code blocks/spans):+ (1) Attributes can contain line breaks. (2) Values in key-value+ attributes can be surrounded by either double or single quotes, or+ left unquoted if they contain no spaces.++ * Don't wrap headers in markdown or RST writers.++ * Added `stateMaxNestingLevel` to `ParserState`.+ We set this to 6, so you can still have `Emph` inside `Emph`,+ just not indefinitely.++ * More efficient implementation of `nowrap` in `Text.Pandoc.Pretty`.++ * `Text.Pandoc.PDF`: Only run latex twice if `\tableofcontents`+ is present.++ * Require highlighting-kate >= 0.5.0.2, texmath >= 0.6.0.2.++pandoc (1.9.0.5)++ * Changed cabal file so that build-depends for the test program+ are not required unless the tests flag is used.++ * LaTeX writer: insert `{}` between adjacent hyphens so they don't+ form ligatures (dashes) in code spans.++pandoc (1.9.0.4)++ * Raised version bound on test-framework to avoid problems+ compiling tests on GHC 7.4.1.++ * LaTeX reader: Use raw LaTeX as fallback inline text for Cites,+ so citations don't just disappear unless you process with+ citeproc. Ignore `\bibliographystyle`, `\nocite`.++ * Simplified tex2pdf; it will always run latex twice to+ resolve table of contents and hyperrefs.++pandoc (1.9.0.3)++ * Require Cabal >= 1.10.+ * Tweaked cabal file to meet Cabal 1.10 requirements.++pandoc (1.9.0.2)++ * Allow build with json 0.4 or 0.5. Otherwise we can't build with+ ghc 6.12.++pandoc (1.9)++ [new features]++ * Added a Microsoft Word `docx` writer. The writer includes support+ for highlighted code and for math (which is converted from TeX to OMML,+ Office's native math markup language, using texmath's new OMML module).+ A new option `--reference-docx` allows the user to customize the+ styles.++ * Added an `asciidoc` writer (<http://www.methods.co.nz/asciidoc/>).++ * Better support for slide shows:++ + Added a `dzslides` writer. DZSlides is a lightweight HTML5/javascript+ slide show format due to Paul Rouget (<http://paulrouget.com/dzslides/>).++ + Added a LaTeX `beamer` writer. Beamer is a LaTeX package for creating+ slide presentations.++ + New, flexible rules for dividing documents into sections and slides+ (see the "Structuring the slide show" in the User's Guide). These+ are backward-compatible with the old rules, but they allow slide+ shows to be organized into sections and subsections containing+ multiple slides.++ + A new `--slide-level` option allows users to override defaults+ and select a slide level below the first header level with content.++ * A new `--self-contained` option produces HTML output that does not+ depend on an internet connection or the presence of any external+ files. Linked images, CSS, and javascript is downloaded (or fetched+ locally) and encoded in `data:` URIs. This is useful for making portable+ `HTML slide shows. The --offline` option has been deprecated and is now+ `treated as a synonym or --self-contained`.++ * Support for PDF output:++ + Removed the old `markdown2pdf`.+ + `pandoc` can now create PDFs (assuming you have latex and a set of+ appropriate packages installed): just specify an output file with the+ `.pdf` extension.+ + A new option `--latex-engine` allows you to specify `pdflatex`,+ `xelatex`, or `lualatex` as the processor.++ * Highlighting changes:++ + Syntax highlighting is now a standard feature; the `highlighting`+ flag is no longer needed when compiling.+ + A new `--no-highlight` option allows highlighting to be disabled.+ + Highlighting now works in `docx`, `latex`, and `epub`, as well as+ `html`, `html5`, `dzslides`, `s5`, and `slidy`.+ + A new `--highlight-style` option selects between various highlighting+ color themes.++ * Internal links to sections now work in ConTeXt and LaTeX as well as HTML.++ * LaTeX `\include` and `\usepackage` commands are now processed,+ provided the files are in the working directory.++ * EPUB improvements:++ + Internal and external links now work in EPUB.+ + Raw HTML is allowed.+ + New `--epub-embed-font` option.+ + Customizable templates for EPUB pages offer more control over+ formatting: `epub-page.html`, `epub-coverimage.html`,+ `epub-titlepage.html`.++ * `--mathml` now works with DocBook.++ * Added support for math in RST reader and writer. Inline math uses the+ `` :math:`...` `` construct. Display math uses++ .. math:: ...++ or if the math is multiline,++ .. math::++ ...++ These constructions are now supported now by `rst2latex.py`.++ * Github syntax for fenced code blocks is supported in pandoc's+ markdown. You can now write++ ```ruby+ x = 2+ ```++ instead of++ ~~~ {.ruby}+ x = 2+ ~~~~++ * Easier scripting: a new `toJsonFilter` function makes it easier to+ write Haskell scripts to manipulate the Pandoc AST.++ [behavior changes]++ * Fixed parsing of consecutive lists in markdown.+ Pandoc previously behaved like Markdown.pl for consecutive+ lists of different styles. Thus, the following would be parsed+ as a single ordered list, rather than an ordered list followed+ by an unordered list:++ 1. one+ 2. two++ - one+ - two++ This change makes pandoc behave more sensibly, parsing this as+ two lists. Any change in list type (ordered/unordered) or in+ list number style will trigger a new list. Thus, the following+ will also be parsed as two lists:++ 1. one+ 2. two++ a. one+ b. two++ Since we regard this as a bug in Markdown.pl, and not something+ anyone would ever rely on, we do not preserve the old behavior+ even when `--strict` is selected.++ * Dashes work differently with `--smart`: `---` is always em-dash,+ and `--` is always en-dash. Pandoc no longer tries to guess when+ `-` should be en-dash. *Note:* This may change how existing documents+ look when processed with pandoc. A new option, `--old-dashes`,+ is provided for legacy documents.++ * The markdown writer now uses setext headers for levels 1-2.+ The old behavior (ATX headers for all levels) can be restored+ using the new `--atx-headers` option.++ * Links are now allowed in markdown image captions. They are also+ allowed in links, but will appear there as regular text. So,++ [link with [link](/url)](/url)++ will turn into++ <p><a href="/url">link with link</a></p>++ * Improved handling of citations using `citeproc-hs-0.3.4`.+ Added `--citation-abbreviations` option.++ * Citation keys can no longer end with a punctuation character.+ This means that `@item1.` will be parsed as a citation with key+ 'item1', followed by a period, instead of a citation with key+ 'item1.', as was the case previously.++ * In HTML output, citations are now put in a span with class `citation`.++ * The markdown reader now recognizes DocBook block and inline tags.+ It was always possible to include raw DocBook tags in a markdown+ document, but now pandoc will be able to distinguish block from+ inline tags and behave accordingly. Thus, for example,++ <sidebar>+ hello+ </sidebar>++ will not be wrapped in `<para>` tags.++ * The LaTeX parser has been completely rewritten; it is now much more+ accurate, robust, and extensible. However, there are two important+ changes in how it treats unknown LaTeX. (1) Previously, unknown+ environments became BlockQuote elements; now, they are treated+ as "transparent", so `\begin{unknown}xyz\end{unknown}` is the+ same as `xyz`. (2) Previously, arguments of unknown commands+ were passed through with their braces; now the braces are stripped+ off.++ * `--smart` is no longer selected automatically with `man` output.++ * The deprecated `--xetex` option has been removed.++ * The `--html5`/`-5` option has been deprecated. Use `-t html5`+ instead. `html5` and `html5+lhs` are now separate output formats.++ * Single quotes are no longer escaped in HTML output. They do not+ need to be escaped outside of attributes.++ * Pandoc will no longer transform leading newlines in code+ blocks to `<br/>` tags.++ * The ODT writer now sizes images appropriately, using the image+ size and DPI information embedded in the image.++ * `--standalone` is once again implicitly for a non-text output format+ (ODT, EPUB). You can again do `pandoc test.txt -o test.odt`+ and get a standalone ODT file.++ * The Docbook writer now uses `<sect1>`, `<sect2>`, etc. instead of+ `<section>`.++ * The HTML writer now uses `<del>` for strikeout.++ * In HTML output with `--section-divs`, the classes `section` and+ `level[1,2,..6]` are put on the `div` tags so they can be styled.+ In HTML 5 output with `--section-divs`, the classes+ `level[1,2,...6]` are put on `section` tags.++ * EPUB writer changes:++ + The `lang` variable now sets the language+ in the metadata (if it is not set, we default to the locale).+ + EPUB: UTF-8 is used rather than decimal entities.++ * Added `titleslide` class to title slide in S5 template.++ * In HTML, EPUB, and docx metadata, the date is normalized into+ YYYY-MM-DD format if possible. (This is required for validation.)++ * Attributes in highlighted code blocks are now preserved in HTML.+ The container element will have the classes, id, and key-value attributes+ you specified in the delimited code block. Previously these were stripped+ off.++ * The reference backlink in the HTML writer no longer has a special+ `footnoteBacklink` class.++ * The HTML template has been split into `html` and `html5` templates.++ * Author and date are treated more consistently in HTML templates.+ Authors are now `<h2>`, date `<h3>`.++ * URLs are hyphenated in the ConTeXt writer (B. Scott Michel).++ * In `Text.Pandoc.Builder`, `+++` has been replaced by `<>`.++ [bug fixes]++ * Better support for combining characters and East Asian wide characters+ in markdown and reST.++ * Better handling of single quotes with `--smart`.+ Previously `D'oh l'*aide*` would be parsed with left and right single+ quotes instead of apostrophes. This kind of error is now fixed.++ * Highlighting: Use `reads` instead of `read` for better error handling.+ Fixes crash on `startNum="abc"`.++ * Added blank comment after directives in rst template.++ * Unescape entities in citation `refId`. The `refId`s coming+ from citeproc contain XML numeric entities, and these don't match with the+ citation keys parsed by pandoc. Solution is to unescape them.++ * HTML reader: Fixed bug parsing tables with both thead and tbody.++ * Markdown reader:++ + Better handling of escapes in link URLs and titles.+ + Fixed backslash escapes in reference links.+ + Fixed bug in table/hrule parsing, by checking that the top+ line of a table is not followed by a blank line. This bug caused+ slowdowns on some files with hrules and tables, as pandoc tried to+ interpret the hrules as the tops of multiline tables.+ + Fixed bug in code block attribute parser. Previously the ID attribute+ got lost if it didn't come first. Now attributes can come in any order.++ * RST reader: allow footnotes followed by newline without space characters.++ * LaTeX reader:++ + Ignore empty groups {}, { }.+ + LaTeX reader: Handle \@.+ + LaTeX reader: Don't crash on commands like `\itemsep`.+ + LaTeX reader: Better handling of letter environments.++ * RST writer: Fixed bug involving empty table cells. isSimple was being+ calculated in a way that assumed there were no non-empty cells.++ * ConTeXt writer:++ + Made `--toc` work even without `--number-sections`.+ + Escape # in link URLs.+ + Use buffering for footnotes containing code blocks.+ + Changed 'descr' to 'description', fixed alignment.++ * LaTeX writer:++ + Escape euro character.+ + Don't escape ~ inside href{...}.+ + Escape # in href URLs.+ + Improved detection of book classes. We now check the+ `documentclass` variable, and if that is not set, we look through+ the template itself. Also, we have added the KOMA classes scrreprt+ and scrbook. You can now make a book using+ `pandoc -V documentclass:book mybook.txt -o mybook.pdf`+ + LHS files now set the "listings" variable, so that the definition+ of the `code` environment will be included in the template.+ + Links are colored blue by default (this can be changed by+ modifying `hyperref` settings in the template).+ + Added `lang` variable to LaTeX template.++ * HTML writer:++ + Fixed bug in HTML template with html5 and mathml.+ + Don't use self-closing img, br, hr tags for HTML5.+ + Use `<section>` for footnotes if HTML5.+ + Update HTML templates to use Content-Style-Type meta tag.+ + Use separate variables for meta-date, meta-author.+ This makes footnotes work in author and date fields.+ + Use 'vertical-align:middle' in WebTeX math for better alignment.++ * S5/slidy writer: Make footnotes appear on separate slide at end.++ * MIME: Added 'layout-cache' to getMimeType. This ensures that the+ META-INF/manifest.xml for ODT files will have everything it needs, so+ that ODT files modified by LibreOffice can be used as `--reference-odt`.++ * `Text.Pandoc.Templates`: Return empty string for json template.++ * `Text.Pandoc.Biblio`:++ + Expand citations recursively inside nested inlines.+ + Treat `\160` as space when parsing locator and suffix.+ This fixes a bug with "p. 33" when `--smart` is used. Previously+ the whole "p. 33" would be included in the suffix, with no locator.+ + Put whole author-in-text citation in a Cite. Previously just the+ date and other info went in the Cite.+ + Don't add comma+space to prefix if it ends in punctuation.++ * Updated chicago-author-date.csl. The old version did not work+ properly for edited volumes with no author.++ * EPUB writer:++ + Add date to EPUB titlepage and metadata.+ + Added TOC identifier in EPUB page template.+ + Don't generate superfluous file `cover-image.jpg`.++ [under the hood improvements]++ * Modified `make_osx_package.sh` to use cabal-dev.+ Items are no longer installed as root.+ Man pages are zipped and given proper permissions.++ * Modified windows installer generater to use cabal-dev.++ * Setup: Making man pages now works with cabal-dev (at least on OSX). In+ Setup.hs we now invoke 'runghc' in a way that points it to the correct+ package databases, instead of always falling back to the default user+ package db.++ * Updated to work with GHC 7.4.1.++ * Removed dependency on old-time.++ * Removed dependency on dlist.++ * New slidy directory for "self-contained."++ * TeXMath writer: Use unicode thin spaces for thin spaces.++ * Markdown citations: don't strip off initial space in locator.++ [API changes]++ * Removed `Apostrophe`, `EmDash`, `EnDash`, and `Ellipses`+ from the native `Inline` type in pandoc-types. Now we use `Str`+ elements with unicode.++ * Improvements to `Text.Pandoc.Builder`:++ + `Inlines` and `Blocks` are now newtypes (not synonyms for+ sequences).+ + Instances are defined for `IsString`, `Show`, `Read`, `Monoid`,+ and a new `Listable` class, which allows these to be manipulated+ to some extent like lists. Monoid append includes automatic+ normalization.+ + `+++` has been replaced by `<>` (mappend).++ * Use blaze-html instead of xhtml for HTML generation.+ This changes the type of `writeHtml`.++ * `Text.Pandoc.Shared`:++ + Added `warn` and `err`.+ + Removed `unescapeURI`, modified `escapeURI`.+ (See under [behavior changes], above.)++ * Changes in URI escaping: Previously the readers escaped URIs by+ converting unicode characters to octets and then percent encoding.+ Now unicode characters are left as they are, and `escapeURI` only+ percent-encodes space characters. This gives more readable+ URIs, and works well with modern user agents. URIs are no longer unescaped+ at all on conversion to `markdown`, `asciidoc`, `rst`, `org`.++ * New module `Text.Pandoc.SelfContained`.++ * New module `Text.Pandoc.Docx`.++ * New module `Text.Pandoc.PDF`.++ * Added `writerBeamer` to `WriterOptions`.++ * Added `normalizeDate` to `Text.Pandoc.Shared`.++ * Added `splitStringWithIndices` in `Text.Pandoc.Shared`.+ This is like `splitWithIndices`, but it is sensitive to distinctions+ between wide, combining, and regular characters.++ * `Text.Pandoc.Pretty`:++ + Added `chomp` combinator.+ + Added `beforeNonBreak` combinator. This allows you to include+ something conditionally on it being before a nonblank.+ Used for RST inline math.+ + Added `charWidth` function. All characters marked W or F in the unicode+ spec EastAsianWidth.txt get width 2.+ + Added `realLength`, based on `charWidth`. `realLength` is now+ used in calculating offsets.++ * New module `Text.Pandoc.Slides`, for common functions for breaking+ a document into slides.++ * Removed `Text.Pandoc.S5`, which is no longer needed.++ * Removed `Text.Pandoc.CharacterReferences`. Moved+ `characterReference` to `Text.Pandoc.Parsing`.+ `decodeCharacterReferences` is replaced by `fromEntities`+ in `Text.Pandoc.XML`.++ * Added `Text.Pandoc.ImageSize`. This is intened for use+ in `docx` and `odt` writers, so the size and dpi of images+ can be calculated.++ * Removed `writerAscii` in `WriterOptions`.++ * Added `writerHighlight` to `WriterOptions`.++ * Added `DZSlides` to `HTMLSlideVariant`.++ * `writeEPUB` has a new argument for font files to embed.++ * Added `stateLastStrPos` to `ParserState`. This lets us keep track+ of whether we're parsing the position immediately after a regular+ (non-space, non-symbol) string, which is useful for distinguishing+ apostrophes from single quote starts.++ * `Text.Pandoc.Parsing`:++ + `escaped` now returns a `Char`.+ + Removed `charsInBalanced'`, added a character parser as+ a parameter of `charsInBalanced`. This is needed for+ proper handling of escapes, etc.+ + Added `withRaw`.++ * Added `toEntities` to `Text.Pandoc.XML`.++ * `Text.Pandoc.Readers.LaTeX`:++ + Export `handleIncludes`.+ + Export `rawLaTeXBlock` instead of `rawLaTeXEnvironment'`.++ * Added `ToJsonFilter` class and `toJsonFilter` function to+ `Text.Pandoc`, deprecating the old `jsonFilter` function.++ * `Text.Pandoc.Highlighting`:++ + Removed `highlightHtml`, `defaultHighlightingCss`.+ + Export `formatLaTeXInline`, `formatLaTeXBlock`, and `highlight`, plus+ key functions from highlighting-kate.+ + Changed types of highlighting function. `highlight` returns a+ `Maybe`, not an `Either`.++pandoc (1.8.2.1)++ * Relaxed cabal consntraints for test-framework (S. Trofimovich).++ * Relaxed cabal constraints for pandoc-types.++ * Adjusted Arbitrary instance to help avoid timeouts in tests.++ * Added `Tests.Writers.Markdown` to cabal file.++pandoc (1.8.2)++ * Added script to produce OS X package.++ * Made `templates` directory a git submodule. This should make it+ easier for people to revise their custom templates when the default+ templates change.++ * Changed template naming scheme: `FORMAT.template` -> `default.FORMAT`.+ **Note:** If you have existing templates in `~/.pandoc/templates`, you+ must rename them to conform to the new scheme!++ * Fixed smart quotes bug, now handling `'...hi'` properly.++ * RST reader:++ + Partial support for labeled footnotes.+ + Improved accuracy of `simpleReferenceName` parser.++ * HTML reader:++ + Substitute correct unicode characters for+ characters in the 128..159 range, which are often found even in+ HTML that purports to be UTF-8.++ * LaTeX reader: Handle `\subtitle` command (a subtitle is added+ to the title, after a colon and linebreak). Closes #280.++ * Leaner `reference.odt`.++ * Added unexported module `Text.Pandoc.MIME` for use in+ the ODT writer.++ * ODT writer: Construct `manifest.xml` based on archive contents.+ This fixes a bug in ODTs containing images. Recent versions of+ LibreOffice would reject these as corrupt, because `manifest.xml`+ did not contain a reference to the image files.++ * LaTeX writer:++ + Make verbatim environments flush to avoid spurious+ blank lines. Closes #277.+ + Use `\texttt` and escapes insntead of `\verb!...!`, which+ is too fragile (doesn't work in command arguments).+ + Use `\enquote{}` for quotes if the template includes+ the `csquotes` package. This provides better support for+ local quoting styles. (Thanks to Andreas Wagner for the idea.)++ * ConTeXt writer: Make `\starttyping`/`\stoptyping` flush with+ margin, preventing spurious blank lines.++ * Slidy writer:++ + Use non-minimized version of `slidy.css` with `--offline`+ option, so users can more easily edit it.+ + Also fixed a bug in the CSS that prevented proper centering+ of title (now reported and fixed upstream).++ * S5 writer:++ + Replaced `s5/default/slides.js.{comment,packed}` with+ new compressed `s5/default/slides.min.js`.+ + Use `data:` protocol to embed S5 CSS in `<link>` tags,+ when `--offline` is specified. Using inline CSS didn't+ work with Chrome or Safari. This fixes offline+ S5 on those browsers.++ * HTML writer: Removed English title on footnote backlinks.+ This is incongrous in non-English documents.++ * Docbook writer:++ + Use CALS tables. (Some older docbook software does not work+ well with XHTML tables.) Closes #77.+ + Use `programlisting` tags (instead of `screen`) for code blocks.++ * `markdown2pdf`:++ + Calls latex with `-halt-on-error -interaction nonstopmode` instead+ of `-interaction=batchmode`, which essentially just ignored errors,+ leading to bad results. Better to know when something is wrong.+ + Fixed issues with non-UTF-8 output of `pdflatex`.+ + Better error reporting.++ * `--mathjax` now takes an optional URL argument. If it is not+ provided, pandoc links directly to the (secure) mathjax CDN,+ as now recommended (thanks to dsanson).++ * Deprecated `--xetex` option in `pandoc`. It is no longer needed,+ since the LaTeX writer now produces a file that can be processed by+ `latex`, `pdflatex`, `lualatex`, or `xelatex`.++ * Introduced `--luatex` option to `markdown2pdf`. This causes `lualatex`+ to be used to create the PDF.++ * If a template specified with `--template` is not found, look for it+ in `datadir`. Also, if no extension is provided, supply one based+ on the writer. So now you can put your `special.latex` template in+ `~/.pandoc/templates`, and use it from any directory via+ `pandoc -t latex --template special`.++ * Default template improvements:++ + HTML: Display author and date after title.+ + HTML: Made table of contents more customizable. The container+ for the TOC is now in the template, so users can insert a header+ or other styling. (Thanks to Bruce D'Arcus for the suggestion.)+ + HTML, Slidy, S5: Enclose scripts in CDATA tags.+ + Slidy, S5: Added `s5-url` and `slidy-url` variables, instead of+ hard-coding. If you want to put your slidy files in the slidy+ subdirectory, for example, you can do+ `pandoc -t slidy -V slidy-url=slidy -s`.+ + LaTeX: Use `\and` to separate authors in LaTeX documents (reader+ & writer). Closes #279.+ + LaTeX: Use different `hyperref` options for `xetex`, fixing+ problems with unicode bookmarks (thanks to CircleCode).+ + LaTeX: Removed `ucs` package, use `utf8` rather than `utf8x`+ with `inputenc`. This covers fewer characters but is more+ robust with other packages, and `ucs` is unmaintained. Users+ who need better unicode support should use xelatex or lualatex.++pandoc (1.8.1.2)++ * Added `--epub-cover-image` option.++ * Documented `--biblatex` and `--natbib` options.++ * Allow `--section-divs` with slidy output. Resolves Issue #296.++ * Disallow notes within notes in reST and markdown.+ These previously caused infinite looping and stack overflows.+ For example:++ [^1]++ [^1]: See [^1]++ Note references are allowed in reST notes, so this isn't a full+ implementation of reST. That can come later. For now we need to+ prevent the stack overflows. Partially resolves Issue #297.++ * EPUB writer: Allow non-plain math methods.++ * Forbid ()s in citation item keys. Resolves Issue #304: problems with+ `(@item1; @item2)` because the final paren was being parsed as part of+ the item key.++ * Changed URI parser so it doesn't include trailing punctuation.+ So, in RST, `http://google.com.` should be parsed as a link followed by a+ period. The parser is smart enough to recognize balanced parentheses, as+ often occur in wikipedia links: `http://foo.bar/baz_(bam)`.++ * Markdown+lhs reader: Require space after inverse bird tracks, so that+ HTML tags can be used freely at the left margin of a markdown+lhs document.+ Thanks to Conal Elliot for the suggestion.++ * Markdown reader:++ + Improved emph/strong parsing; fixes bug found by Perry Wagle.+ + Fixed bug in footnote order (reported by CircleCode).++ * RST reader:+ + Fixed bug in in field lists with multi-line items at the+ end of the list.+ + Added parentheses to RST `specialChars`, so+ `(http://google.com)` will be parsed as a link in parens.+ Resolves Issue #291.+ + Allow `|` followed by newline in RST line block.++ * LaTeX reader:+ + Support `\dots`.+ + Gobble option & space after linebreak `\\[10pt]`.++ * Textile reader:+ + Make it possible to have colons after links. (qerub)+ + Make it possible to have colons after links. (Christoffer Sawicki)++ * HTML reader:+ + Skip spaces after `<b>`, `<emph>`, etc.+ + Handle tbody, thead in simple tables. Closes #274.+ + Implicit `Para`s instead of `Plains` in some contexts.++ * OpenDocument writer: Use special `First paragraph` style for+ first paragraph after most non-paragraph blocks. This allows users to+ specify e.g. that only paragraphs after the first paragraph of a block are+ to be indented. Thanks to Andrea Rossato for the patch. Closes #20.++ * LaTeX writer: use `deVerb` on table and picture captions.+ Otherwise LaTeX complains about `\verb` inside command argument.+ Thanks to bbanier for reporting the bug.++ * Markdown writer: Insert HTML comment btw list and indented code block.+ This prevents the code block from being interpreted as part of the list.++ * EPUB writer: Add a meta element specify the cover.+ Some EPUB e-readers, such as the Nook, require a meta element inside the+ OPF metadata block to ensure the cover image is properly displayed.+ (Kelsey Hightower)++ * HTML writer: Use embed tag for images with non-image extensions.+ (e.g. PDFs). Closes #264.++ * LaTeX writer: Improved tables.++ + More space between lines, top-align cells.+ + Use ctable package, which allows footnotes and+ provides additional options.+ + Made cell alignments work in multiline tables.+ + Closes #271, #272.++ * Un-URI-escape image filenames in LaTeX, ConTeXt, RTF, Texinfo.+ Also do this when copying image files into EPUBs and ODTs.+ Closes #263.++ * Changed to github issue tracker.++ * Added failing emph/strong markdown test case due to Perry Wagle.++ * Slidy improvements:+ + Updated to use Slidy2.+ + Fixed bug, unclosed div tag.+ + Added `duration` variable in template.+ Setting this activates the timer.+ + Use 'titlepage' instead of 'cover' for title div.++pandoc (1.8.1.1)++ * `markdown2pdf`: Removed some debugging lines accidentally included+ in the 1.8.1 release. With those lines, the temp directory is created+ in the working directory, and it is not deleted. This fix restores+ the original behavior.++pandoc (1.8.1)++ * Added `--ascii` option. Currently supported only in HTML writer,+ which it causes to use numerical entities instead of UTF-8.++ * EPUB writer: `--toc` now works to provide a table of contents+ at the beginning of each chapter.++ * LaTeX writer: Change figure defaults to `htbp`.+ This prevents "too many unprocessed floats." Resolves+ Issue #285.++ * `Text.Pandoc.UTF8`: Encode filenames even when using recent+ base.++ * `markdown2pdf`: Fixed filename encoding issues. With help from Paulo+ Tanimoto. Resolves Issue #286.++ * HTML writer: Put line breaks in section divs.++ * `Text.Pandoc.Shared`: Make `writerSectionDivs` default to False.++pandoc (1.8.0.3)++ * Fixed Source-repository stanza in cabal file.++pandoc (1.8.0.2)++ * HTML writer:++ + Stringify alt text instead of converting to HTML.+ + Break lines after block elements, not inside tags.+ HTML output now closely resembles that of tidy. Resolves Issue #134.++ * Markdown reader: Fixed bug in footnote block parser (pointed out+ by Jesse Rosenthal). The problem arose when the blank line+ at the end of a footnote block contained indenting spaces.++ * Shared: Improved 'normalize' function so it normalizes Spaces too.+ In normal form, Space elements only occur to separate two non-Space+ elements. So, we never have [Space], or [, ..., Space].++ * Tests:++ + Improved Arbitrary instance.+ + Added timeout for test instances.++ * README:++ + Added section on four-space rule for lists. Resolves Issue #283.+ + Clarified optional arguments on math options.++ * markdown2pdf: Fixed bug with output file extensions.+ Previously `markdown2pdf test.txt -o test.en.pdf` would produce+ `test.pdf`, not `test.en.pdf`. Thanks to Paolo Tanimoto for the fix.++pandoc (1.8.0.1)++ * Revised Interact.hs so that it works with the CPP macros+ in the UTF8 module.++ * Revised Setup.hs so that we don't call MakeManPage.hs unless+ the man pages are out of date.++pandoc (1.8)++ [new features]++ * Support for citations using Andrea Rossato's `citeproc-hs` 0.3.+ You can now write, for example,++ Water is wet [see @doe99, pp. 33-35; also @smith04, ch. 1].++ and, when you process your document using `pandoc`, specifying+ a citation style using `--csl` and a bibliography using `--bibliography`,+ the citation will be replaced by an appropriately formatted+ citation, and a list of works cited will be added to the end+ of the document.++ This means that you can switch effortlessly between different citation+ and bibliography styles, including footnote, numerical, and author-date+ formats. The bibliography can be in any of the following formats: MODS,+ BibTeX, BibLaTeX, RIS, EndNote, EndNote XML, ISI, MEDLINE, Copac, or JSON.+ See the README for further details.++ Citations are supported in the markdown reader, using a special+ syntax, and in the LaTeX reader, using natbib or biblatex syntax.+ (Thanks to Nathan Gass for the natbib and biblatex support.)++ * New `textile` reader and writer. Thanks to Paul Rivier for contributing+ the `textile` reader, an almost complete implementation of the textile+ syntax used by the ruby [RedCloth library](http://redcloth.org/textile).+ Resolves Issue #51.++ * New `org` writer, for Emacs Org-mode, contributed by Puneeth Chaganti.++ * New `json` reader and writer, for reading and writing a JSON+ representation of the native Pandoc AST. These are much faster+ than the `native` reader and writer, and should be used for+ serializing Pandoc to text. To convert between the JSON representation+ and native Pandoc, use `encodeJSON` and `decodeJSON` from+ `Text.JSON.Generic`.++ * A new `jsonFilter` function in `Text.Pandoc` makes it easy+ to write scripts that transform a JSON-encoded pandoc document.+ For example:++ -- removelinks.hs - removes links from document+ import Text.Pandoc+ main = interact $ jsonFilter $ bottomUp removeLink+ where removeLink (Link xs _) = Emph xs+ removeLink x = x++ To use this to remove links while translating markdown to LaTeX:++ pandoc -t json | runghc removelinks.hs | pandoc -f json -t latex++ * Attributes are now allowed in inline `Code` elements, for example:++ In this code, `ulist ! [theclass "special"] << elts`{.haskell} is...++ The attribute syntax is the same as for delimited code blocks.+ `Code` inline has an extra argument place for attributes, just like+ `CodeBlock`. Inline code will be highlighted in HTML output, if pandoc+ is compiled with highlighting support. Resolves Issue #119.++ * New `RawBlock` and `RawInline` elements (replacing `RawHtml`,+ `HtmlInline`, and `TeX`) provide lots of flexibility in writing+ scripts to transform Pandoc documents. Scripts can now change+ how each element is rendered in each output format.++ * You can now define LaTeX macros in markdown documents, and pandoc+ will apply them to TeX math. For example,++ \newcommand{\plus}[2]{#1 + #2}+ $\plus{3}{4}$++ yields `3+4`. Since the macros are applied in the reader, they+ will work in every output format, not just LaTeX.++ * LaTeX macros can also be used in LaTeX documents (both in math+ and in non-math contexts).++ * A new `--mathjax` option has been added for displaying+ math in HTML using MathJax. Resolves issue #259.++ * Footnotes are now supported in the RST reader. (Note, however,+ that unlike docutils, pandoc ignores the numeral or symbol used in+ the note; footnotes are put in an auto-numbered ordered list.)+ Resolves Issue #258.++ * A new `--normalize` option causes pandoc to normalize the AST+ before writing the document. This means that, for example,+ `*hi**there*` will be rendered as `<em>hithere</em>`+ instead of `<em>hi</em><em>there</em>`. This is not the default,+ because there is a significant performance penalty.++ * A new `--chapters` command-line option causes headers+ in DocBook, LaTeX, and ConTeXt to start with "chapter" (level one).+ Resolves Issue #265.++ * In DocBook output, `<chapter>` is now used for top-level+ headers if the template contains `<book>`. Resolves Issue #265.++ * A new `--listings` option in `pandoc` and `markdown2pdf` causes+ the LaTeX writer to use the listings package for code blocks.+ (Thanks to Josef Svennigsson for the pandoc patch, and Etienne+ Millon for the markdown2pdf patch.)++ * `markdown2pdf` now supports `--data-dir`.++ * URLs in autolinks now have class "url" so they can be styled.++ * Improved prettyprinting in most formats. Lines will be wrapped+ more evenly and duplicate blank lines avoided.++ * New `--columns` command-line option sets the column width for+ line wrapping and relative width calculations for tables.++ * Made `--smart` work in HTML, RST, and Textile readers, as well+ as markdown.++ * Added `--html5` option for HTML5 output.++ * Added support for listings package in LaTeX reader+ (Puneeth Chaganti).++ * Added support for simple tables in the LaTeX reader.++ * Added support for simple tables in the HTML reader.++ * Significant performance improvements in many readers and writers.++ [API and program changes]++ * Moved `Text.Pandoc.Definition` from the `pandoc` package to a new+ auxiliary package, `pandoc-types`. This will make it possible for other+ programs to supply output in Pandoc format, without depending on the whole+ pandoc package.++ * Added `Attr` field to `Code`.++ * Removed `RawHtml`, `HtmlInline`, and `TeX` elements; added generic+ `RawBlock` and `RawInline`.++ * Moved generic functions to `Text.Pandoc.Generic`. Deprecated+ `processWith`, replacing it with two functions, `bottomUp` and `topDown`.+ Removed previously deprecated functions `processPandoc` and `queryPandoc`.++ * Added `Text.Pandoc.Builder`, for building `Pandoc` structures.++ * `Text.Pandoc` now exports association lists `readers` and `writers`.++ * Added `Text.Pandoc.Readers.Native`, which exports `readNative`.+ `readNative` can now read full pandoc documents, block lists, blocks,+ inline lists, or inlines. It will interpret `Str "hi"`+ as if it were `Pandoc (Meta [] [] []) [Plain [Str "hi"]]`.+ This should make testing easier.++ * Removed deprecated `-C/--custom-header` option.+ Use `--template` instead.++ * `--biblio-file` has been replaced by `--bibliography`.+ `--biblio-format` has been removed; pandoc now guesses the format+ from the file extension (see README).++ * pandoc will treat an argument as a URI only if it has an+ `http(s)` scheme. Previously pandoc would treat some+ Windows pathnames beginning with `C:/` as URIs.++ * The `--sanitize-html` option and the `stateSanitize` field in+ `ParserState` have been removed. Sanitization is better done in the+ resulting HTML using `xss-sanitize`, which is based on pandoc's+ sanitization, but improved.++ * pandoc now adds a newline to the end of its output in fragment+ mode (= not `--standalone`).++ * Added support for `lang` in `html` tag in the HTML template,+ so you can do `pandoc -s -V lang=es`, for example.++ * `highlightHtml` in `Text.Pandoc.Highlighting` now takes+ a boolean argument that selects between "inline" and+ "block" HTML.++ * `Text.Pandoc.Writers.RTF` now exports `rtfEmbedImage`.+ Images are embedded in RTF output when possible (png, jpeg).+ Resolves Issue #275.++ * Added `Text.Pandoc.Pretty`. This is better suited for pandoc than the+ `pretty` package. Changed all writers that used+ `Text.PrettyPrint.HughesPJ` to use `Text.Pandoc.Pretty` instead.++ * Rewrote `writeNative` using the new prettyprinting module. It is+ now much faster. The output has been made more consistent and compressed.+ `writeNative` is also now sensitive to writerStandalone`, and will simply+ `print a block list if writerStandalone` is False.++ * Removed `Text.Pandoc.Blocks`. `Text.Pandoc.Pretty` allows you to define+ blocks and concatenate them, so a separate module is no longer needed.++ * `Text.Pandoc.Shared`:++ + Added `writerColumns`, `writerChapters`, and `writerHtml5` to+ `WriterOptions`.+ + Added `normalize`.+ + Removed unneeded prettyprinting functions:+ `wrapped`, `wrapIfNeeded`, `wrappedTeX`, `wrapTeXIfNeeded`, `hang'`,+ `BlockWrapper`, `wrappedBlocksToDoc`.+ + Made `splitBy` take a test instead of an element.+ + Added `findDataFile`, refactored `readDataFile`.+ + Added `stringify`. Rewrote `inlineListToIdentifier` using `stringify`.+ + Fixed `inlineListToIdentifier` to treat '\160' as ' '.++ * `Text.Pandoc.Readers.HTML`:++ + Removed `rawHtmlBlock`, `anyHtmlBlockTag`, `anyHtmlInlineTag`,+ `anyHtmlTag`, `anyHtmlEndTag`, `htmlEndTag`, `extractTagType`,+ `htmlBlockElement`, `htmlComment`+ + Added `htmlTag`, `htmlInBalanced`, `isInlineTag`, `isBlockTag`,+ `isTextTag`++ * Moved `smartPunctuation` from `Text.Pandoc.Readers.Markdown`+ to `Text.Pandoc.Readers.Parsing`, and parameterized it with+ an inline parser.++ * Added `nonspaceChar` to `Text.Pandoc.Parsing`.++ * Ellipses are no longer allowed to contain spaces.+ Previously we allowed '. . .', ' . . . ', etc. This caused+ too many complications, and removed author's flexibility in+ combining ellipses with spaces and periods.++ * Allow linebreaks in URLs (treat as spaces). Also, a string of+ consecutive spaces or tabs is now parsed as a single space. If you have+ multiple spaces in your URL, use `%20%20`.++ * `Text.Pandoc.Parsing`:++ + Removed `refsMatch`.+ + Hid `Key` constructor.+ + Removed custom `Ord` and `Eq` instances for `Key`.+ + Added `toKey` and `fromKey` to convert between `Key` and `[Inline]`.+ + Generalized type on `readWith`.++ * Small change in calculation of relative widths of table columns.+ If the size of the header > the specified column width, use+ the header size as 100% for purposes of calculating+ relative widths of columns.++ * Markdown writer now uses some pandoc-specific features when `--strict`+ is not specified: `\` newline is used for a hard linebreak instead of+ two spaces then a newline. And delimited code blocks are used when+ there are attributes.++ * HTML writer: improved gladTeX output by setting ENV appropriately+ for display or inline math (Jonathan Daugherty).++ * LaTeX writer: Use `\paragraph`, `\subparagraph` for level 4,5 headers.++ * LaTeX reader:++ + `\label{foo}` and `\ref{foo}` now become `{foo}` instead of `(foo)`.+ + `\index{}` commands are skipped.++ * Added `fontsize` variable to default LaTeX template.+ This makes it easy to set the font size using `markdown2pdf`:+ `markdown2pdf -V fontsize=12pt input.txt`.++ * Fixed problem with strikeout in LaTeX headers when using+ hyperref, by adding a command to the default LaTeX template+ that disables `\sout` inside pdf strings. Thanks to Joost Kremers+ for the fix.++ * The `COLUMNS` environment variable no longer has any effect.++ [under-the-hood improvements]++ * Pandoc now compiles with GHC 7. (This alone leads to a+ significant performance improvement, 15-20%.)++ * Completely rewrote HTML reader using tagsoup as a lexer. The+ new reader is faster and more accurate. Unlike the+ old reader, it does not get bogged down on some input+ (Issues #277, 255). And it handles namespaces in tags+ (Issue #274).++ * Replaced `escapeStringAsXML` with a faster version.++ * Rewrote `spaceChar` and some other parsers in Text.Pandoc.Parsing+ for a significant performance boost.++ * Improved performance of all readers by rewriting parsers.++ * Simplified Text.Pandoc.CharacterReferences by using+ entity lookup functions from TagSoup.++ * `Text.Pandoc.UTF8` now uses the unicode-aware IO functions+ from `System.IO` if base >= 4.2. This gives support for+ windows line endings on windows.++ * Remove duplications in documentation by generating the+ pandoc man page from README, using `MakeManPage.hs`.++ * README now includes a full description of markdown syntax,+ including non-pandoc-specific parts. A new `pandoc_markdown`+ man page is extracted from this, so you can look up markdown+ syntax by doing `man pandoc_markdown`.++ * Completely revised test framework (with help from Nathan Gass).+ The new test framework is built when the `tests` Cabal flag is set. It+ includes the old integration tests, but also some new unit and quickcheck+ tests. Test output has been much improved, and you can now specify a glob+ pattern after `cabal test` to indicate which tests should be run;+ for example `cabal test citations` will run all the citation tests.++ * Added a shell script, `stripansi.sh`, for filtering ANSI control+ sequences from test output: `cabal test | ./stripansi.sh > test.log`.++ * Added `Interact.hs` to make it easier to use ghci while developing.+ `Interact.hs` loads `ghci` from the `src` directory, specifying+ all the options needed to load pandoc modules (including+ specific package dependencies, which it gets by parsing+ dist/setup-config).++ * Added `Benchmark.hs`, testing all readers + writers using criterion.++ * Added `stats.sh`, to make it easier to collect and archive+ benchmark and lines-of-code stats.++ * Added upper bounds to all cabal dependencies.++ * Include man pages in extra-source-files. This allows users to+ install pandoc from the tarball without needing to build the man+ pages.++ [bug fixes]++ * Filenames are encoded as UTF8. Resolves Issue #252.++ * Handle curly quotes better in `--smart` mode. Previously, curly quotes+ were just parsed literally, leading to problems in some output formats.+ Now they are parsed as `Quoted` inlines, if `--smart` is specified.+ Resolves Issue #270.++ * Text.Pandoc.Parsing: Fixed bug in grid table parser.+ Spaces at end of line were not being stripped properly,+ resulting in unintended LineBreaks.++ * Markdown reader:++ + Allow HTML comments as inline elements in markdown.+ So, `aaa <!-- comment --> bbb` can be a single paragraph.+ + Fixed superscripts with links: `^[link](/foo)^` gets+ recognized as a superscripted link, not an inline note followed by+ garbage.+ + Fixed regression, making markdown reference keys case-insensitive again.+ Resolves Issue #272.+ + Properly handle abbreviations (like `Mr.`) at the end of a line.+ + Better handling of intraword underscores, avoiding exponential+ slowdowns in some cases. Resolves Issue #182.+ + Fixed bug in alignments in tables with blank rows in the header.++ * RST reader:++ + Field lists now allow spaces in field names, and+ block content in field values. (Thanks to Lachlan Musicman+ for pointing out the bug.)+ + Definition list items are now always `Para` instead of+ `Plain`, matching behavior of `rst2xml.py`.+ + In image blocks, the description is parsed properly and+ used for the alt attribute, not also the title.+ + Skip blank lines at beginning of file. Resolves+ Debian #611328.++ * LaTeX reader:++ + Improved parsing of preamble.+ Previously you'd get unexpected behavior on a document that+ contained `\begin{document}` in, say, a verbatim block.+ + Allow spaces between `\begin` or `\end` and `{`.+ + Support `\L` and `\l`.+ + Skip comments inside paragraphs.++ * LaTeX writer:++ + Escape strings in `\href{..}`.+ + In nonsimple tables, put cells in `\parbox`.++ * OpenDocument writer: don't print raw TeX.++ * Markdown writer:++ + Fixed bug in `Image`. URI was getting unescaped twice!+ + Avoid printing extra blank lines at the end if there are+ no notes or references.++ * LaTeX and ConTeXt: Escape `[` and `]` as `{[}` and `{]}`.+ This avoids unwanted interpretation as an optional argument.++ * ConTeXt writer: Fixed problem with inline code. Previously+ `}` would be rendered `\type{}}`. Now we check the string for '}' and '{'.+ If it contains neither, use `\type{}`; otherwise use `\mono{}`+ with an escaped version of the string.++ * `:` now allowed in HTML tags. Resolves Issue #274.++pandoc (1.6)++ [ John MacFarlane ]++ * New EPUB and HTML Slidy writers. (Issue #122)++ - EPUB is a standard ebook format, used in Apple's iBooks for+ the iPad and iPhone, Barnes and Noble's nook reader, the Sony+ reader, and many other devices.+ - Slidy, like S5, is a system for producing HTML+javascript slide+ shows.++ * All input is assumed to be UTF-8, no matter what the locale and ghc+ version, and all output is UTF-8. This reverts to pre-1.5 behavior.+ Also, a BOM, if present, is stripped from the input.++ * Markdown now supports grid tables, whose cells can contain+ arbitrary block elements. (Issue #43)++ * Sequentially numbered example lists in markdown with `@` marker.++ * Markdown table captions can begin with a bare colon and no longer need+ to include the English word "table." Also, a caption can now occur+ either before or after the table. (Issue #227)++ * New command-line options:++ - `--epub-stylesheet` allows you to specify a CSS file that will+ be used to style your ebook.+ - `--epub-metadata` allows you to specify metadata for the ebook.+ - `--offline` causes the generated HTML slideshow to include all+ needed scripts and stylesheets.+ - `--webtex` causes TeX math to be converted to images using the+ Google Charts API (unless a different URL is specified).+ - `--section-divs` causes div tags to be added around each section+ in an HTML document. (Issue #230, 239)++ * Default behavior of S5 writer in standalone mode has changed:+ previously, it would include all needed scripts and stylesheets+ in the generated HTML; now, only links are included unless+ the `--offline` option is used.++ * Default behavior of HTML writer has changed. Between 1.2 and 1.5,+ pandoc would enclose sections in div tags with identifiers on the+ div tags, so that the sections can be manipulated in javascript.+ This caused undesirable interactions with raw HTML div tags. So,+ starting with 1.6, the default is to put the identifiers directly+ on the header tags, and not to include the divs. The `--section-divs`+ option selects the 1.2-1.5 behavior.++ * API changes:++ - `HTMLMathMethod`: Added `WebTeX`, removed `MimeTeX`.+ - `WriterOptions`: Added `writerUserDataDir`, `writerSourceDirectory`,+ `writerEPUBMetadata` fields. Removed `writerIncludeBefore`,+ `writerIncludeAfter`.+ - Added `headerShift` to `Text.Pandoc.Shared`.+ - Moved parsing code and `ParserState` from `Text.Pandoc.Shared`+ to a new module, `Text.Pandoc.Parsing`.+ - Added `stateHasChapters` to `ParserState`.+ - Added `HTMLSlideVariant`.+ - Made `KeyTable` a map instead of an association list.+ - Added accessors for `Meta` fields (`docTitle`, `docAuthors`,+ `docDate`).+ - `Pandoc`, `Meta`, `Inline`, and `Block` have been given `Ord`+ instances.+ - Reference keys now have a type of their own (`Key`), with its+ own `Ord` instance for case-insensitive comparison.+ - Added `Text.Pandoc.Writers.EPUB`.+ - Added `Text.Pandoc.UUID`.+ - Removed `Text.Pandoc.ODT`, added `Text.Pandoc.Writers.ODT`.+ Removed `saveOpenDocumentAsODT`, added `writeODT`.+ - Added `Text.Pandoc.Writers.Native` and `writeNative`.+ Removed `prettyPandoc`.+ - Added `Text.Pandoc.UTF8` for portable UTF8 string IO.+ - Removed `Text.Pandoc.Writers.S5` and the `writeS5` function.+ Moved `s5Includes` to a new module, `Text.Pandoc.S5`.+ To write S5, you now use `writeHtml` with `writerSlideVariant`+ set to `S5Slides` or `SlidySlides`.++ * Template changes. If you use custom templates, please update them,+ particularly if you use syntax highlighting with pandoc. The old HTML+ templates hardcoded highlighting CSS that will no longer work with+ the most recent version of highlighting-kate.++ - HTML template: avoid empty meta tag if no date.+ - HTML template: Use default highlighting CSS from highlighting-kate+ instead of hard-coding the CSS into the template.+ - HTML template: insert-before text goes before the title, and+ immediately after the <body> tag, as documented. (Issue #241)+ - Added slidy and s5 templates.+ - Added amssymb to preamble of latex template. (github Issue 1)++ * Removed excess newlines at the end of output. Note: because output+ will not contain an extra newline, you may need to make adjustments+ if you are inserting pandoc's output into a template.++ * In S5 and slidy, horizontal rules now cause a new slide, so you+ are no longer limited to one slide per section.++ * Improved handling of code in man writer. Inline code is now monospace,+ not bold, and code blocks now use .nf (no fill) and .IP (indented para).++ * HTML reader parses `<tt>` as Code. (Issue #247)++ * html+lhs output now contains bird tracks, even when compiled without+ highlighting support. (Issue #242)++ * Colons are now no longer allowed in autogenerated XML/HTML identifiers,+ since they have a special meaning in XML.++ * Code improvements in ODT writer. Remote images are now replaced with+ their alt text rather than a broken link.++ * LaTeX reader improvements:++ - Made latex `\section`, `\chapter` parsers more forgiving of+ whitespace.+ - Parse `\chapter{}` in latex.+ - Changed `rawLaTeXInline` to accept `\section`, `\begin`, etc.+ - Use new `rawLaTeXInline'` in LaTeX reader, and export `rawLaTeXInline`+ for use in markdown reader.+ - Fixes bug wherein `\section{foo}` was not recognized as raw TeX+ in markdown document.++ * LaTeX writer: images are automatically shrunk if they would extend+ beyond the page margin.++ * Plain, markdown, RST writers now use unicode for smart punctuation.++ * Man writer converts math to unicode when possible, as in other writers.++ * `markdown2pdf` can now recognize citeproc options.++ * Command-line arguments are converted to UTF-8. (Issue #234)++ * `Text.Pandoc.TeXMath` has been rewritten to use texmath's parser.+ This allows it to handle a wider range of formulas. Also, if a formula+ cannot be converted, it is left in raw TeX; formulas are no longer+ partially converted.++ * Unicode curly quotes are left alone when parsing smart quotes. (Issue+ #143)++ * Cabal file changes:++ - Removed parsec < 3 restriction.+ - Added 'threaded' flag for architectures where GHC lacks a threaded+ runtime.+ - Use 'threaded' only for markdown2pdf; it is not needed for pandoc.+ - Require highlighting-kate 0.2.7.++ * Use explicit imports from `Data.Generics`. Otherwise we have a+ conflict with the 'empty' symbol, introduced in syb >= 0.2. (Issue #237)++ * New data files: slidy/slidy.min.js, slidy/slidy.min.css, epub.css.++pandoc (1.5.1.1)++ [ John MacFarlane ]++ * Fixed uniqueIdent in Shared so that header identifiers work as+ advertized in the README and are are valid XHTML names.++pandoc (1.5.1)++ [ John MacFarlane ]++ * Fixed treatment of unicode characters in URIs.+ + Shared now exports escapeURI and unescapeURI. These handle+ UTF8 encoding and decoding as well as URI escaping/unescaping.+ + Shared: uri and emailAddress now return a pair of the original+ parsed text and the escaped URI (in the latter case, with+ the mailto: prefix).+ + HTML reader: unsanitaryURI has been modified to allow unicode+ high characters in a URI.+ + Readers: All link and image URIs are now escaped using+ escapeURI.+ + Markdown and RST writers: unescapeURI is used so that URIs+ in these formats are human-readable.++ * Setup.hs: Don't assume that the build directory is "dist".+ Instead, get it from localBuildInfo.++ * OpenDocument writer: Use a Map for stTextStyleAttr.+ This avoids duplicates (and invalid xml). Resolves Issue #222.++pandoc (1.5.0.1)++ [ John MacFarlane ]++ * HTML writer: Fixed error in math writer (with MathML option)+ that caused an infinite loop for unparsable MathML.++pandoc (1.5)++ [ John MacFarlane ]++ * Added --mathml option. When this is selected, pandoc will convert+ TeX math into MathML.+ + Added data/MathMLinHTML.js, which is included when no URL is+ provided for --mathml. This allows MathML to be displayed (in+ better browsers) as text/html.+ + Removed Text.Pandoc.LaTeXMathML. The module was no longer+ necessary; it was replaced by two lines in pandoc.hs.+ + Replaced LaTeXMathML.js.commend and LaTeXMathML.js.packed with a+ single combined file, LaTeXMathML.js.++ * Added --data-dir option.+ This specifies a user data directory. If not specified, will default+ to ~/.pandoc on unix or Application Data\pandoc on Windows.+ Files placed in the user data directory will override system default+ data files.++ * Added Maybe datadir parameter to readDataFile, saveOpenDocumentAsODT,+ latexMathMLScript, s5HeaderIncludes, and getDefaultTemplate. If+ Nothing, no user directory is searched for an override.++ * Added 'plain' output format. This is similar to markdown, but+ removes links, pictures, inline formatting, and most anything that+ looks even vaguely markupish. The function writePlain is exported by+ Text.Pandoc.Writers.Markdown, with which it shares most of its code.++ * Allow multi-line titles and authors in meta block.+ Titles may span multiple lines, provided continuation lines+ begin with a space character. Separate authors may be put on+ multiple lines, provided each line after the first begins with+ a space character. Each author must fit on one line. Multiple+ authors on a single line may still be separated by a semicolon.+ Based on a patch by Justin Bogner.++ * When given an absolute URI as parameter, pandoc will try to fetch+ the content via HTTP. So you can do:+ 'pandoc -r html -w markdown http://www.fsf.org'+ Adds dependency on HTTP.++ * Made HTML reader much more forgiving.+ + Incorporated idea (from HXT) that an element can be closed+ by an open tag for another element.+ + Javascript is partially parsed to make sure that a <script>+ section is not closed by a </script> in a comment or string.+ + More lenient non-quoted attribute values.+ Now we accept anything but a space character, quote, or <>.+ This helps in parsing e.g. www.google.com!+ + Bare & signs are now parsed as a string. This is a common+ HTML mistake.+ + Skip a bare < in malformed HTML.++ * Removed html2markdown and hsmarkdown.+ + html2markdown is no longer needed, since you can now pass URI+ arguments to pandoc and directly convert web pages. (Note,+ however, that pandoc assumes the pages are UTF8. html2markdown+ made an attempt to guess the encoding and convert them.)+ + hsmarkdown is pointless -- a large executable that could be+ replaced by 'pandoc --strict'.++ * In most writers, an image in a paragraph by itself is now rendered+ as a figure, with the alt text as the caption. (Texinfo, HTML, RST,+ MediaWiki, Docbook, LaTeX, ConTeXt, HTML.) Other images are+ rendered inline.++ * Depend on extensible-exceptions. This allows pandoc to be compiled+ on GHC 6.8.++ * Added --base-header-level option. For example, --base-header-level=2+ will change level 1 headers to level 2, level 2 to level 3, etc.+ Closes Debian #563416.++ * Incomplete support for RST tables (simple and grid).+ Thanks to Eric Kow. Colspans and rowspans not yet supported.++ * Added accessors (docTitle, docAuthors, docDate) to Meta type.++ * MediaWiki writer: format links with relative URLs as wikilinks.+ The new rule: If the link target is an absolute URL, an external+ link is created. Otherwise, a wikilink is created.++ * Text.Pandoc.Shared: Export uniqueIdent, and don't allow tilde in+ identifier. Note: This may break links to sections that involve+ tildes.++ * Markdown(+lhs) reader: handle "inverse bird tracks."+ Inverse bird tracks (<) are used for haskell example code that is not+ part of the literate Haskell program. Resolves Issue #211.++ * LaTeX reader:+ + Recognize '\ ' (interword space).+ + Recognize nonbreaking space '~'.+ + Ignore \section, \pdfannot, \pdfstringdef. Ignore alt title in+ section headers. Don't treat \section as inline LaTeX.+ Resolves Issue #202.+ + LaTeX reader: allow any special character to be escaped.+ Resolves Issue #221.+ + LaTeX reader: treat \paragraph and \subparagraph as level 4, 5+ headers. Resolves Issue #207.++ * Use template variables for include-before/after.+ + These options now imply -s; previously they worked also in fragment+ mode.+ + Users can now adjust position of include-before and include-after+ text in the templates.+ + Default position of include-before moved back (as it was before 1.4)+ before table of contents.+ + Resolves Issue #217.++ * Don't print an empty table header: (all writers).+ Resolves Issue #210.++ * HTML, Docbook writer: Use tbody, thead, and cols in tables.++ * HTML writer: Don't include TOC div if table of contents is empty.++ * Markdown writer: Fixed citations.+ Previously the markdown writer printed raw citation codes, e.g.+ [geach1970], rather than the expanded citations provided by+ citeproc, e.g. (Geach 1970). Now it prints the expanded citations.+ This means that the document produced can be processed as a markdown+ document without citeproc. Thanks to dsanson for reporting, and+ Andrea Rossato for the patch.++ * Improved and simplified title block in context template.+ Previously it caused an error if there was no title.+ This method should also be easier for users to customize.++ * Markdown reader:+ + Treat p., pp., sec., ch., as abbreviations in smart mode.+ + Disallow blank lines in inline code span.+ + Allow footnotes to be indented < 4 spaces.+ This fixes a regression. A test case has been added.+ + Escape spaces in URLs as %20. Previously they were incorrectly+ escaped as +, which is appropriate only for the query part of+ a URL. Resolves Issue #220.+ + Require two spaces after capital letter + period for list item.+ Otherwise "E. coli" starts a list. This might change the semantics+ of some existing documents, since previously the two-space+ requirement was only enforced when the second word started+ with a capital letter. But it is consistent with the existing+ documentation and follows the principle of least surprise.+ Resolves Issue #212.++ * LaTeX template: redefine labelwidth when using enumerate package.+ Otherwise the list labels (numbers) often extend past the left+ margin, which looks bad.++ * Mediawiki writer: Don't print a "== Notes ==" header before+ references. This is too English-centric. Writers can provide their+ own header at the end of the document.++ * Promoted mediawiki headers. '= head =' is now level 1, '== head =='+ level 2, etc. This seems to be correct; it's only by convention+ that wikipedia articles have level 2 headers at most.+ Patch due to Eric Kow.++ * RunTests.hs: Set LANG to a UTF-8 locale. Use 'pandoc --data-dir=' so+ data files don't need to have been installed. This removes the need to+ set HOME.++ * HTML reader:+ + Handle spaces before <html>. Resolves Issue #216.+ + Be forgiving in parsing a bare list within a list.+ The following is not valid xhtml, but the intent is clear:+ <ol>+ <li>one</li>+ <ol><li>sub</li></ol>+ <li>two</li>+ </ol>+ We'll treat the <ol> as if it's in a <li>. Resolves Issue #215.++ * Updated INSTALL instructions. cabal method is now promoted.++ * Updated markdown2pdf man page. It no longer says all pandoc options+ are accepted.++ * README/man pages: Removed advice to pipe through tidy before HTML+ reader. This is obsolete, now that we have a forgiving HTML parser.++ * LaTeX writer: set numbersections template variable, so+ the section numbering options work again.++ * Removed obsolete Makefile.++ * Website: renamed index.txt.in -> index.txt.++ * New batch file to make-windows-installer.+ + Removed old Makefile.windows+ + Added make-windows-installer.bat+ + Modified default installer name in pandoc-setup.iss++ * Removed freebsd and macports directories.+ They are no longer up to date.++ * Setup.hs:+ + Made man page building sensitive to build verbosity.+ + Improved detection of highlighting support in test hook.+ + Install wrapper scripts into cabal bin directory.+ + Also simplified installManpages.+ + Setup.hs: install manpages to mandir. Code borrowed from darcs.++ * Changed default of writerXeTeX to False.++ * HTML writer: don't include empty UL if --toc but no sections.+ Resolves Issue #199.++ * LaTeX writer:++ + If book, report, or memoir documentclass, use \chapter{}+ for first-level headers. Otherwise use \section{}.+ + Removed stLink, link template variable. Reason: we now always+ include hyperref in the template.++ * LaTeX template:++ + Only show \author if there are some.+ + Always include hyperref package. It is used not just for links but+ for toc, section heading bookmarks, footnotes, etc. Also added+ unicode=true on hyperref options.++ * markdown2pdf: always do at least two runs. hyperref bookmarks+ require this.++ * cabal file: Removed unneeded dependency on template-haskell.++ * Windows installer - fixed bug in data file locations.+ Resolves Issue #197.++ * Deprecated --custom-header in documentation.+ Removed old "Custom Headers" section in README.++pandoc (1.4)++ [ John MacFarlane ]++ * Pandoc will now compile with either GHC 6.10 or 6.12.+ + Don't use System.IO.UTF8 when compiling with 6.12+ + Use -fno-warn-unused-do-bind option when compiling with 6.12++ * Replaced old headers with templates. Now users have much more+ control over the way documents appear in --standalone mode,+ and writer code is simplified. Resolves Issues #59, 147.+ Every effort has been made to retain backwards compatibilty.+ So, the --custom-header option should still work as before.++ + Added Text.Pandoc.Templates. This provides functions for+ retrieving default templates and for rendering templates.+ + System templates (in the pandoc data directory) can be+ overridden by user templates in $HOME/.pandoc/templates.+ + Removed Text.Pandoc.DefaultHeaders.+ + Removed data/headers directory.+ + Added templates directory.+ + Added writerTemplate and writerVariables fields to WriterOptions.+ + Removed writerTitlePrefix, writerHeader fields from WriterOptions.+ + Changed --print-default-header to --print-default-template.+ + Added --template option.+ + Added -V/--variable option to set custom template variables.++ * Pandoc no longer requires Template Haskell. Resolves Issue #186.++ + Removed need for TH in ODT module. Instead get reference.odt from+ data file at run time.+ + Removed TH dependency from S5 module. S5 module now exports+ s5HeaderIncludes, which pandoc.hs includes if writer is s5 and+ standalone.+ + Refactored LaTeXMathML not to use TH.++ * Meta is now Meta [Inline] [[Inline]] [Inline] rather than+ Meta [Inline] [String] String. Authors and date in Meta are now lists+ of Inline elements rather than raw strings. This means that they can+ be formatted and can include footnotes. NOTE: This may be a breaking+ change for those using pandoc as a library.++ * Added readDataFile to Text.Pandoc.Shared. This retrieves+ a data file from the user pandoc data directory (~/.pandoc+ on unix), or, if not found there, from the system data+ directory ($CABALDIR/shared/pandoc-VERSION/). All data+ files, including templates, LaTeXMathML.js, s5 styles,+ and reference.odt, can be overridden by the user.++ * s5 files moved from data/ui/default to s5/default.++ * Use unicode instead of entities in HTML and XML output. Resolves+ Issue #163.++ * Prettier HTML footnote references: put anchor inside sup,+ instead of other way. Resolves Issue #191. Thanks to+ infinity0x.++ * Added --xetex option to pandoc and markdown2pdf.+ If --xetex is specified, pandoc produces latex suitable for+ processing by xelatex, and markdown2pdf uses xelatex to create+ the PDF. Resolves Issue #185.++ * RTF writer: multiple authors now occupy multiple paragraphs rather+ than using a line break.++ * Man writer: now the "--after-body" will come after the "AUTHORS"+ section, whereas before it would come before it. This is a+ slight break from backwards compatibility.++ * Added --reference-odt option, so users may customize the styles+ used in pandoc-generated ODT files. Users may also place a+ default reference.odt in the ~\.pandoc directory.++ * ODT writer:+ + Indented and line-broke styles.xml so it can be modified more easily.+ + Omitted some unnecessary style declarations.+ + Don't wrap text in OpenDocument writer. The tags are too long, making+ wrapping ugly and pointless.++ * LaTeX reader: use \\ to separate multiple authors.++ * Markdown reader: use ; as separator between authors.+ This allows you to use ',' within author names: e.g. "John Jones, Jr."++ * S5 writer: use linebreak to separate authors in title page.++ * RST reader: Allow :: before lhs code block. The RST spec requires the+ :: before verbatim blocks. This :: should not be treated as literal+ colons. Resolves Issue #189.++ * Documented pandoc 1.3's new definition list syntax in README.+ (An oversight in the last release.)++ * markdown2pdf.hs:+ + interpret ! in a log as an error line.+ + --toc now works properly.++ * Changes in RunTests.hs:+ + Use the Diff library rather than a local copy of Diff.hs.+ (This vastly increases performance.) This change means that 'cabal+ test' presupposes that the Diff library is installed.+ + Removed tests/Diff.hs from cabal file.+ + Changed RunTests to use local environment. We need at least HOME, so+ pandoc can find its data directory.++ * Updated windows installer to install data files in the app directory.++ * Windows installer now installs portable wrappers hsmarkdown and+ markdown2pdf.++pandoc (1.3)++ [ John MacFarlane ]++ * Added --id-prefix option (Issue #41). This adds a prefix to all+ automatically generated HTML identifiers, which helps prevent+ duplicate identifiers when you're generating a fragment (say a blog+ post).++ * Added --indented-code-classes option. This specifies classes+ to use for indented code blocks. (Patch due to buttock; Issue #87.)++ * --number-sections now affects HTML output as well as ConTeXt and LaTeX+ (Issue #150).++ * Improved syntax for markdown definition lists (Issue #24).+ Definition lists are now more compatible with PHP Markdown Extra.+ + You can have multiple definitions for a term (but still not+ multiple terms).+ + Multi-block definitions no longer need a column before each block+ (indeed, this will now cause multiple definitions).+ + The marker no longer needs to be flush with the left margin,+ but can be indented at or two spaces. Also, ~ as well as :+ can be used as the marker (this suggestion due to David+ Wheeler.)+ + There can now be a blank line between the term and the+ definitions.++ * Better looking simple tables. Resolves Issue #180.+ + Markdown reader: simple tables are now given column widths of 0.+ + Column width of 0 is interpreted as meaning: use default column width.+ + Writers now include explicit column width information only+ for multiline tables. (Exception: RTF writer, which requires+ column widths. In this case, columns are given equal widths,+ adding up to the text width.)+ + Simple tables should now look better in most output formats.++ * Allow markdown tables without headers (Issue #50).+ The new syntax is described in README. Also allow optional line of+ dashes at bottom of simple tables.++ * Compensate for width of final table column (Issue #144).++ * Treat a backslash followed by a newline as a hard line break+ in markdown. Resolves Issue #154. This is a nice alternative+ to markdown's "invisible" way of indicating hardline breaks+ using lines that end with two spaces.++ * Improved performance of markdown reader by ~10% by eliminating the+ need for a separate parsing pass for notes. Raw notes are now stored+ on the first pass (which parses references), then parsed when the+ note is inserted into the AST. The stateNotes field in ParserState+ is now a list of [(String, String)] pairs instead of [(String,+ [Block])].++ * In markdown reader, treat 4 or more * or _ in a row as literal+ text. (Trying to parse long strings of * or _ as strong or emph+ leads to exponential performance problems.)++ * Markdown reader: Use + rather than %20 for spaces in URLs.++ * Fixed htmlComment parser, adding a needed 'try'.++ * Don't print raw HTML in man output.++ * Allow . _ and ~ in header identifiers.++ * Specially mark code blocks that were "literate" in the input.+ They can then be treated differently in the writers. This allows+ authors to distinguish bits of the literate program they are writing+ from source code examples, even if the examples are marked as+ Haskell for highlighting. (Issue #174.)++ * Modified html+lhs output to use "haskell" highlighter instead+ of "literateHaskell". The highlighting module now adds bird tracks+ after highlighting (for HTML output), if the code block has the+ "literate" class. This gives better results, because kate's+ haskell highlighter is much better than the literateHaskell+ highlighter.++ * Fixed handling of footnotes in titles (HTML) and headers (LaTeX).+ (Issue #137.)++ * Support for "..code-block" directive in RST reader. Not core+ RST, but used in Sphinx for code blocks annotated with syntax+ information. Thanks to Luke Plant for the patch.++ * Added "head" to list of block-level HTML tags. Resolves+ Issue #108.++ * Added stripTags to Text.Pandoc.XML. This is used in the HTML writer.++ * Set utf-8 encoding in texinfo headers.++ * Docbook writer: add ids to sections. Use link for internal links.+ (Issue #60.)++ * Blank lines after lists in MediaWiki writer.++ * Properly handle commented-out list items in markdown.+ Resolves Issue #142. Example:++ - a+ <!--+ - b+ -->+ - c++ * Changed heuristic in compactify. compactify has to decide whether a+ Para that ends a list is a Para intentionally, or just because of+ the blank lines at the end of every list. In the latter case the+ Para is turned to a Plain. The old heuristic was: change final Para+ to Plain iff the other items all end in Plain. This produces bad+ results when, for example, an item contains just a Plain and an HTML+ comment, as it does in the list above. The new heuristic: change+ final Para to Plain iff the other items don't contain a Para.++ * Added % as an rst underline character. Resolves Issue #173.++ * Fix inline math parser so that \$ is allowed in math.+ Resolves Issue #169.++ * Translate \int (integral) into unicode when using unicode math+ method. Resolves Issue #177.++ * markdown2pdf.hs improvements:+ + Use System.IO.UTF8.+ + Print error messages on last attempt.+ + Do not create a backup when overwriting a PDF (Issue #166).+ + Accept --longopt=val options.+ + Added man/man1/markdown2pdf.1 to extra-tmp-files in cabal, so that+ it is properly cleaned.++ * Added haddock comments warning that readers assume \n line endings.++ * Updated COPYRIGHT file.++ * Makefile: Changed EXECSBASE so it doesn't pull in hsmarkdown &+ markdown2pdf. Otherwise strip tries to strip shell scripts when you+ install using 'make'.++ * Changed Makefile so it doesn't build Haskell wrappers.++ * Fixed Makefile so it doesn't try to build man pages in build-doc.++ * Install pcre3.dll in Windows install script; this allows us to+ package a version of pandoc with highlighting support.++pandoc (1.2.1)++ [ John MacFarlane ]++ * Fixed regression with --preserveTabs. Brought back optPreserveTabs.+ The trick of setting tabStop to 0 to mean "preserve tabs" had a bad+ side effect: strings of 0 spaces were interpreted as indentation.+ So, with --preserve-tabs, unindented paragraphs were treated as+ code. Resolves Issue #138.++ * HTML writer: wrap sections in divs. Resolves Issue #70.++ + hierarchicalize has been rationalized; it builds a hierarchical+ representation of the document from the headers, and simultaneously+ gives each section a unique identifier based on the heading title.+ + Identifiers are now attached to the divs rather than+ to the headers themselves.+ + Table of content backlinks go to the beginning of the table, rather+ than to the section reference that was clicked.+ + Code for constructing identifiers has been moved to Text.Pandoc.Shared+ from the HTML writer, since it is now consumed only by+ hierarchicalize.+ + In --strict mode, pandoc just prints bare headings, as before+ (unless --toc has been specified).+ + In s5 output, it does not wrap sections in divs, as that seems to+ confuse the s5 javascript.++ * Man writer: break lines at end of each sentence. groff expects this+ and treats '.' and '?' differently when followed by line ending as+ opposed to ordinary space. Also, don't escape periods. Instead, use+ zero-width character \& to avoid unwanted interpretation of periods+ at start of line. Resolves Issue #148.++ * Markdown writer: Added '#' and '>' to list of characters to be+ escaped in markdown output. Removed '<', as it is not an officially+ escapable character. This partially resolves Issue #96.++ * Make --smart the default for man output format. Otherwise we have+ trouble dividing lists of endlines into sentences.++ * DocBook writer: Use language attribute to indicate source language+ in code blocks.++ * RST reader:++ + Allow # to continue list, even if the list was started with an+ explicit marker. For example:++ A. my list+ #. continued++ Resolves Issue #140.+ + Allow continuation lines in line blocks. Also added test cases for+ line blocks for RST reader. Resolves Issue #149.+ + Allow explicit links with spaces in URL: `link <to this>`_++ * Improved LaTeX reader's coverage of math modes. Remove displaymath*+ (which is not in LaTeX) and recognize all the amsmath environments+ that are alternatives to eqnarray, namely equation, equation*,+ gather, gather*, gathered, multline, multline*, align, align*,+ alignat, alignat*, aligned, alignedat, split. Resolves Issue #103.+ Thanks to shreevatsa.public for the patch.++ * Markdown reader:++ + Allow -, _, :, . in markdown attribute names. These are legal in+ XML attribute names.+ + Use non-breaking spaces in abbreviations.+ + Markdown reader: improved efficiency of abbreviation parsing.+ Instead of a separate abbrev parser, we just check for+ abbreviations each time we parse a string. This gives a huge+ performance boost with -S. Resolves Issue #141.++ * Improved efficiency of shared parsers: hexNum, htmlComment,+ whitespace, indentSpaces.++ * Export HTMLMathMethod in Text.Pandoc.++ * Export languagesByExtension in Text.Pandoc.Highlighting.++ * Added new Haskell version of markdown2pdf, due to+ Paulo Tanimoto. This should be more portable than the old+ shell script.++ * Made 'pandoc -v' more explicit about compiler options.+ Resolves Issue #139.++ * pandoc.hs: Made --strict compatible with --standalone, --toc.++ * Use Paths_pandoc to get version number, instead of hard-coding it+ into Text/Pandoc.hs.++pandoc (1.2)++ [ John MacFarlane ]++ * Added support for literate Haskell. lhs support is triggered by+ '+lhs' suffixes in formats. For example, 'latex+lhs' is literate+ Haskell LaTeX. '.lhs' files are treated by default as literate+ markdown.++ + Added stateLiterateHaskell to parser state.+ + Added parser for lhsCodeBlock to Markdown, RST, LaTeX readers.+ + Added parser for |inline lhs| to LaTeX reader.+ + Added writerLiterateHaskell to WriterOptions.+ + Added lhs support to Markdown, RST, LaTeX, HTML writers.+ + Added definition of code environment to LaTeX header.+ + Added tests (run only if highlighting support compiled in).+ + Documented lhs features in man page and README.++ * In Text.Pandoc.Definition, added processWith, processWithM,+ and queryWith, and deprecated processPandoc and queryPandoc+ for these more general functions.++ * Fixed bug in mediawiki writer: improper closing tags in tables.+ Thanks to Benct Philip Jonsson for reporting the bug.++ * Added --email-obfuscation option.++ + Added writer option for email obfuscation.+ + Implemented email obfuscation options in HTML writer.+ + Added option to option parser.+ + Documented in README and pandoc man page.+ + Resolves Issue #97.++ * LaTeX writer: fixed bug with empty table cells.+ Resolves Issue #107. Thanks to rodja.trappe for the patch.++ * Fixed bug with header spacing in Markdown and RST writers.+ A null header (Meta [] [] []) should not cause a blank line+ at the beginning of output. But a blank line is needed between+ a non-null header and the main text.++ * Markdown reader: Relax spacing rules for $$ in display math. Now+ space and newlines are allowed after the opening $$ and before the+ closing $$. However, the display math cannot contain an entirely+ blank line. Resolves Issue #105.++ * Markdown reader: Gobble space after Plain blocks containing only+ raw html inline. Otherwise following header blocks are not parsed+ correctly, since the parser sees blank space before them. Resolves+ Issue #124.++ * Markdown reader: Allow " as well as '' to end a latex double-quote.++ * Conditionally depend on syb and base >= 4 if ghc >= 6.10.+ Resolves Issue #109.++ * Fixed problems in RST and markdown output due to bug in pretty-1.0.1.0++ + Added hang' function to Text.Pandoc.Shared; this will be used instead+ of hang, which doesn't work properly in pretty-1.0.1.0. When pretty+ is upgraded, we can go back to hang.+ See http://article.gmane.org/gmane.comp.lang.haskell.general/16687+ + Use hang' (and some different techniques) in RST and markdown writers.+ Some output is now a bit different.++ * Brought citeproc support up to date for citeproc-hs-0.2.+ (Patch by Andrea Rossato.)++ * Moved all haskell source to src subdirectory. Renamed Main.hs to+ pandoc.hs.++ * Rewrote hsmarkdown in Haskell for portability (src/hsmarkdown.hs).+ For now, keeping the old shell script too.++ * Added TemplateHaskell to Extensions for executable, removed+ -threaded for library. Thanks to duncan.coutts for the bug report.+ Resolves Issue #121.++ * Moved some Extra-Source-Files to Data-Files.++ * Moved tabFilter to Shared.++ * In pandoc.hs, removed optPreserveTabs; instead, tabstop of 0 means+ preserve tabs.++ * Minor code cleanup based on hlint suggestions.++pandoc (1.1)++ [ John MacFarlane ]++ * Main.hs:++ + Changed date on copyright message in Main.hs.+ + Have the '-v' option print syntax highlighting languages+ separated by commas, and wrapped in lines, instead of in five+ columns as before.++ * Added --jsmath option. Resolves Issue #68.++ + Added --jsmath option to Main.hs+ + Added JsMath to HTMLMathMethod in Text.Pandoc.Shared.+ + Handle math appropriately in HTML writer when JsMath selected.+ + Documented the option in README and man page.++ * Text.Pandoc.Shared: Changed compactify to use a better heuristic+ for tight and loose lists. Final Para is changed to Plain if all+ other list items *end* with a Plain block. Addresses Issue #99.++ * HTML reader:++ + Added colons to protocols in unsanitaryURI. Closes Issue #88.+ + HTML reader: Don't interpret contents of <pre> blocks as markdown.+ Added rawVerbatimBlock parser. Resolves Issue #94.++ * Markdown reader:++ + Allow URLs with spaces in them in links and references, but escape+ them as "%20".+ + Allow blank space at the end of horizontal rules.++ * RST reader: Modified 'unknownDirective' parser to handle comment+ blocks correctly, and added tests for comment blocks. Resolves Issue+ #86. Closes Debian Bug #500662.++ * HTML writer:++ + Include classes on tr elements in HTML output:+ "header", "odd", "even". This allows tables to be styled with+ lines in alternating colors. Resolves Issue #91.+ + Enclose all LaTeXMathML bits in <span class="LaTeX">.+ This prevents parts of the document that are not math from being+ interpreted as math by LaTeXMathML.js.++ * OpenDocument and ODT writers: Added support for HorizontalRule elements,+ which were formerly ignored. Resolves Issue #95.++ * Text.Pandoc.Shared: Modified wrappedTeX to eliminate the line break+ between a footnote and immediately following nonspace characters in+ LaTeX and ConTeXt output. (This gets interpreted as a space, which+ is not desired in cases like "text^[note]---".) Resolves Issue #93.++ * Windows installer: Don't require admin privileges to run+ installer. Modified pandoc-setup.iss, and changed modpath.iss to+ modify HKCU path if user lacks admin privileges. Also fixed case+ where oldpath is empty (previously this led to the new path+ beginning with a semicolon).++ * Updated INSTALL instructions for Arch packages and OS X install using+ cabal-install.++ * Removed the (now unneeded) debian directory.+ Removed empty Codec and System directories.++ * Moved odt-styles/ to data/. Removed unneeded variable in Makefile.++ * Modified Setup.hs so that the "test" target returns an error status+ when tests fail, and "build" returns a success status if+ the build succeeds. Resolves Issue #100.++ * Added BUGS to files in tarball.+++pandoc (1.0.0.1)++ [ John MacFarlane ]++ * Removed spurious reference to pdf output format from pandoc(1) man page.++pandoc (1.0)++ [ Andrea Rossato ]++ * Added new OpenDocument writer.++ * Added support for SmallCaps inline element.++ * Added support for integrating pandoc with citeproc-hs.++ + Added Cite element to definition and writers.+ + Added Text.Pandoc.Biblio module+ + Note: This support is included only if the 'citeproc'+ Cabal configuration flag is set.++ * Made Pandoc data structure an instance of Typeable.+ Added new processPandoc and queryPandoc functions, to query+ or transform matching elements in a Pandoc structure.++ [ Peter Wang ]++ * Added new Texinfo writer.++ [ John MacFarlane ]++ * Changes to Texinfo writer:++ + No space between paragraph and following @verbatim (provides more+ pleasing appearance in text formats)+ + Blank line consistently after list environments.+ + Removed deVerb.+ + Use @code instead of @verb for inline code (this solves the character+ escaping problem for texi2dvi and texi2pdf).+ + Added news of Texinfo writer to README.+ + Added Texinfo to list of formats in man page, and removed extra 'groff'.+ + Added texi & texinfo extensions to Main.hs, and fixed bug in determining+ default output extension.+ + Modified disallowedInNode in Texinfo writer to correct list of disallowed characters.++ * Added tests for OpenDocument writer.++ * Added ODT writer (using zip-archive library to package output of+ OpenDocument writer). Added odt-styles directory with default ODT styles.++ * Added new mediawiki writer and tests.++ * Markdown reader: Added support for delimited code blocks, with optional+ syntax highlighting using highlighting-kate (if the 'highlighting'+ configuration option is selected).++ + Currently highlighting is supported only in the HTML writer.+ + Delimited code blocks can have attributes; using the language name as+ class triggers highlighting.+ + New Attributes parameter in CodeBlock structure.+ + --version now indicates whether syntax highlighting support is compiled+ in, and prints a list of supported languages++ * Removed debian directory. Pandoc is no longer a native debian package.++ * Changes to build process: pandoc can now be built from the repository+ using Cabal. No unix tools are needed (so, pandoc can be built on Windows+ without Cygwin).++ + Include shell scripts themselves in repo, rather than generating from wrappers.+ Removed wrappers directory and wrappers Makefile target.+ + Text/Pandoc/ASCIIMathML.hs, Text/Pandoc/DefaultHeaders.hs,+ and Text/Pandoc/Writers/S5.hs are no longer built in Makefile+ from templates in the templates/ directory. Instead, they use template+ haskell to read data at compile time from the relevant files in data/.+ Template haskell functions go in a new module, Text.Pandoc.TH.+ + man pages are now generated in Setup.hs hook, not by Makefile+ + Makefile 'tarball' target now calls Cabal's 'sdist'+ + Added "Extra-Source-Files" to pandoc.cabal, so sdist contains everything needed+ + Added "Build-Type" field to pandoc.cabal to avoid warning.+ + Added to "Extra-source-files" and "Extra-tmp-files" in pandoc.cabal,+ so 'sdist' and 'clean' will work properly.+ + Setup.hs now generates man pages in a postbuild hook.+ + Added dependency-checking to Setup.hs, so it only rebuilds things+ that need rebuilding.+ + Added 'library' and 'executable' configuration flags.+ Cabal can now be told to build just the library or just the executable.+ + CABALOPTS may now be specified with 'make' to pass Cabal configuration flags.+ For example: CABALOPTS=-fhighlighting make++ * Rewrote test suite so it doesn't depend on perl or unix tools.++ + Replaced old runtests.pl with a Haskell script RunTests.hs.+ + Added Diff.hs module to be used by RunTests.hs instead of unix 'diff'.+ + Added test hook to Setup.hs, so tests may be run from cabal.+ + Changed Makefile's 'test' target to run tests via cabal.+ + Removed old generate.sh.+ + Since we no longer have 'sed' to filter out raw HTML sections+ from the docbook writer test, or raw LaTeX sections from the+ context writer test, we now just include these sections.+ They can be taken out if it is necessary to process the files.+ + Updated latex and context writer tests to remove extra spaces+ after '\\item'+ + Added a markdown table reader test.+ + Added markdown-reader-more.txt to test suite, for additional test cases+ for raw ConTeXt environments and more.++ * Compatibility fixes for CPP, Cabal, and haddock:++ + Use CPP in "Extensions" field in pandoc.cabal.+ + Removed use of backslash string continuations in source files.++ * Removed pandoc.cabal.ghc66. We now require Cabal >= 1.2, GHC >= 6.8,+ base >= 3.++ * Require parsec < 3.+ The compatibility module in parsec 3.0.0 gives far worse performance than+ parsec 2.1. Eventually pandoc will be upgraded to use the new bytestring+ version of parsec, and then we'll go to parsec 3.0.0.++ * Removed Text.Regex dependencies by rewriting using plain Haskell+ (Text.Pandoc.Writers.RTF, Text.Pandoc.Writers.HTML, Main.hs)++ * Moved Text.Pandoc.Writers.DefaultHeaders -> Text.Pandoc.DefaultHeaders.++ * Makefile:++ + Added 'configure' as dependency of 'uninstall-all'.+ (It uses the Cabal build program.)+ + Makefile: only use --with-hc-pkg if GHC_PKG is defined.+ Note that Cabal will automatically choose the ghc-pkg appropriate+ for the compiler selected, so normally specifying GHC by itself+ is sufficient.++ * Removed Text.Pandoc.UTF8 module; instead, depend on utf8-string and use+ its IO and conversion functions.++ * Added -Wall to ghc-options in pandoc.cabal. Cleaned up modules so that+ everything is -Wall clean.++ + Added pragma to HTML writer to avoid deprecation warning for use of "start" attribute.+ + Added pragma to Text/Pandoc/Shared.hs to get rid of "orphan instance" warnings.+ (These are caused by the Lift instance for ByteString.)++ * Changed the comment used to replace unsafe HTML if sanitize-html option+ selected.++ * Made -c/--css option repeatable on the command line (like -H, -A, -B).++ * Moved XML-formatting functions to new unexported module Text.Pandoc.XML.++ * Escape '\160' as " ", not " " in XML.+ "nbsp" isn't a predefined XML entity.++ * Fixed bug in RST reader, which would choke on: "p. one\ntwo\n".+ Added some try's in ordered list parsers.++ * Man writer: don't escape " as \".++ * Allow newline before URL in markdown link references. Resolves Issue #81.+ Added tests for this issue in new "markdown-reader-more" tests.+ Changed RunTests.hs to run these tests.++ * Support for display math. Resolves Issue #47.++ + Added a DisplayMath/InlineMath selector to Math inlines.+ + Markdown parser yields DisplayMath for $$...$$.+ + LaTeX parser yields DisplayMath when appropriate. Removed+ mathBlock parsers, since the same effect is achieved by the math+ inline parsers, now that they handle display math.+ + Writers handle DisplayMath as appropriate for the format.+ + Modified tests accordingly; added new tests for display math.++ * Use LaTeXMathML instead of ASCIIMathML. LaTeXMathML is closer+ to LaTeX in its display of math, and supports many non-math LaTeX environments.++ + Changed -m option to use LaTeXMathML rather than ASCIIMathML.+ + Modified HTML writer to print raw TeX when LaTeXMathML is+ being used instead of suppressing it.+ + Removed ASCIIMathML files from data/ and added LaTeXMathML.+ + Replaced ASCIIMathML with LaTeXMathML in source files.+ + Modified README and pandoc man page source.+ + Added --latexmathml option (kept --asciimathml as a synonym+ for backwards compatibility)++ * Markdown reader: Parse setext headers before atx headers.+ Test case:+ # hi+ ====+ parsed by Markdown.pl as an H1 header with contents "# hi".++ * Markdown reader: Treat "mixed" lists the same way as Markdown.pl does.+ The marker on the first list item determines the type of the whole+ list. Thus, a list like+ 1. one+ - two+ * three+ gets parsed as a single ordered list. (Previous versions of pandoc+ treated this as an ordered list with an unordered sublist.)++ * Markdown smart typography:++ + Em dashes no longer eat surrounding whitespace. Resolves Issue #69.+ + Use nonbreaking spaces after known abbreviations in markdown parser.+ Thus, for example, "Mr. Brown" comes out as "Mr.~Brown" in LaTeX, and does+ not produce a sentence-separating space. Resolves Issue #75.++ * Markdown writer: Print unicode \160 literally, rather than as .++ * Treat '\ ' in (extended) markdown as nonbreaking space.+ Print nonbreaking space appropriately in each writer (e.g. ~ in LaTeX).++ * The '--sanitize-html' option now examines URIs in markdown links+ and images, and in HTML href and src attributes. If the URI scheme+ is not on a whitelist of safe schemes, it is rejected. The main point+ is to prevent cross-site scripting attacks using 'javascript:' URIs.+ See http://www.mail-archive.com/markdown-discuss@six.pairlist.net/msg01186.html+ and http://ha.ckers.org/xss.html. Resolves Issue #62.++ * HTML writer:++ + Override Text.XHtml's stringToHtml function,+ so that characters below 0xff are not converted to numerical entity+ references. Also convert '\160' to " ". This should aid readability+ and editability of the HTML source. It does presuppose that the HTML+ will be served as UTF-8.+ + In code blocks, change leading newlines to <br /> tags.+ (Some browsers ignore them.) Resolves Issue #71.+ See http://six.pairlist.net/pipermail/markdown-discuss/2008-May/001297.html+ + Use style attributes rather than css classes for strikethrough+ and ordered list styles. This works better when fragments, rather than+ standalone documents, are generated.++ * HTML reader: Count anything that isn't a known block (HTML) tag as an+ inline tag (rather than the other way around). Added "html", "head", and+ "body" to list of block tags. Resolves Issue #66, allowing+ <lj> to count as an inline tag.++ * RTF writer: Fixed bug. Extra spaces were being printed after emphasized,+ boldface, and other inline elements. Resolves Issue #64.++ * LaTeX reader: improvements in raw LaTeX parsing.++ + "loose punctuation" (like {}) parsed as Space+ + Para elements must contain more than Str "" and Space elements+ + Added parser for "\ignore" command used in literate haskell.+ + Reworked unknownCommand and rawLaTeXInline: when not in "parse raw"+ mode, these parsers simply strip off the command part and allow+ the arguments to be parsed normally. So, for example,+ \blorg{\emph{hi}} will be parsed as Emph "hi" rather than+ Str "{\\emph{hi}}".+ + Parse lhs "code" environments as verbatim.+ Refactored parsers for verbatim environments.+ + Removed specialEnvironment parser.+ + parse '{}', if present, after \textless, \textgreater,+ \textbar, \textbackslash, \ldots.+ + Parse unescaped special characters verbatim rather than+ changing them to spaces. This way arguments of unknown+ commands will appear in braces.++ * Parse raw ConTeXt environments as TeX in markdown reader.+ Resolves Issue #73.++ * Moved BlockWrapper and wrappedBlocksToDoc from ConTeXt writer to Shared.++ * Made some structural changes to parsing of raw LaTeX environments.+ Previously there was a special block parser for LaTeX environments.+ It returned a Para element containing the raw TeX inline. This has+ been removed, and the raw LaTeX environment parser is now used in the+ rawLaTeXInline parser. The effect is exactly the same, except that we+ can now handle consecutive LaTeX and ConTeXt environments not separated+ by spaces. This new flexibility is required by the example in+ Issue #73:++ \placeformula \startformula+ L_{1} = L_{2}+ \stopformula++ API change: The LaTeX reader now exports rawLaTeXEnvironment' (which+ returns a string) rather than rawLaTeXEnvironment (which returns a block+ element). This is more likely to be useful in other applications.++ * Use \textsubscr instead of \textsubscript for LaTeX subscript macro.+ \textsubscript conflicts with a definition in the memoir class.+ Resolves Issue #65.++ * Removed unneeded space after "\\item" in LaTeX and ConTeXt output.++ * Added amsmath package to default LaTeX header. Resolves Issue #48.++ * Added \setupitemize[autointro] to ConTeXt header, to prevent orphaned+ list introduction lines.++ * Changed Float to Double in definition of Table element.+ (Double is more efficient in GHC.)++ * Fixed bug in Markdown parser: regular $s triggering math mode.+ For example: "shoes ($20) and socks ($5)."+ The fix consists in two new restrictions:++ + the $ that ends a math span may not be directly followed by a digit.+ + no blank lines may be included within a math span.++ Thanks to Joseph Reagle for noticing the bug.++ * Use Data.List's 'intercalate' instead of custom 'joinWithSep'.+ Removed 'joinWithSep' from Text.Pandoc.Shared.++ * Updated README and man pages. Acknowledge contributors in README.+ Added paragraph to README about producing S5 with separate CSS/javascript.++ * Updated INSTALL to reflect new build system (including configuration+ options) and document new dependencies. Added note to INSTALL that+ Cabal >= 1.2 is required for build. Resolves Issue #74.++ * Fixed some haddock documentation errors.++ * Small fix to markdown2pdf man page: only input needs to be piped through iconv.++pandoc (0.46) unstable; urgency=low++ [ John MacFarlane ]++ * Made -H, -A, and -B options cumulative: if they are specified+ multiple times, multiple files will be included.++ * Added optional HTML sanitization using a whitelist.+ When this option is specified (--sanitize-html on the command line),+ unsafe HTML tags will be replaced by HTML comments, and unsafe HTML+ attributes will be removed. This option should be especially useful+ for those who want to use pandoc libraries in web applications, where+ users will provide the input.++ + Main.hs: Added --sanitize-html option.++ + Text.Pandoc.Shared: Added stateSanitizeHTML to ParserState.++ + Text.Pandoc.Readers.HTML:+ - Added whitelists of sanitaryTags and sanitaryAttributes.+ - Added parsers to check these lists (and state) to see if a given+ tag or attribute should be counted unsafe.+ - Modified anyHtmlTag and anyHtmlEndTag to replace unsafe tags+ with comments.+ - Modified htmlAttribute to remove unsafe attributes.+ - Modified htmlScript and htmlStyle to remove these elements if+ unsafe.++ + Modified README and man pages to document new option.++ * Improved handling of email addresses in markdown and reStructuredText.+ Consolidated uri and email address parsers. (Resolves Issue #37.)++ + New emailAddress and uri parsers in Text.Pandoc.Shared.+ - uri parser uses parseURI from Network.URI.+ - emailAddress parser properly handles email addresses with periods+ in them.++ + Removed uri and emailAddress parsers from Text.Pandoc.Readers.RST+ and Text.Pandoc.Readers.Markdown.++ * Markdown reader:++ + Fixed emph parser so that "*hi **there***" is parsed as a Strong+ nested in an Emph. (A '*' is only recognized as the end of the+ emphasis if it's not the beginning of a strong emphasis.)++ + Moved blockQuote parser before list parsers for performance.++ + Modified 'source' parser to allow backslash-escapes in URLs.+ So, for example, [my](/url\(1\)) yields a link to /url(1).+ Resolves Issue #34.++ + Disallowed links within links. (Resolves Issue #35.)+ - Replaced inlinesInBalanced with inlinesInBalancedBrackets, which+ instead of hard-coding the inline parser takes an inline parser+ as a parameter.+ - Modified reference and inlineNote to use inlinesInBalancedBrackets.+ - Removed unneeded inlineString function.+ - Added inlineNonLink parser, which is now used in the definition of+ reference.+ - Added inlineParsers list and redefined inline and inlineNonLink parsers+ in terms of it.+ - Added failIfLink parser.++ + Better handling of parentheses in URLs and quotation marks in titles.+ - 'source' parser first tries to parse URL with balanced parentheses;+ if that doesn't work, it tries to parse everything beginning with+ '(' and ending with ')'.+ - source parser now uses an auxiliary function source'.+ - linkTitle parser simplified and improved, under assumption that it+ will be called in context of source'.++ + Make 'block' conditional on strictness state, instead of using+ failIfStrict in block parsers. Use a different ordering of parsers+ in strict mode (raw HTML block before paragraph) for performance.+ In non-strict mode use rawHtmlBlocks instead of htmlBlock.+ Simplified htmlBlock, since we know it's only called in strict+ mode.++ + Improved handling of raw HTML. (Resolves Issue #36.)+ - Tags that can be either block or inline (e.g. <ins>) should+ be treated as block when appropriate and as inline when+ appropriate. Thus, for example,+ <ins>hi</ins>+ should be treated as a paragraph with inline <ins> tags, while+ <ins>+ hi+ </ins>+ should be treated as a paragraph within <ins> tags.+ - Moved htmlBlock after para in list of block parsers. This ensures+ that tags that can be either block or inline get parsed as inline+ when appropriate.+ - Modified rawHtmlInline' so that block elements aren't treated as+ inline.+ - Modified para parser so that paragraphs containing only HTML tags and+ blank space are not allowed. Treat these as raw HTML blocks instead.++ + Fixed bug wherein HTML preceding a code block could cause it to+ be parsed as a paragraph. The problem is that the HTML parser+ used to eat all blank space after an HTML block, including the+ indentation of the code block. (Resolves Issue #39.)+ - In Text.Pandoc.Readers.HTML, removed parsing of following space+ from rawHtmlBlock.+ - In Text.Pandoc.Readers.Markdown, modified rawHtmlBlocks so that+ indentation is eaten *only* on the first line after the HTML+ block. This means that in+ <div>+ foo+ <div>+ the foo won't be treated as a code block, but in+ <div>++ foo++ </div>+ it will. This seems the right approach for least surprise.++ * RST reader:++ + Fixed bug in parsing explicit links (resolves Issue #44).+ The problem was that we were looking for inlines until a '<' character+ signaled the start of the URL; so, if you hit a reference-style link,+ it would keep looking til the end of the document. Fix: change+ inline => (notFollowedBy (char '`') >> inline). Note that this won't+ allow code inlines in links, but these aren't allowed in resT anyway.++ + Cleaned up parsing of reference names in key blocks and links.+ Allow nonquoted reference links to contain isolated '.', '-', '_', so+ so that strings like 'a_b_' count as links.++ + Removed unnecessary check for following link in str.+ This is unnecessary now that link is above str in the definition of+ 'inline'.++ * HTML reader:++ + Modified rawHtmlBlock so it parses </html> and </body> tags.+ This allows these tags to be handled correctly in Markdown.+ HTML reader now uses rawHtmlBlock', which excludes </html> and </body>,+ since these are handled in parseHtml. (Resolves Issue #38.)++ + Fixed bug (emph parser was looking for `<IT>` tag, not `<I>`).++ + Don't interpret contents of style tags as markdown.+ (Resolves Issue #40.)+ - Added htmlStyle, analagous to htmlScript.+ - Use htmlStyle in htmlBlockElement and rawHtmlInline.+ - Moved "script" from the list of tags that can be either block or+ inline to the list of block tags.++ + Modified rawHtmlBlock to use anyHtmlBlockTag instead of anyHtmlTag+ and anyHtmlEndTag. This fixes a bug in markdown parsing, where+ inline tags would be included in raw HTML blocks.++ + Modified anyHtmlBlockTag to test for (not inline) rather than+ directly for block. This allows us to handle e.g. docbook in+ the markdown reader.++ * LaTeX reader: Properly recognize --parse-raw in rawLaTeXInline.+ Updated LaTeX reader test to use --parse-raw.++ * HTML writer:++ + Modified rules for automatic HTML header identifiers to+ ensure that identifiers begin with an alphabetic character.+ The new rules are described in README. (Resolves Issue #33.)++ + Changed handling of titles in HTML writer so you don't get+ "titleprefix - " followed by nothing.++ * ConTeXt writer: Use wrappers around Doc elements to ensure proper+ spacing. Each block element is wrapped with either Pad or Reg.+ Pad'ed elements are guaranteed to have a blank line in between.++ * RST writer:++ + Refactored RST writer to use a record instead of a tuple for state,+ and to include options in state so it doesn't need to be passed as+ a parameter.++ + Use an interpreted text role to render math in restructuredText.+ See http://www.american.edu/econ/itex2mml/mathhack.rst for the+ strategy.++ [ Recai Oktaş ]++ * Debian packaging changes:++ + Remove the empty 'include' directory in -dev package, which lintian+ complains about.+ + Bump Standarts-Version to 3.7.3.+ + Use new 'Homepage:' field to specify the upstream URL on suggestion of+ lintian.++ -- Recai Oktaş <roktas@debian.org> Tue, 08 Jan 2008 05:13:31 +0200++pandoc (0.45) unstable; urgency=low++ [ John MacFarlane ]++ * Simplified parsing of reference keys and notes in markdown and RST+ readers: The Reference data structure from Text.Pandoc.Shared is no+ longer needed, since referenceKey and noteBlock parses return strings+ (as many blank lines as were occupied by the key or note) and update+ state themselves. getPosition and setPosition are now used to ensure+ that error messages will give the correct line number. This yields+ cleaner (and slightly faster) code, with more accurate parsing error+ messages.++ * Added new Math inline element:++ + Markdown and LaTeX readers now convert TeX math into Math elements,+ not TeX.+ + This allows math to be treated differently from raw TeX in output.+ TeX elements are no longer printed in output formats other than+ Markdown, LaTeX, and ConTeXt. But Math elements are always printed.++ * New default handling of math in writers:++ + New module Text.Pandoc.Readers.TeXMath exports readTeXMath, which+ parses raw TeX math and outputs a string of Pandoc inlines that+ tries to render it as far as possible using unicode characters,+ lapsing into literal TeX when needed.+ + readTeXMath is now used for default HTML output in HTML, S5, RTF,+ and Docbook, if no other method for displaying math in HTML is+ specified. Enclosing $'s are no longer printed by default.+ + By default, math is put inside `<span class="math">`. This way it can be+ distinguished from the surrounding text, e.g. put in a different+ font.++ * New --gladtex and --mimetex options for display of math in HTML:++ + If --gladtex is specified, math is output between `<eq>` tags, so+ it can be processed by gladTeX.+ + If --mimetex is specified, math is put in `<img>` tags with a link+ to the mimetex CGI script (or any other script that takes TeX math+ as input and outputs an image). The URL of the script may be+ specified, but defaults to /cgi-bin/mimetex.cgi.+ + HTMLMathMethod structure in WriterOptions keeps track of how to+ display math in HTML output.+ + Updated README with a description of the four options for displaying+ math in HTML.++ * HTML reader:++ + Fixed bug: parser for minimized attributes should not swallow+ trailing spaces.+ + Simplified HTML attribute parsing.+ + Changed parsing of code blocks in HTML reader: `<code>` tag is no+ longer needed. `<pre>` suffices. All HTML tags in the code block+ (e.g. for syntax highlighting) are skipped, because they are not+ portable to other output formats. A `<code>...</code>` block not+ surrounded by `<pre>` now counts as inline HTML, not a code block.+ + Remove just one leading and one trailing newline from contents of+ `<pre>...</pre>` in codeBlock parser.++ * Markdown reader:++ + Removed support for box-style block quotes.+ + Require space before title in links and references.+ This fixes a bug in parsing URLs like http://silly/url(withparen).+ + Improved and simplified setextHeader parser.+ + Fixed logic in smart quote parsing, adding some needed 'try'+ statements.+ + Fixed smart quote parsing so that unicode characters 8216 and 8217+ are recognized as single quotes, and 8220 and 8221 as double quotes.++ * RST reader:++ + Fixed bug in parsing of code blocks. Previously a full tab indent+ was required, but RST allows code to be indented any amount.+ Resolves Issue #27.+ + Allow field lists to be indented.+ + Parse the contents of field lists instead of treating as a raw string.+ + Represent field lists as definition lists instead of blockquotes.+ + Fixed bug in which metadata would be overridden if the document+ contained multiple field lists.+ + Parse fields associated with '.. image::' blocks, and use 'alt'+ field, if given, for image alt and title attributes.++ * LaTeX reader:++ + Modified specialChar so that '"' characters are parsed.+ + Fixed a bug in parsing of \[ \] math blocks (thanks to Mark Kalderon).++ * HTML writer:++ + Changes in handling of math (see above).+ + Don't produce HTML for table of contents if there are+ no headers. (This would be an empty list, which is invalid XHTML.)++ * Markdown writer:++ + Don't print title attribute if title is empty. (This differs from+ the behavior of Markdown.pl, and agrees with PHP Markdown. But John+ Gruber has indicated that he prefers this behavior.) Adjusted test+ suite accordingly.+ + Fixed incorrect line wrapping in paragraphs including hard line+ breaks. Resolves Issue #25.+ + Fixed bug in markdown writer: If an ordered list item began with+ a marker greater than 3 characters in width, and the item took more+ than one line, it would appear on the line after the list marker,+ e.g.:++ (12)+ My list item.+ Multiline.++ Now it works as follows:++ (12) My list item.+ Multiline.++ * RST writer++ + Fixed bug in RST writer's handling of ordered lists. Previously,+ list items with multiple lines would not always line up with+ single-line list items. Now, list items are nested the length of+ the list marker + 1. This looks better and ensures that list items+ all line up. (Note that list markers are padded to the length of+ the longest list marker in the series.)+ + Use 3-space indent for unordered lists.+ + If label for a link reference contains a colon, surround it by `+ signs so it won't be interpreted as the end of the link label.++ * LaTeX writer:++ + Cleaner output for footnotes. Footnotes now always begin on a new+ line, and the final } is on a line by itself only when it needs to+ be (i.e. only when the note ends with a Verbatim environment).+ + Added writer options to state, so state doesn't need to be passed as+ a parameter.+ + Text wrapping now provided, using wrapTeXIfNeeded.++ * ConTeXt writer: many improvements for more idiomatic ConTeXt output+ (thanks to Idris Samawi Hamid for suggestions).++ + PrettyPrint module now used for output.+ + Writer options are now in state, so they don't have to be passed as+ a parameter.+ + Text wrapping now provided, using wrapTeXIfNeeded.+ + Better treatment of footnotes: footnotes are always on lines by+ themselves, and the final } is on a line by itself only when+ it needs to be (after \stoptyping).+ + Use \subject, \subsubject, ... or \section, \subsection, ... for headings,+ depending on whether --number-sections option is selected.+ + Extra blank line inserted after \stopitemize+ + Use new, "official" definition of blockquote environment. Also, use+ blank line after \startblockquote to balance blank line at the end.+ + Both itemized and enumerated lists are now generated using+ \start-stopitemize, with appropriate options. Removed definitions+ of ltxenum and ltxitem, which are no longer needed. Provided+ defaults for itemized lists in the preamble. State keeps track of+ ordered list level, so that when default numbering is specified,+ the appropriate scheme can be used.+ + Changed \useurl to \useURL.+ + Changed link color from red to blue.+ + Use \subsubsubsubsection etc., since these are supported+ (up to at least sub x 5).++ * Text.Pandoc.Shared:++ + Save and restore position in parseFromString, so that accurate+ error messages can be given.+ + Improved efficiency of romanNumeral parser.+ + Added wrappedTeX and wrapTeXIfNeeded functions. These ensure+ that footnotes occur on lines by themselves (to make them+ easier to see and move) and do not screw up line wrapping.++ * Text.Pandoc.UTF8: modified fromUTF8 to strip out the BOM+ if present. Windows Notepad and other applications insert a+ BOM at the beginning of a UTF8 file.++ * Main.hs (tabFilter): Treat '\r' at end of line as newline (in+ addition to "\r\n" and '\n').++ * Added a writer option for wrapped text and a command-line option+ '--no-wrap', which disables text wrapping and minimizes whitespace+ in HTML. (Resolves Issue #26.)++ + Added support for '--no-wrap' to Main.hs.+ + Added wrapIfNeeded function to Text.Pandoc.Shared.+ + Use wrapIfNeeded instead of wrapped in the RST, Man, Docbook, and+ Markdown writers.+ + Added render and renderFragment helpers to HTML writer.++ * Modified html2markdown to run tidy only if the HTML cannot be+ parsed. Previously html2markdown piped all input through tidy+ before passing it to pandoc. This caused problems on certain pages+ (e.g. http://daringfireball.com/markdown) which have well-formed+ XHTML that causes tidy to choke. The solution is to pipe through+ tidy only if pandoc cannot parse the input by itself. This means+ that a temp file is now always used, even when input comes from a+ local file or standard input.++ * Removed 'version' constant from Main.hs; added 'pandocVersion' to+ Text.Pandoc library.++ * pandoc.cabal:++ + Modified to work with GHC 6.8 and Cabal configurations. (For GHC+ 6.8, pretty and containers must be added to Build-Depends, and it+ is desirable to use the -O2 compiler option.) Cabal configurations+ allows one to select options depending on the compiler version.+ For GHC 6.6, the splitBase option can be disabled.+ + pandoc.cabal.ghc66 is provided for users with older versions of+ Cabal, which do not support configurations.+ + Use Ghc-Prof-Options to ensure that '-auto-all' is used when+ '--enable-(executable|library)-profiling' is specified. Updated+ PROFILING instructions accordingly.++ * Makefile:++ + Makefile now checks GHC version. If GHC is 6.6, pandoc.cabal.ghc66+ is copied to pandoc.cabal, and the old pandoc.cabal is copied+ to pandoc.cabal.orig. Otherwise, pandoc.cabal is copied to+ pandoc.cabal.orig but otherwise unmodified. This way, the Makefile+ will work properly with either GHC 6.6 or 6.8.+ + Changed BUILDCONF to point to dist/setup-config, not .setup-config.+ This is where current versions of Cabal put it.+ + Added $(BUILDCMD) target, so setup doesn't get compiled every time.+ + Removed dependency of templates on ./templates, which is circular+ now that templates is a subdirectory of the top-level.++ * MacPorts Portfile:++ + Modified to install the pandoc library in addition to programs.+ + Installation must be done manually rather than using Makefile's+ install-all.+ + Note that the library must be registered in the activate phase,+ after the library files have been copied out of the destroot.+ Cabal generates a 'register.sh' script that will do this.++ * debian/control: Added libghc6-network-dev, libghc6-xhtml-dev, and+ libghc6-mtl-dev as dependencies for libghc6-pandoc-dev.+ Closes: #445235++ * debian/rules: Converted to UTF-8.++ * Changed pandoc home page to http://johnmacfarlane.net/pandoc/.++ * Updated ASCIIMathML.js to latest version.++ * Directory structure:++ + Moved everything from src into the top-level directory.+ + Changed references to source directory in Makefile and+ pandoc.cabal.*.+ + Moved ASCIIMathML.js, headers, and ui into templates directory.+ + Modified fillTemplates.pl to reflect new paths.++ [ Recai Oktaş ]++ * Makefile: Fixed the issue of having two copies of the library+ documentation under some usage scenarios.++ * Replaced 'ghc' with '$(GHC)' in Makefile, and made GHC+ and GHC_PKG configurable through the environment, to support+ unusual ghc installations. For example:+ GHC=/opt/ghc/bin/ghc GHC_PKG=/opt/ghc/bin/ghc-pkg make++ -- Recai Oktaş <roktas@debian.org> Sun, 07 Oct 2007 20:51:43 +0300++pandoc (0.44) unstable; urgency=low++ [ John MacFarlane ]++ * Fixed bug in HTML writer: when --toc was used, anchors were put around+ headers, which is invalid XHTML (block content within inline element).+ Now the anchors are put inside the header tags. Resolves Issue #23.++ * Added xmlns attribute to html element in html writer tests.+ This attribute is added by more recent versions of the+ xhtml library (>= 3000), and is required for valid XHTML.++ [ Recai Oktaş ]++ * On configure, compile 'Setup.hs' to 'setup' and use 'setup' as the build+ command instead of 'runhaskell', which, on some platforms (such as s390,+ alpha, m68k), throws the following error:++ runhaskell Setup.hs configure --prefix=/usr+ ghc-6.6.1: not built for interactive use++ This causes a serious FTBFS bug. Closes: #440668.++ -- Recai Oktaş <roktas@debian.org> Mon, 03 Sep 2007 18:24:02 +0300++pandoc (0.43) unstable; urgency=low++ [ John MacFarlane ]++ * The focus of this release is performance. The markdown parser+ is about five times faster than in 0.42, based on benchmarks+ with the TextMate manual.++ * Main.hs: Replaced CRFilter and tabFilter with single function+ tabFilter, which operates on the whole string rather than breaking+ it into lines, and handles dos-style line-endings as well as tabs.++ * Added separate LaTeX reader and native reader tests; removed+ round-trip tests.++ * Text.Pandoc.Shared:++ + Removed tabsToSpaces and tabsInLine (they were used only in Main.hs.)+ + General code cleanup (to elimante warnings when compiling with -Wall.)+ + Added 'wrapped' function, which helps wrap text into paragraphs,+ using the prettyprinting library.+ + Rewrote charsInBalanced and charsInBalanced'.+ - Documented restriction: open and close must be distinct characters.+ - Rearranged options for greater efficiency.+ - Bug fix: Changed inner call to charsInBalanced inside+ charsInBalanced' to charsInBalanced'.+ + anyLine now requires that the line end with a newline (not eof).+ This is a harmless assumption, since we always add newlines to the+ end of a block before parsing with anyLine, and it yields a 10% speed+ boost.+ + Removed unnecessary 'try' in anyLine.+ + Removed unneeded 'try' from romanNumeral parser.+ + Use notFollowedBy instead of notFollowedBy' in charsInBalanced.+ + Removed unneeded 'try' in parseFromString.+ + Removed unneeded 'try' from stringAnyCase. (Now it behaves+ like 'string'.)+ + Changed definition of 'enclosed' in Text.Pandoc.Shared so that+ 'try' is not automatically applied to the 'end' parser. Added+ 'try' in calls to 'enclosed' where needed. Slight speed increase.++ * Writers:++ + Replaced individual wrapping routines in RST, Man, and Markdown+ writers with 'wrapped' from Text.Pandoc.Shared.+ + Rewrote LaTeX writer to use the prettyprinting library,+ so we get word wrapping, etc.+ + Modified latex writer tests for new latex writer using prettyprinter.+ + Fixed bug in LaTeX writer: autolinks would not cause+ '\usepackage{url}' to be put in the document header. Also, changes+ to state in enumerated list items would be overwritten.+ + In Markdown writer, escape paragraphs that begin with ordered list+ markers, so they don't get interpreted as ordered lists.++ * Text.Pandoc.Reades.LaTeX:++ + Fixed bug in LaTeX reader, which wrongly assumed that the roman+ numeral after "enum" in "setcounter" would consist entirely of+ "i"s. 'enumiv' is legitimate.+ + LaTeX command and environment names can't contain numbers.+ + Rearranged order of parsers in inline for slight speed improvement.+ + Added '`' to special characters and 'unescapedChar'.++ * Text.Pandoc.Readers.RST:++ + Removed unneeded try's in RST reader; also minor code cleanup.+ + Removed tabchar.+ + Rearranged parsers in inline (doubled speed).++ * Text.Pandoc.Readers.Markdown:++ + Skip notes parsing if running in strict mode. (This yields a nice+ speed improvement in strict mode.)+ + Simplify autolink parsing code, using Network.URI to test for+ URIs. Added dependency on network library to debian/control and+ pandoc.cabal.+ + More perspicuous definition of nonindentSpaces.+ + Removed unneeded 'try' in 'rawLine'.+ + Combined linebreak and whitespace into a new whitespace parser, to+ avoid unnecessary reparsing of space characters.+ + Removed unnecessary 'try' in 'codeBlock', 'ellipses', 'noteMarker',+ 'multilineRow', 'dashedLine', 'rawHtmlBlocks'.+ + Use lookAhead in parsers for setext headers and definition lists+ to see if the next line begins appropriately; if not, don't waste+ any more time parsing.+ + Don't require blank lines after code block. (It's sufficient to+ end code block with a nonindented line.)+ + Changed definition of 'emph': italics with '_' must not+ be followed by an alphanumeric character. This is to help+ prevent interpretation of e.g. `[LC_TYPE]: my_type` as+ `[LC<em>TYPE]:my</em>type`.+ + Improved Markdown.pl-compatibility in referenceLink: the two parts+ of a reference-style link may be separated by one space, but not+ more... [a] [link], [not] [a link].+ + Fixed markdown inline code parsing so it better accords with+ Markdown.pl: the marker for the end of the code section is a clump+ of the same number of `'s with which the section began, followed+ by a non-` character. So, for example,+ ` h ``` i ` -> `<code>h ``` i</code>`.+ + Split 'title' into 'linkTitle' and 'referenceTitle', since the+ rules are slightly different.+ + Rewrote 'para' for greater efficiency.+ + Rewrote link parsers for greater efficiency.+ + Removed redundant 'referenceLink' in definition of inline (it's+ already in 'link').+ + Refactored escapeChar so it doesn't need 'try'.+ + Refactored hrule for performance in Markdown reader.+ + More intelligent rearranging of 'inline' so that most frequently+ used parsers are tried first.+ + Removed tabchar parser, as whitespace handles tabs anyway.++ * Text.Pandoc.CharacterReferences:++ + Refactored.+ + Removed unnecessary 'try's for a speed improvement.+ + Removed unnecessary '&' and ';' from the entity table.++ * Build process:++ + Makefile: Get VERSION from cabal file, not Main.hs.+ + Modified MacPorts Portfile:+ - Depend on haddock+ - Build and install libraries and library documentation in+ addition to pandoc executable+ - Added template item for md5 sum in Portfile.in.+ - Incorporated changes from MacPorts repository (r28278).+ + FreeBSD port: Don't try to generate distinfo in Makefile.+ It can be made using 'make makesum' in FreeBSD.+ + Make both freebsd and macports targets depend on tarball.++ * Website and documentation:++ + Updated INSTALL instructions.+ + Added pandocwiki demo to website.+ + Removed local references to Portfile, since pandoc is now in the+ MacPorts repository.++ -- Recai Oktaş <roktas@debian.org> Sun, 02 Sep 2007 15:50:11 +0300++pandoc (0.42) unstable; urgency=low++ [ John MacFarlane ]++ * Main.hs: Use utf8 conversion on the extra files loaded with+ the -H, -C, -B, and -A options. This fixes problems with unicode+ characters in these files.++ * Exposed Text.Pandoc.ASCIIMathML, since it is imported in+ Text.Pandoc.Readers.HTML and without it we get a linking error when+ using the library.++ * Markdown reader:++ + Added new rule for enhanced markdown ordered lists: if the list+ marker is a capital letter followed by a period (including a+ single-letter capital roman numeral), then it must be followed by+ at least two spaces. The point of this is to avoid accidentally+ treating people's initials as list markers: a paragraph might begin,+ "B. Russell was an English philosopher," and this shouldn't be+ treated as a list. Documented change in README.+ + Blocks that start with "p. " and a digit are no longer treated+ as ordered lists (it's a page number).+ + Added a needed 'try' to listItem.+ + Removed check for a following setext header in endline.+ A full test is too inefficient (doubles benchmark time), and the+ substitute we had before is not 100% accurate.+ + Don't use Code elements for autolinks if --strict specified.++ * LaTeX writer: When a footnote ends with a Verbatim environment, the+ close } of the footnote cannot occur on the same line or an error occurs.+ Fixed this by adding a newline before the closing } of every footnote.++ * HTML writer:+ + Removed incorrect "{}" around style information in HTML tables.+ Column widths now work properly in HTML.+ + If --strict option is specified (and --toc is not), don't include+ identifiers in headers, for better Markdown compatibility.++ * Build process:++ + Separated $(web_dest) and website targets.+ + In website, index.txt is now constructed from template index.txt.in.+ + Added freebsd target to Markefile. This creates the freebsd Makefile+ from Makefile.in, and creates distinfo. Removed Makefile and distinfo+ from the repository.+ + Added macport target to Makefile. Portfile is built from template+ Portfile.in.+ + Removed OSX package targets. (Too many difficulties involving+ dependencies on dynamic libraries.)+ + More complete INSTALL instructions for all architectures.++ * Website:+ + Added a programming demo, pandocwiki.++ [ Recai Oktaş ]++ * Do not forget to close pandoc's ITP. Closes: #391666++ -- Recai Oktaş <roktas@debian.org> Sun, 26 Aug 2007 22:51:32 +0300++pandoc (0.41) unstable; urgency=low++ [ John MacFarlane ]++ * Fixed bugs in HTML reader:+ + Skip material at end *only if* `</html>` is present (previously,+ only part of the document would be parsed if an error was+ found; now a proper error message is given).+ + Added new constant eitherBlockOrInline with elements that may+ count either as block-level or as inline. Modified isInline and+ isBlock to take this into account.+ + Modified rawHtmlBlock to accept any tag (even an inline tag):+ this is innocuous, because rawHtmlBlock is tried only if a regular+ inline element can't be parsed.+ + Added a necessary 'try' in definition of 'para'.++ * Fixed bug in markdown ordered list parsing. The problem was that+ anyOrderedListStart did not check for a space following the+ ordered list marker. So in 'A.B. 2007' the parser would be+ expecting a list item, but would not find one, causing an error.+ Fixed a similar bug in the RST reader. Resolves Issue #22.++ * Refactored RST and Markdown readers using parseFromString.++ * LaTeX reader will now skip anything after \end{document}.++ * Fixed blockquote output in markdown writer: previously, block+ quotes in indented contexts would be indented only in the first+ line.++ * Added note to INSTALL about variations in versions of the xhtml+ library that can lead to failed tests (thanks to Leif LeBaron).++ -- Recai Oktaş <roktas@debian.org> Sun, 19 Aug 2007 23:26:07 +0300++pandoc (0.4) unstable; urgency=low++ [ John MacFarlane ]++ * Added two new output formats: groff man pages and ConTeXt. By+ default, output files with extensions ".ctx" and ".context" are+ assumed to be ConTeXt, and output files with single-digit extensions+ are assumed to be man pages.++ * Enhanced ordered lists (documented in README, under Lists):+ + The OrderedList block element now stores information about+ list number style, list number delimiter, and starting number.+ + The readers parse this information when possible.+ + The writers use this information to style ordered lists.+ + The enhancement can be disabled using the --strict option.++ * Added support for tables (with a new Table block element). Two kinds+ of tables are supported: a simple table with one-line rows, and a+ more complex variety with multiline rows. All output formats are+ supported, but only markdown tables are parsed at the moment. The+ syntax is documented in README.++ * Added support for definition lists (with a new DefinitionList block+ element). All output and input formats are supported. The syntax is+ documented in README.++ * Added support for superscripts and subscripts (with new Superscript+ and Subscript inline elements). All input and output+ formats. The syntax is documented in README.++ * Added support for strikeout (with a new Strikeout inline element).+ All input and output formats are supported. Thanks to Bradley Kuhn,+ who contributed a patch. The syntax is documented in README. Resolves+ Issue #18.++ * Added a --toc|--table-of-contents option. This causes an automatically+ generated table of contents (or an instruction that creates one) to+ be inserted at the beginning of the document. Not supported in S5,+ DocBook, or man page writers.++ * Modified the -m|--asciimathml option:++ + If an optional URL argument is provided, a link is inserted+ instead of the contents of the ASCIIMathML.js script.+ + Nothing is inserted unless the document actually contains+ LaTeX math.++ * Removed Blank block element as unnecessary.++ * Removed Key and Note blocks from the Pandoc data structure. All+ links are now stored as explicit links, and note contents are+ stored with the (inline) notes.++ + All link Targets are now explicit (URL, title) pairs; there+ is no longer a 'Ref' target.+ + Markdown and RST parsers now need to extract data from key and+ note blocks and insert them into the relevant inline elements.+ Other parsers have been simplified, since there is no longer any need+ to construct separate key and note blocks.+ + Markdown, RST, and HTML writers need to construct lists of+ notes; Markdown and RST writers need to construct lists of link+ references (when the --reference-links option is specified); and+ the RST writer needs to construct a list of image substitution+ references. All writers have been rewritten to use the State monad+ when state is required.+ + Several functions (generateReference, keyTable,+ replaceReferenceLinks, replaceRefLinksBlockList, and some auxiliaries+ used by them) have been removed from Text.Pandoc.Shared, since+ they are no longer needed. New functions and data structures+ (Reference, isNoteBlock, isKeyBlock, isLineClump) have been+ added. The functions inTags, selfClosingTag, inTagsSimple, and+ inTagsIndented have been moved to the DocBook writer, since that+ is now the only module that uses them. NoteTable is now exported+ in Text.Pandoc.Shared.+ + Added stateKeys and stateNotes to ParserState; removed stateKeyBlocks,+ stateKeysUsed, stateNoteBlocks, stateNoteIdentifiers, stateInlineLinks.+ + Added writerNotes and writerReferenceLinks to WriterOptions.++ * Added Text.Pandoc module that exports basic readers, writers,+ definitions, and utility functions. This should export everything+ needed for most uses of Pandoc libraries. The haddock documentation+ includes a short example program.++ * Text.Pandoc.ASCIIMathML is no longer an exported module.++ * Added Text.Pandoc.Blocks module to help in printing markdown+ and RST tables. This module provides functions for working with+ fixed-width blocks of text--e.g., placing them side by side, as+ in a table row.++ * Refactored to avoid reliance on Haskell's Text.Regex library, which+ (a) is slow, and (b) does not properly handle unicode. This fixed+ some strange bugs, e.g. in parsing S-cedilla, and improved performance.++ + Replaced 'gsub' with a general list function 'substitute'+ that does not rely on Text.Regex.+ + Rewrote extractTagType in HTML reader so that it doesn't use+ regexs.+ + In Markdown reader, replaced email regex test with a custom email+ autolink parser (autoLinkEmail). Also replaced selfClosingTag regex+ with a custom function isSelfClosingTag.+ + Modified Docbook writer so that it doesn't rely on Text.Regex for+ detecting 'mailto' links.+ + Removed escapePreservingRegex and reamped entity-handling+ functions in Text.Pandoc.Shared and Text.Pandoc.CharacterReferences to+ avoid reliance on Text.Regex (see below on character reference+ handling changes).++ * Renamed Text.Pandoc.Entities as Text.Pandoc.CharacterReferences.++ * Changed handling of XML entities. Entities are now parsed (and unicode+ characters returned) in the Markdown and HTML readers, rather than being+ handled in the writers. In HTML and Docbook writers, UTF-8 is now used+ instead of entities for characters above 128. This makes the HTML and+ DocBook output much more readable and more easily editable.++ + Removed sgmlHexEntity, sgmlDecimalEntity, sgmlNamedEntity, and+ sgmlCharacterEntity regexes from Text.Pandoc.Shared.+ + Renamed escapeSGMLChar to escapeCharForXML. Added escapeStringForXML.+ Moved both functions to Text.Pandoc.Writers.Docbook.+ + Added characterReference parser to Text.Pandoc.CharacterReferences.+ This parses a string and return a unicode character.+ + Rewrote decodeCharacterReferences to use the new parser instead of+ Text.Regex.+ + Added new charRef parser for Markdown and HTML, which replaces the+ old 'entity' parser. Added '&' as a special character in Markdown reader.+ + Modified HTML and Markdown readers to call decodeEntities on all raw+ strings (e.g. authors, dates, link titles), to ensure that no+ unprocessed entities are included in the native representation of+ the document. (In the HTML reader, most of this work is done by a+ change in extractAttributeName.)+ + In XML and Markdown output, escape unicode nonbreaking space as ' ',+ since a unicode non-breaking space is impossible to distinguish visually+ from a regular space. (Resolves Issue #3.)+ + Removed encodeEntitiesNumerical.+ + Use Data.Map for entityTable and (new) reverseEntityTable, for a+ slight performance boost over the old association list.+ + Removed unneeded decodeEntities from 'str' parser in HTML and+ Markdown readers.++ * Text.Pandoc.UTF8: Renamed encodeUTF8 to toUTF8, decodeUTF8 to+ fromUTF8, for clarity.++ * Replaced old haskell98 module names replaced by hierarchical module+ names, e.g. List by Data.List. Removed haskell98 from dependencies+ in pandoc.cabal, and added mtl (needed for state monad). Substituted+ xhtml for html.++ * Refactored and cleaned up character escaping in writers, using+ backslashEscapes and escapeStringUsing functions.++ * Instead of adding "\n\n" to the end of an input string in Main.hs,+ this is now done in the readers. This makes the libraries behave+ the way you'd expect from the pandoc program. Resolves Issue #10.++ * URLs and email addresses in autolinks are now typeset as Code.++ * In Main.hs, changed putStr to putStrLn -- mainly because MacOS X+ doesn't display the whole output unless there's a line ending.++ * Major code cleanup in all modules, for greater consistency, concision,+ and readability.++ * HTML reader:++ + Fixed several bugs (extractTagType, attribute parsing).+ + Remove Null blocks in lists of blocks when possible.+ + Allow HTML comments as raw HTML inline.++ * Markdown reader:++ + Ordered list items may no longer begin with uppercase letters, or+ letters greater than 'n'. (This prevents first initials and page+ reference, e.g. 'p. 400', from being parsed as beginning lists.)+ Also, numbers beginning list items may no longer end with ')',+ which is now allowed only after letters. Note: These changes+ may cause documents to be parsed differently. Users should take+ care in upgrading.+ + Changed autoLink parsing to conform better to Markdown.pl's+ behavior. `<google.com>` is not treated as a link, but+ `<http://google.com>`, `<ftp://google.com>`, and+ `<mailto:google@google.com>` are.+ + Cleaned up handling of embedded quotes in link titles. Now these are+ stored as a '"' character, not as '"'.+ + Use lookAhead parser for the 'first pass' (looking for reference keys),+ instead of parsing normally, then using setInput to reset input. This+ yields a slight performance boost.+ + Fixed several bugs in smart quote recognition.+ + Fixed bug in indentSpaces (which didn't properly handle+ cases with mixed spaces and tabs).+ + Consolidated 'text', 'special', and 'inline' into 'inline'.+ + Fixed bug which allowed URL and title to be separated by multiple blank+ lines in links and reference keys. They can be on separate lines but+ can't have blank lines between them.+ + Correctly handle bracketed text inside inline footnotes and links,using+ new function inlinesInBalanced. Resolves Issue #14.+ + Fixed bug in footnotes: links in footnotes were not being+ processed. Solution: three-stage parse. First, get all the+ reference keys and add information to state. Next, get all the+ notes and add information to state. (Reference keys may be needed+ at this stage.) Finally, parse everything else.+ + Replaced named constants like 'emphStart' with literals.+ + Removed an extra occurance of escapedChar in definition of inline.++ * RST reader:++ + Allow the URI in a RST hyperlink target to start on the line+ after the reference key.+ + Added 'try' in front of 'string', where needed, or used a different+ parser. This fixes a bug where ````` would not be correctly parsed as+ a verbatim `.+ + Fixed slow performance in parsing inline literals in RST reader. The+ problem was that ``#`` was seen by 'inline' as a potential link or image.+ Fix: inserted 'notFollowedBy (char '`')' in link parsers.+ Resolves Issue #8.+ + Use lookAhead instead of getInput/setInput in RST reader. Removed+ unneeded getState call, since lookAhead automatically saves and+ restores the parser state.+ + Allow hyperlink target URIs to be split over multiple lines, and+ to start on the line after the reference. Resolves Issue #7.+ + Fixed handling of autolinks.++ * LaTeX reader:++ + Replaced 'choice [(try (string ...), ...]' idiom with 'oneOfStrings',+ for clarity.+ + Added clauses for tilde and caret. Tilde is \ensuremath{\sim}, and+ caret is \^{}, not \^ as before.+ + Added parsing for \url.+ + Parse \texttt{} as code, provided there's nothing fancy inside.++ * HTML writer:++ + Modified HTML writer to use the Text.XHtml library. This results+ in cleaner, faster code, and it makes it easier to use Pandoc in+ other projects, like wikis, which use Text.XHtml. Two functions are+ now provided, writeHtml and writeHtmlString: the former outputs an+ Html structure, the latter a rendered string. The S5 writer is also+ changed, in parallel ways (writeS5, writeS5String).+ + The Html header is now written programmatically, so it has been+ removed from the 'headers' directory. The S5 header is still+ needed, but the doctype and some of the meta declarations have+ been removed, since they are written programatically. This change+ introduces a new dependency on the xhtml package.+ + Fixed two bugs in email obfuscation involving improper escaping+ of '&' in the `<noscript>` section and in `--strict` mode. Resolves+ Issue #9.+ + Fixed another bug in email obfuscation: If the text to be obfuscated+ contains an entity, this needs to be decoded before obfuscation.+ Thanks to thsutton for the patch. Resolves Issue #15.+ + Changed the way the backlink is displayed in HTML footnotes.+ Instead of appearing on a line by itself, it now generally+ appears on the last line of the note. (Exception: when the+ note does not end with a Plain or Para block.) This saves space+ and looks better.+ + Added automatic unique identifiers to headers:+ - The identifier is derived from the header via a scheme+ documented in README.+ - WriterState now includes a list of header identifiers and a table+ of contents in addition to notes.+ - The function uniqueIdentifiers creates a list of unique identifiers+ from a list of inline lists (e.g. headers).+ - This list is part of WriterState and gets consumed by blockToHtml+ each time a header is encountered.+ + Include CSS for .strikethrough class in header only if strikethrough+ text appears in the document.+ + If the 'strict' option is specified, elements that do not appear in+ standard markdown (like definition lists) are passed through as+ raw HTML.+ + Simplified treatment of autolinks, using pattern matching instead of+ conditionals.++ * Markdown writer:++ + Links in markdown output are now printed as inline links by default,+ rather than reference links. A --reference-links option has been added+ that forces links to be printed as reference links. Resolves Issue #4.+ + Use autolinks when possible. Instead of `[site.com](site.com)`,+ use `<site.com>`.++ * LaTeX writer:++ + Rewrote to use the State monad. The preamble now includes only those+ packages that are actually required, given the document's content.+ Thus, for example, if strikeout is not used, ulem is not required.+ Modified LaTeXHeader accordingly.+ + Modified LaTeX writer to insert '\,' between consecutive quotes.+ + Removed unused function tableRowColumnWidths.+ + Simplified code for escaping special characters.+ + Leave extra blank line after \maketitle.+ + Include empty '\author{}' when no author specified to avoid LaTeX+ errors.+ + Include fancyvrb code in header only if needed -- that is, only+ if there is actually code in a footnote.+ + Use \url{} for autolinks.+ + Include [mathletters] option in ucs package, so that basic unicode+ Greek letters will work correctly.++ * RST writer: Force blank line before lists, so that sublists will+ be handled correctly.++ * Docbook writer: Fixed a bug: email links with text, like+ [foo](me@bar.baz), were being incorrectly treated as autolinks.++ * Removed Text.ParserCombinators.Pandoc and moved all its functions to+ Text.Pandoc.Shared.++ * Text.Pandoc.Shared:++ + Added defaultWriterOptions.+ + Added writerTableOfContents to WriterOptions.+ + Added writerIgnoreNotes option to WriterOptions. This is needed+ for processing header blocks for a table of contents, since notes on+ headers should not appear in the TOC.+ + Added prettyprinting for native Table format.+ + Removed some unneeded imports.+ + Moved escape and nullBlock parsers from+ Text.ParserCombinators.Pandoc, since the latter is for+ general-purpose parsers that don't depend on Text.Pandoc.Definition.+ + Moved isHeaderBlock from Text.Pandoc.Writers.HTML.+ + Moved Element, headerAtLeast, and hierarchicalize from Docbook+ writer, because HTML writer now uses these in constructing a table+ of contents.+ + Added clauses for new inline elements (Strikeout, Superscript,+ Subscript) to refsMatch.+ + Removed backslashEscape; added new functions escapeStringUsing and+ backslashEscapes.+ + Moved failIfStrict from markdown reader, since it is now used also+ by the HTML reader.+ + Added a 'try' to the definition of indentSpaces.+ + In definition of 'reference', added check to make sure it's not a note+ reference.+ + Added functions: camelCaseToHyphenated, toRomanNumeral,+ anyOrderedListMarker, orderedListmarker, orderedListMarkers,+ charsInBalanced', withHorizDisplacement, romanNumeral+ + Fixed a bug in the anyLine parser. Previously it would parse an empty+ string "", but it should fail on an empty string, or we get an error+ when it is used inside "many" combinators.+ + Removed followedBy' parser, replacing it with the lookAhead parser from+ Parsec.+ + Added some needed 'try's before multicharacter parsers, especially in+ 'option' contexts.+ + Removed the 'try' from the 'end' parser in 'enclosed', so that+ 'enclosed' behaves like 'option', 'manyTill', etc.+ + Added lineClump parser, which parses a raw line block up to and+ including any following blank lines.+ + Renamed parseFromStr to parseFromString.+ + Added a 'try' to the 'end' parser in 'enclosed'. This makes errors in+ the use of 'enclosed' less likely. Removed some now-unnecessary 'try's+ in calling code.+ + Removed unneeded 'try' in blanklines.+ + Removed endsWith function and rewrote calling functions to use+ isSuffixOf instead.+ + Added >>~ combinator.+ + Fixed bug in normalizeSpaces: Space:Str "":Space should compress to+ Space.++ * Refactored runtests.pl; added separate tests for tables.++ * Shell scripts:++ + Added -asxhtml flag to tidy in html2markdown. This will+ perhaps help the parser, which expects closing tags.+ + Modified markdown2pdf to run pdflatex a second time if --toc or+ --table-of-contents was specified; otherwise the table of+ contents won't appear.+ + Modified markdown2pdf to print a helpful message if the 'ulem'+ LaTeX package is required and not found.++ * Changes to build process:++ + Dropped support for compilation with GHC 6.4. GHC 6.6 or higher+ is now required.+ + Removed cabalize and Pandoc.cabal.in. The repository now contains+ pandoc.cabal itself.+ + Pandoc.cabal has been changed to pandoc.cabal, because HackageDB+ likes the cabal file to have the same name as the tarball.+ + Expanded and revised the package description in pandoc.cabal.+ Revised the package synopsis.+ + The tarball built by 'make tarball' now contains files built from+ templates (including man pages and shell scripts), so pandoc can+ be built directly using Cabal tools, without preprocessing.+ + Executable binaries are now stripped before installing.+ + Man pages are now generated from markdown sources, using pandoc's+ man page writer.+ + Use HTML version of README (instead of RTF) in Mac OS X installer.+ + Instead of testing for the existence of a pandoc symlink in build-exec,+ use ln -f.++ * Documentation:++ + Updated README and man pages with information on new features.+ + Updated INSTALL instructions with some useful clarifications and+ links.+ + Updated web content.++ * Added FreeBSD port.++ [ Recai Oktaş ]++ * debian/control:++ + Changed pandoc's Build-Depends to include libghc6-mtl-dev and+ libghc6-xhtml-dev. Removed libghc6-html-dev.+ + Suggest texlive-latex-recommended | tetex-extra instead of+ tetex-bin. This brings in fancyvrb and unicode support.++ -- Recai Oktaş <roktas@debian.org> Tue, 16 Jan 2007 00:37:21 +0200++pandoc (0.3) unstable; urgency=low++ [ John MacFarlane ]++ * Changes in pandoc options:++ + Allow options to follow or precede arguments.+ + Changed '--smartypants' to '--smart' and adjusted symbols accordingly.+ + Added '--strict' option.+ + Added '-o/--output' option.+ + Added '--dump-args' and '--ignore-args' options (for use in wrappers).+ + Modified '-v' and '-h' output to go to STDERR, not STDOUT, and return+ error conditions. This is helpful for writing wrappers.+ + Added copyright message to '-v' output, modeled after FSF messages.+ + Reformatted usage message so that it doesn't wrap illegibly.+ + Removed extra blanks after '-h' and '-D' output.++ * Added docbook writer.++ * Added implicit setting of default input and output format based+ on input and output filename extensions. These defaults are+ overridden if explicit input and output formats are specified using+ '-t', '-f', '-r', or '-w' options. Documented in pandoc(1) man page+ and README.++ * Allow ordered list items to begin with (single) letters, as well+ as numbers. The list item marker may now be terminated either by+ '.' or by ')'. This extension to standard markdown is documented+ in README.++ * Revised footnote syntax. (See README for full details.) The+ '[^1]' format now standard in markdown extensions is supported,+ as are inline footnotes with this syntax: '^[My note.]'.+ The earlier footnote syntax '^(1)' is no longer supported.++ * Improved HTML representation of footnotes. All footnotes+ are now auto-numbered and appear in an ordered list at the+ end of the HTML document. Since the default appearance is now+ acceptable, the old footnote styles have been removed from the+ HTML header.++ * Bug fixes:++ + Fixed a serious bug in the markdown, LaTeX, and RST readers.+ These readers ran 'runParser' on processed chunks of text to handle+ embedded block lists in lists and quotation blocks. But then+ any changes made to the parser state in these chunks was lost,+ as the state is local to the parser. So, for example, footnotes+ didn't work in quotes or list items. The fix: instead of calling+ runParser on some raw text, use setInput to make it the input, then+ parse it, then use setInput to restore the input to what it was+ before. This is shorter and more elegant, and it fixes the problem.+ + Fixed bug in notFollowedBy' combinator (adding 'try' before+ 'parser'). Adjusted code that uses this combinator accordingly.+ + Fixed bug in RTF writer that caused improper indentation on+ footnotes occurring in indented blocks like lists.+ + Fixed parsing of metadata in LaTeX reader. Now the title, author,+ and date are parsed correctly. Everything else in the preamble+ is skipped.+ + Modified escapedChar in LaTeX reader to allow a '\' at the end of a+ line to count as escaped whitespace.+ + Modified LaTeX reader to produce inline links rather than reference+ links. Otherwise, links in footnotes aren't handled properly.+ + Fixed handling of titles in links in Markdown reader, so that+ embedded quotation marks are now handled properly.+ + Fixed Markdown reader's handling of embedded brackets in links.+ + Fixed Markdown reader so that it only parses bracketed material+ as a reference link if there is actually a corresponding key.+ + Revised inline code parsing in Markdown reader to conform to+ markdown standard. Now any number of `s can begin inline code,+ which will end with the same number of `s. For example, to+ have two backticks as code, write ``` `` ```. Modified Markdown+ writer accordingly.+ + Fixed bug in text-wrapping routine in Markdown and RST writers.+ Now LineBreaks no longer cause wrapping problems.+ + Supported hexadecimal numerical entity references as well as+ decimal ones.+ + Fixed bug in Markdown reader's handling of underscores and other+ inline formatting markers inside reference labels: for example,+ in '[A_B]: /url/a_b', the material between underscores was being+ parsed as emphasized inlines.+ + Changed Markdown reader's handling of backslash escapes so that+ only non-alphanumeric characters can be escaped. Strict mode+ follows Markdown.pl in only allowing a select group of punctuation+ characters to be escaped.+ + Modified HTML reader to skip a newline following a `<br>` tag.+ Otherwise the newline will be treated as a space at the beginning+ of the next line.++ * Made handling of code blocks more consistent. Previously, some+ readers allowed trailing newlines, while others stripped them.+ Now, all readers strip trailing newlines in code blocks. Writers+ insert a newline at the end of code blocks as needed.++ * Modified readers to make spacing at the end of output more consistent.++ * Minor improvements to LaTeX reader:++ + '\thanks' now treated like a footnote.+ + Simplified parsing of LaTeX command arguments and options.+ commandArgs now returns a list of arguments OR options (in+ whatever order they appear). The brackets are included, and+ a new stripFirstAndLast function is provided to strip them off+ when needed. This fixes a problem in dealing with \newcommand+ and \newenvironment.++ * Revised RTF writer:++ + Default font is now Helvetica.+ + An '\f0' is added to each '\pard', so that font resizing works+ correctly.++ * Moved handling of "smart typography" from the writers to the Markdown+ and LaTeX readers. This allows great simplification of the writers+ and more accurate smart quotes, dashes, and ellipses. DocBook can+ now use `<quote>`. The '--smart' option now toggles an option in+ the parser state rather than a writer option. Several new kinds+ of inline elements have been added: Quoted, Ellipses, Apostrophe,+ EmDash, EnDash.++ * Changes in HTML writer:++ + Include title block in header even when title is null.+ + Made javascript obfuscation of emails even more obfuscatory,+ by combining it with entity obfuscation.++ * Changed default ASCIIMathML text color to black.++ * Test suite:++ + Added --strip-trailing-cr option to diff in runtests.pl, for+ compatibility with Windows.+ + Added regression tests with footnotes in quote blocks and lists.++ * Makefile changes:++ + osx-pkg target creates a Mac OS X package (directory). New osx+ directory contains files needed for construction of the package.+ + osx-dmg target creates a compressed disk image containing the package.+ + win-pkg target creates Windows binary package.+ + tarball target creates distribution source tarball.+ + website target generates pandoc's website automatically, including+ demos. New 'web' directory containts files needed for construction+ of the website (which will be created as the 'pandoc' subdirectory+ of 'web').+ + Makefile checks to see if we're running Windows/Cygwin; if so,+ a '.exe' extension is added to each executable in EXECS.++ * Removed all wrappers except markdown2pdf and html2markdown.++ * Added new wrapper hsmarkdown, to be used as a drop-in replacement+ for Markdown.pl. hsmarkdown calls pandoc with the '--strict'+ option and disables other options.++ * Added code to html2markdown that tries to determine the character+ encoding of an HTML file, by parsing the "Content-type" meta tag.++ + If the encoding can't be determined, then if the content is local,+ the local encoding is used; if it comes from a URL, UTF-8 is used+ by default.+ + If input is from STDIN, don't try to determine character encoding.+ + Encoding can be specified explicitly using '-e' option.++ * Improved warning messages in wrappers:++ + Print warning if iconv not available+ + More user-friendly error messages in markdown2pdf, when+ pdflatex fails.++ * Code cleanup:++ + Renamed 'Text/Pandoc/HtmlEntities' module to+ 'Text/Pandoc/Entities'. Also changed function names so as+ not to be HTML-specific.+ + Refactored SGML string escaping functions from HTML and Docbook+ writers into Text/Pandoc/Shared. (escapeSGML, stringToSGML)+ + Removed 'BlockQuoteContext' from ParserContext, as it isn't+ used anywhere.+ + Removed splitBySpace and replaced it with a general, polymorphic+ splitBy function.+ + Refactored LaTeX reader for clarity (added isArg function).+ + Converted some CR's to LF's in src/ui/default/print.css.+ + Added license text to top of source files.+ + Added module data for haddock to source files.+ + Reformatted code for consistency.++ * Rewrote documentation and man pages. Split README into INSTALL+ and README.++ * Split LICENSE into COPYING and COPYRIGHT.++ * Removed TODO, since we now maintain ToDo on the wiki.++ * Made COPYRIGHT in top level a symlink to debian/copyright, to avoid+ duplication.++ [ Recai Oktaş ]++ * Revamped build process to conform to debian standards and created+ a proper debian package. Closes: #391666.++ * Modified build process to support GHC 6.6.++ + The package can still be compiled using GHC 6.4.2, though because+ of dependencies the "make deb" target works only with GHC 6.6+.+ + The script 'cabalize' is used to create an appropriate+ 'Pandoc.cabal' from 'Pandoc.cabal.in', depending on the GHC and+ Cabal versions.++ * Refactored template processing (fillTemplates.pl).++ * Modified wrapper scripts to make them more robust and portable.+ To avoid code duplication and ensure consistency, wrappers are+ generated via a templating system from templates in src/wrappers.++ + Wrappers now accept multiple filenames, when appropriate.+ + Spaces and tabs allowed in filenames.+ + getopts shell builtin is used for portable option parsing.+ + Improved html2markdown's web grabber code, making it more robust,+ configurable and verbose. Added '-e', '-g' options.++ -- Recai Oktaş <roktas@debian.org> Fri, 05 Jan 2007 09:41:19 +0200++pandoc (0.2) unstable; urgency=low++ * Fixed unicode/utf-8 translation++ -- John MacFarlane <jgm@berkeley.edu> Mon, 14 Aug 2006 00:00:00 -0400++pandoc (0.1) unstable; urgency=low++ * Initial creation of debian package++ -- John MacFarlane <jgm@berkeley.edu> Mon, 14 Aug 2006 00:00:00 -0400
@@ -0,0 +1,89 @@+Scholdoc changelog+==================++All notable changes to Scholdoc will be documented in this file.++This log pertains to Scholdoc development **only**. Pandoc's changelog can be found in the `changelog-pandoc` file.++Scholdoc's version numbers reflect Scholdoc changes only, and does not necessarily correspond to Pandoc's version number. Scholdoc strives to track the latest official Pandoc release. Whenever new Pandoc commits are merged into Scholdoc, it will be noted in the changelog below.++Scholdoc follows semantic versioning with regards to its output schema.++## 0.1.3-alpha - 2014-10-15++**Note:** *This version largely consists of major cleanups under the hood. It bring the development of Scholdoc up-to-date with the latest Pandoc development version, and removed many unnecessary source files related to unused reader/writers.*++### Added+- The Pandoc-derived portion of Scholdoc is now up to date with Pandoc 1.13.1 (commit 8b60d430)+- The build-chain of Scholdoc have been cleaned-up and is now ready for production. Running `make deps && make install` under the source directory now fully builds using its own `scholdoc-types` and `scholdoc-texmath` packages.+- Updated documentation to reflect the Scholdoc project: README.md, CONTRIBUTING.md, BUGS, COPYRIGHT++### Changed+- Scholdoc now looks for custom template files under the `~/.scholdoc/` directory, instead of `~/.pandoc`+- The "--no-standalone" option no longer imply "_bodyOnly" writers. Instead "--no-standalone" now strictly stops all template usage.++## 0.1.2-alpha - 2014-09-09++### Added+- Allow rudimentary Docx output, although most Scholmd elements map to empty++### Changed+- The program name is changed from `scholpandoc` to `scholdoc` to more accurately reflect the limited input/output options compared to Pandoc.++#### HTML output+- Uses HTTPS instead of protocol-relative URLs for default polyfills in the template from CDNJS. This will make previewing local HTML files much easier.+ - Default MathJax CDN URL is also changed to the HTTPS protocol+- Added an additional variable `html-header-includes` for inclusion of HTML-specific header tags. This can be specified in YAML metadata blocks, and will be treated as an unformatted string.++#### LaTeX output+- Added `indentparagraphs` variable to template, so you can change between "no indent/line-height paragraph margins" and "indent/no paragraph margins"+- Added variables `natbib-options` and `biblatex-options` to specify loading options for these citation packages+- Added additional variables to the template for more flexibility in "injection" of custom LaTeX code without resorting to a separate template:+ - `latex-before-documentclass-includes`+ - `latex-before-packages-includes`+ - `latex-after-packages-includes`+ - `latex-header-includes`+ - `latex-after-body-includes`+ - `latex-after-document-includes`+- *All the above variable can be specified in YAML metadata blocks, and will be treated as unformatted strings (along with `geometry`)*++## 0.1.1-alpha - 2014-05-30++### Added+- Allow output of JSON-style native format++### Changed++#### LaTeX output+- No longer hard-codes the `htbp` placement of floats. This is now controlled in the template using the `Float` package.++### Fixed+- Fixed a bug where figures/floats display captions prefixes when it is not needed++## 0.1.0-alpha - 2014-04-22++### Changed++#### HTML output+- Conforms to ScholarlyMarkdown HTML5 Schema 0.1++### Fixed+- The `bibliography` metadata is now treated like a pure string and will not be formatted+- Display math and figure/floats now properly parses if delimiters have multiple trailing whitespaces+- Disabling standalone mode using `_bodyonly` suffix now works again+- Minor code cleanup using `hlint`, refactored various writer monads for floats++## 0.0.1-alpha - 2014-03-16++### Added+- Display math equations that uses the class `math_def` instead of `math` are now appended to a global variable called `$math-macros$`. In the updated templates this is placed in the header, and enables LaTeX declarations that only work in the header++### Changed+- ScholarlyPandoc now has the following arguments enabled by default: `-f markdown_scholarly --smart --parse-raw --standalone`. Renaming the executable to anything other than `scholpandoc` reverts this behavior++### Fixes+- Fixed a bug where templates files are not compiled into the binary, resulting in complaints about "can't find file ..."++## 0.0.0-alpha - 2014-03-14++Initial Release
@@ -0,0 +1,71 @@+Contributing to Scholdoc+========================++Official Scholdoc repository address on GitHub:++https://github.com/timtylin/scholdoc++Had a sudden inspiration?+-------------------------++If you have an awesome idea for Scholdoc, great! You should probably discuss it on the ScholarlyMarkdown discussion forum, so others will have a chance to weigh in.++If your idea is related to the syntax, design, or convention prescribed by ScholarlyMarkdown itself, and concerns changes that would affect all implementations, please talk about it in the Syntax category:++http://forum.scholarlymarkdown.com/category/syntax++If you have suggestions concerning the *behavior* of Scholdoc itself, such as default settings or command-line options, use the Scholdoc category instead:++http://forum.scholarlymarkdown.com/category/implementations/scholdoc+++Have you found a bug?+---------------------++If you feel confident that a bug is directly related to ScholarlyMarkdown features, you can file a report in the Scholdoc issue tracker:++https://github.com/timtylin/scholdoc/issues+ +Before submitting a bug report, please search all issued (both open *and* closed) to make sure it is not a duplicate issue.++Your report should give detailed instructions for how to reproduce the problem,+including++ * the exact command line used+ * the exact input used+ * the output received+ * the output you expected instead++A small test case (just a few lines) is ideal. If your input is large,+try to whittle it down to the minimum necessary to illustrate the problem.++If the issue does not reflect an obvious programming bug, but instead an+undesired behavior, the policy is to aggressively close the issue and move the+discussion to the forum instead (see above). The goal is to ensure that+important discussion concerning potential improvements do not get lost in the+bug tracker.++Any bugs that are also deemed to impact Pandoc itself will be referred to+Pandoc's issue tracker. The official policy is to merge in the fixes only after+it has been made in Pandoc.++The README file will always describe the latest version of improvement to Pandoc+that have been merged into Scholdoc. This information will also be reflected in the changelog.++Pull requests+-------------++Pull requests without an associated issue ticket or discussion on the forum are welcome for bugs and trivial fixes (such as documentation).++All other pull request will be considered, but not necessarily followed-up on. It is very possible that you will be asked to discuss the pull request first on the forum.++All pull requests are expected to meet the [guidelines laid out for Pandoc][pandoc-pr-guidelines].++Technical details+-----------------++All bug fixes and pull requests are requested to provide appropriate addition to the test cases. For information on running tests, as well as the general library structure of Scholdoc, please refer to the [contribution guide for Pandoc][pandoc-contrib-tech].+++[pandoc-pr-guidelines]: http://johnmacfarlane.net/pandoc/CONTRIBUTING.html#patches-and-pull-requests+[pandoc-contrib-tech]: http://johnmacfarlane.net/pandoc/CONTRIBUTING.html#tests
@@ -0,0 +1,346 @@+GNU GENERAL PUBLIC LICENSE+==========================++Version 2, June 1991++Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA++Everyone is permitted to copy and distribute verbatim copies+of this license document, but changing it is not allowed.++Preamble+--------++The licenses for most software are designed to take away your+freedom to share and change it. By contrast, the GNU General Public+License is intended to guarantee your freedom to share and change free+software--to make sure the software is free for all its users. This+General Public License applies to most of the Free Software+Foundation's software and to any other program whose authors commit to+using it. (Some other Free Software Foundation software is covered by+the GNU Library General Public License instead.) You can apply it to+your programs, too.++When we speak of free software, we are referring to freedom, not+price. Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+this service if you wish), that you receive source code or can get it+if you want it, that you can change the software or use pieces of it+in new free programs; and that you know you can do these things.++To protect your rights, we need to make restrictions that forbid+anyone to deny you these rights or to ask you to surrender the rights.+These restrictions translate to certain responsibilities for you if you+distribute copies of the software, or if you modify it.++For example, if you distribute copies of such a program, whether+gratis or for a fee, you must give the recipients all the rights that+you have. You must make sure that they, too, receive or can get the+source code. And you must show them these terms so they know their+rights.++We protect your rights with two steps: (1) copyright the software, and+(2) offer you this license which gives you legal permission to copy,+distribute and/or modify the software.++Also, for each author's protection and ours, we want to make certain+that everyone understands that there is no warranty for this free+software. If the software is modified by someone else and passed on, we+want its recipients to know that what they have is not the original, so+that any problems introduced by others will not reflect on the original+authors' reputations.++Finally, any free program is threatened constantly by software+patents. We wish to avoid the danger that redistributors of a free+program will individually obtain patent licenses, in effect making the+program proprietary. To prevent this, we have made it clear that any+patent must be licensed for everyone's free use or not licensed at all.++The precise terms and conditions for copying, distribution and+modification follow.++GNU GENERAL PUBLIC LICENSE+--------------------------++TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION++0. This License applies to any program or other work which contains+ a notice placed by the copyright holder saying it may be distributed+ under the terms of this General Public License. The "Program", below,+ refers to any such program or work, and a "work based on the Program"+ means either the Program or any derivative work under copyright law:+ that is to say, a work containing the Program or a portion of it,+ either verbatim or with modifications and/or translated into another+ language. (Hereinafter, translation is included without limitation in+ the term "modification".) Each licensee is addressed as "you".++ Activities other than copying, distribution and modification are not+ covered by this License; they are outside its scope. The act of+ running the Program is not restricted, and the output from the Program+ is covered only if its contents constitute a work based on the+ Program (independent of having been made by running the Program).+ Whether that is true depends on what the Program does.++1. You may copy and distribute verbatim copies of the Program's+ source code as you receive it, in any medium, provided that you+ conspicuously and appropriately publish on each copy an appropriate+ copyright notice and disclaimer of warranty; keep intact all the+ notices that refer to this License and to the absence of any warranty;+ and give any other recipients of the Program a copy of this License+ along with the Program.++ You may charge a fee for the physical act of transferring a copy, and+ you may at your option offer warranty protection in exchange for a fee.++2. You may modify your copy or copies of the Program or any portion+ of it, thus forming a work based on the Program, and copy and+ distribute such modifications or work under the terms of Section 1+ above, provided that you also meet all of these conditions:++ a) You must cause the modified files to carry prominent notices+ stating that you changed the files and the date of any change.++ b) You must cause any work that you distribute or publish, that in+ whole or in part contains or is derived from the Program or any+ part thereof, to be licensed as a whole at no charge to all third+ parties under the terms of this License.++ c) If the modified program normally reads commands interactively+ when run, you must cause it, when started running for such+ interactive use in the most ordinary way, to print or display an+ announcement including an appropriate copyright notice and a+ notice that there is no warranty (or else, saying that you provide+ a warranty) and that users may redistribute the program under+ these conditions, and telling the user how to view a copy of this+ License. (Exception: if the Program itself is interactive but+ does not normally print such an announcement, your work based on+ the Program is not required to print an announcement.)++ These requirements apply to the modified work as a whole. If+ identifiable sections of that work are not derived from the Program,+ and can be reasonably considered independent and separate works in+ themselves, then this License, and its terms, do not apply to those+ sections when you distribute them as separate works. But when you+ distribute the same sections as part of a whole which is a work based+ on the Program, the distribution of the whole must be on the terms of+ this License, whose permissions for other licensees extend to the+ entire whole, and thus to each and every part regardless of who wrote it.++ Thus, it is not the intent of this section to claim rights or contest+ your rights to work written entirely by you; rather, the intent is to+ exercise the right to control the distribution of derivative or+ collective works based on the Program.++ In addition, mere aggregation of another work not based on the Program+ with the Program (or with a work based on the Program) on a volume of+ a storage or distribution medium does not bring the other work under+ the scope of this License.++3. You may copy and distribute the Program (or a work based on it,+ under Section 2) in object code or executable form under the terms of+ Sections 1 and 2 above provided that you also do one of the following:++ a) Accompany it with the complete corresponding machine-readable+ source code, which must be distributed under the terms of Sections+ 1 and 2 above on a medium customarily used for software interchange; or,++ b) Accompany it with a written offer, valid for at least three+ years, to give any third party, for a charge no more than your+ cost of physically performing source distribution, a complete+ machine-readable copy of the corresponding source code, to be+ distributed under the terms of Sections 1 and 2 above on a medium+ customarily used for software interchange; or,++ c) Accompany it with the information you received as to the offer+ to distribute corresponding source code. (This alternative is+ allowed only for noncommercial distribution and only if you+ received the program in object code or executable form with such+ an offer, in accord with Subsection b above.)++ The source code for a work means the preferred form of the work for+ making modifications to it. For an executable work, complete source+ code means all the source code for all modules it contains, plus any+ associated interface definition files, plus the scripts used to+ control compilation and installation of the executable. However, as a+ special exception, the source code distributed need not include+ anything that is normally distributed (in either source or binary+ form) with the major components (compiler, kernel, and so on) of the+ operating system on which the executable runs, unless that component+ itself accompanies the executable.++ If distribution of executable or object code is made by offering+ access to copy from a designated place, then offering equivalent+ access to copy the source code from the same place counts as+ distribution of the source code, even though third parties are not+ compelled to copy the source along with the object code.++4. You may not copy, modify, sublicense, or distribute the Program+ except as expressly provided under this License. Any attempt+ otherwise to copy, modify, sublicense or distribute the Program is+ void, and will automatically terminate your rights under this License.+ However, parties who have received copies, or rights, from you under+ this License will not have their licenses terminated so long as such+ parties remain in full compliance.++5. You are not required to accept this License, since you have not+ signed it. However, nothing else grants you permission to modify or+ distribute the Program or its derivative works. These actions are+ prohibited by law if you do not accept this License. Therefore, by+ modifying or distributing the Program (or any work based on the+ Program), you indicate your acceptance of this License to do so, and+ all its terms and conditions for copying, distributing or modifying+ the Program or works based on it.++6. Each time you redistribute the Program (or any work based on the+ Program), the recipient automatically receives a license from the+ original licensor to copy, distribute or modify the Program subject to+ these terms and conditions. You may not impose any further+ restrictions on the recipients' exercise of the rights granted herein.+ You are not responsible for enforcing compliance by third parties to+ this License.++7. If, as a consequence of a court judgment or allegation of patent+ infringement or for any other reason (not limited to patent issues),+ conditions are imposed on you (whether by court order, agreement or+ otherwise) that contradict the conditions of this License, they do not+ excuse you from the conditions of this License. If you cannot+ distribute so as to satisfy simultaneously your obligations under this+ License and any other pertinent obligations, then as a consequence you+ may not distribute the Program at all. For example, if a patent+ license would not permit royalty-free redistribution of the Program by+ all those who receive copies directly or indirectly through you, then+ the only way you could satisfy both it and this License would be to+ refrain entirely from distribution of the Program.++ If any portion of this section is held invalid or unenforceable under+ any particular circumstance, the balance of the section is intended to+ apply and the section as a whole is intended to apply in other+ circumstances.++ It is not the purpose of this section to induce you to infringe any+ patents or other property right claims or to contest validity of any+ such claims; this section has the sole purpose of protecting the+ integrity of the free software distribution system, which is+ implemented by public license practices. Many people have made+ generous contributions to the wide range of software distributed+ through that system in reliance on consistent application of that+ system; it is up to the author/donor to decide if he or she is willing+ to distribute software through any other system and a licensee cannot+ impose that choice.++ This section is intended to make thoroughly clear what is believed to+ be a consequence of the rest of this License.++8. If the distribution and/or use of the Program is restricted in+ certain countries either by patents or by copyrighted interfaces, the+ original copyright holder who places the Program under this License+ may add an explicit geographical distribution limitation excluding+ those countries, so that distribution is permitted only in or among+ countries not thus excluded. In such case, this License incorporates+ the limitation as if written in the body of this License.++9. The Free Software Foundation may publish revised and/or new versions+ of the General Public License from time to time. Such new versions will+ be similar in spirit to the present version, but may differ in detail to+ address new problems or concerns.++ Each version is given a distinguishing version number. If the Program+ specifies a version number of this License which applies to it and "any+ later version", you have the option of following the terms and conditions+ either of that version or of any later version published by the Free+ Software Foundation. If the Program does not specify a version number of+ this License, you may choose any version ever published by the Free Software+ Foundation.++10. If you wish to incorporate parts of the Program into other free+ programs whose distribution conditions are different, write to the author+ to ask for permission. For software which is copyrighted by the Free+ Software Foundation, write to the Free Software Foundation; we sometimes+ make exceptions for this. Our decision will be guided by the two goals+ of preserving the free status of all derivatives of our free software and+ of promoting the sharing and reuse of software generally.++NO WARRANTY++11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,+ REPAIR OR CORRECTION.++12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE+ POSSIBILITY OF SUCH DAMAGES.++END OF TERMS AND CONDITIONS++How to Apply These Terms to Your New Programs+---------------------------------------------++If you develop a new program, and you want it to be of the greatest+possible use to the public, the best way to achieve this is to make it+free software which everyone can redistribute and change under these terms.++To do so, attach the following notices to the program. It is safest+to attach them to the start of each source file to most effectively+convey the exclusion of warranty; and each file should have at least+the "copyright" line and a pointer to where the full notice is found.++ <one line to give the program's name and a brief idea of what it does.>+ Copyright (C) <year> <name of author>++ This program is free software; you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation; either version 2 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program; if not, write to the Free Software+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA++Also add information on how to contact you by electronic and paper mail.++If the program is interactive, make it output a short notice like this+when it starts in an interactive mode:++ Gnomovision version 69, Copyright (C) year name of author+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.+ This is free software, and you are welcome to redistribute it+ under certain conditions; type `show c' for details.++The hypothetical commands `show w' and `show c' should show the appropriate+parts of the General Public License. Of course, the commands you use may+be called something other than `show w' and `show c'; they could even be+mouse-clicks or menu items--whatever suits your program.++You should also get your employer (if you work as a programmer) or your+school, if any, to sign a "copyright disclaimer" for the program, if+necessary. Here is a sample; alter the names:++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program+ `Gnomovision' (which makes passes at compilers) written by James Hacker.++ <signature of Ty Coon>, 1 April 1989+ Ty Coon, President of Vice++This General Public License does not permit incorporating your program into+proprietary programs. If your program is a subroutine library, you may+consider it more useful to permit linking proprietary applications with the+library. If this is what you want to do, use the GNU Library General+Public License instead of this License.
@@ -0,0 +1,95 @@+Scholdoc+Copyright (C) 2014 Tim T.Y. Lin <timtylin at gmail do com>++This code is released under the [GPL], version 2 or later:++ This program is free software; you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation; either version 2 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program; if not, write to the Free Software+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA++The GNU General Public License is available in the file COPYING in+the source distribution. On Debian systems, the complete text of the+GPL can be found in `/usr/share/common-licenses/GPL`.++Scholdoc's complete source code is available on [Github][scholdoc repo].++[GPL]: http://www.gnu.org/copyleft/gpl.html+[scholdoc repo]: https://github.com/timtylin/scholdoc++----------------------------------------------------------------------+Scholdoc is a fork of:++Pandoc+Copyright (C) 2006-2014 John MacFarlane <jgm at berkeley dot edu>++Released under the GNU General Public License version 2 or later.++Pandoc's complete source code is available from the [Pandoc home page].++[Pandoc home page]: http://johnmacfarlane.net/pandoc/++Pandoc includes some code from other authors. The copyright and license+statements for these sources are included below. All are GPL-compatible+licenses.++----------------------------------------------------------------------+src/Text/Pandoc/Writers/Texinfo.hs+Copyright (C) 2008-2014 John MacFarlane and Peter Wang++Released under the GNU General Public License version 2 or later.++----------------------------------------------------------------------+src/Text/Pandoc/Writers/OpenDocument.hs+Copyright (C) 2008-2014 Andrea Rossato and John MacFarlane++Released under the GNU General Public License version 2 or later.++----------------------------------------------------------------------+src/Text/Pandoc/Writers/Org.hs+Copyright (C) 2010-2014 Puneeth Chaganti and JohnMacFarlane++Released under the GNU General Public License version 2 or later.++----------------------------------------------------------------------+src/Text/Pandoc/Readers/Textile.hs+Copyright (C) 2010-2014 Paul Rivier and John MacFarlane++Released under the GNU General Public License version 2 or later.++----------------------------------------------------------------------+src/Text/Pandoc/Readers/Org.hs+tests/Tests/Readers/Org.hs+Copyright (C) 2014 Albert Krewinkel++Released under the GNU General Public License version 2 or later.++----------------------------------------------------------------------+data/LaTeXMathML.js+Adapted by Jeff Knisely and Douglas Woodall from+ASCIIMathML.js v. 1.4.7+Copyright (C) 2005 Peter Jipsen++Released under the GNU General Public License version 2 or later.++----------------------------------------------------------------------+data/MathMLinHTML.js+Copyright (C) 2004 Peter Jipsen http://www.chapman.edu/~jipsen++Released under the GNU General Public License version 2 or later.++------------------------------------------------------------------------+The dzslides template contains javascript and CSS from Paul Rouget's+dzslides template.+http://github.com/apulrouget/dzslides++Released under the Do What the Fuck You Want To Public License.
@@ -0,0 +1,250 @@+Installing Scholdoc+===================++This document describe how to completely install Scholdoc from source. The instructions are largely adapted from Pandoc's installation instructions.++If you are installing the development version from Github, the procedure is identical to Pandoc:++https://github.com/jgm/pandoc/wiki/Installing-the-development-version-of-pandoc++However, Scholdoc relies on its own fork of `pandoc-types`, `texmath`, and+`pandoc-citeproc`. The reposity for all these packages can be found in this+post:++http://forum.scholarlymarkdown.com/t/scholdoc-repository-information/ +++Setting up a Haskell build chain+--------------------------------++Scholdoc is written in pure Haskell. It requires the [GHC] compiler and the [cabal-install] build system. The easiest way to get it is by installing the [Haskell platform] (unless you are using [Homebrew] with OSX or Ubuntu >12.04, see below).++### Using [Homebrew]++OSX users running [Homebrew] can easily get the prerequisites by running+ + brew update+ brew install ghc cabal-install++### Using the `hvr/ghc` PPA on Ubuntu (12.04 or later)++Herbert V. Riedel have conveniently provided a [PPA of pre-compiled GHC and Cabal][hvr-PPA] for recent Ubuntu systems. Here's an example of how to get recommended versions of [GHC] and [cabal-install] using `apt-get`++ sudo add-apt-repository ppa:hvr/ghc+ sudo apt-get update && apt-get install ghc-7.8.3 cabal-install-1.20+++Quick install (stable release from Hackage)+-------------------------------------------++1. Install the [Haskell platform]. This will give you [GHC] and+ the [cabal-install] build tool.++2. Update your package database:++ cabal update++3. Use `cabal` to install Scholdoc and its dependencies:++ cabal install scholdoc++ This procedure will install the released version of Scholdoc,+ which will be downloaded automatically from HackageDB.+ +Quick install (your own version)+--------------------------------++If you want to install a modified or development version+of Scholdoc instead, switch to the source directory.++1. Install the [Haskell platform]. This will give you [GHC] and the + [cabal-install] build tool.++2. Update your package database:++ cabal update++3. Use the provided makefile to trigger the right install instructions for `cabal`:++ make deps+ make install++ **Note:** If you obtained the source from the git repository (rather than a+ release tarball), you'll need to do++ git submodule update --init++ to fetch the contents of `data/templates` before `cabal install`.++4. Make sure the `$CABALDIR/bin` directory is in your path. You should now be + able to run `scholdoc`:++ scholdoc --help++ [Not sure where `$CABALDIR` is?](http://www.haskell.org/haskellwiki/Cabal-Install#The_cabal-install_configuration_file)++Installing Scholdoc-citeproc+----------------------------++If you want to process citations with Scholdoc, you will also need to install a+separate package, `scholdoc-citeproc`. This can be installed using cabal:++ cabal install scholdoc-citeproc++### Locale-sensitive unicode collation++By default `scholdoc-citeproc` uses the "i;unicode-casemap" method to sort+bibliography entries (RFC 5051). If you would like to use the locale-sensitive+unicode collation algorithm instead, specify the `unicode_collation` flag:++ cabal install scholdoc-citeproc -funicode_collation++Note that this requires the `text-icu` library, which in turn depends on the C+library `icu4c`. Installation directions vary by platform. Here is how it might+work on OSX with homebrew:++ brew install icu4c+ cabal install --extra-lib-dirs=/usr/local/Cellar/icu4c/51.1/lib \+ --extra-include-dirs=/usr/local/Cellar/icu4c/51.1/include \+ -funicode_collation text-icu scholdoc-citeproc+++Custom install+--------------++This is a step-by-step procedure that offers maximal control over the build and+installation. Most users should use the quick install, but this information may+be of use to packagers. For more details, see the [Cabal User's Guide]. These+instructions assume that the Scholdoc source directory is your working+directory.++1. Install dependencies: in addition to the [Haskell platform], you will need+ a number of additional libraries. You can install them all with++ cabal update+ cabal install --only-dependencies++2. Configure:++ cabal configure --prefix=DIR --bindir=DIR --libdir=DIR \+ --datadir=DIR --libsubdir=DIR --datasubdir=DIR --docdir=DIR \+ --htmldir=DIR --program-prefix=PREFIX --program-suffix=SUFFIX \+ --mandir=DIR --flags=FLAGSPEC++ All of the options have sensible defaults that can be overridden as needed.++ `FLAGSPEC` is a list of Cabal configuration flags, optionally preceded by a+ `-` (to force the flag to `false`), and separated by spaces. Scholdoc's+ flags include:++ - `embed_data_files`: embed all data files into the binary (default no).+ This is helpful if you want to create a relocatable binary. Note: if this+ option is selected, you need to install the `hsb2hs` preprocessor:++ cabal install hsb2hs++ - `https`: enable support for downloading resources over https (using the+ `http-client` and `http-client-tls` libraries).+ + - `tryscholdoc`: builds a CGI executable that can be served to parse+ ScholarlMarkdown text over the internet. See the contents of the+ `tryscholdoc` directory for more details.++3. Build:++ cabal build++4. Build API documentation:++ cabal haddock --html-location=URL --hyperlink-source++5. Copy the files:++ cabal copy --destdir=PATH++ The default destdir is `/`.++6. Register Scholdoc as a GHC package:++ cabal register++ Package managers may want to use the `--gen-script` option to+ generate a script that can be run to register the package at+ install time.++Creating a relocatable binary+-----------------------------++It is possible to compile Scholdoc such that the data files Scholdoc uses are+embedded in the binary. The resulting binary can be run from any directory and+is completely self-contained.++ cabal install hsb2hs # a required build tool+ cabal install --flags="embed_data_files" citeproc-hs+ cabal configure --flags="embed_data_files"+ cabal build++You can find the Scholdoc executable in `dist/build/scholdoc`. Copy this+wherever you please.++If you use the included `Makefile` commands, then embedding the binary files is+the default behavior.++Running tests+-------------++Scholdoc comes with an automated test suite integrated to cabal. The fastest+way to access the tests is by the Makefile commands.++To build the tests:++ make deps+ make quick++To run the tests:++ make test++To run particular tests (pattern-matching on their names), use `cabal test`+with the `-t` option:++ cabal test --test-options='-t markdown'++If you add a new feature to Scholdoc, please add tests as well, following the+pattern of the existing tests. The test suite code is in+`tests/test-scholdoc.hs`. It is probably easiest to add/modify data files to+the `tests` directory (and change `tests/Tests/Old.hs` if addiitons are made).+For small, detailed behavior and messy edge cases, it is better to modify the+tests under the `tests/Tests` hierarchy corresponding to the Scholdoc module+you are changing.++Running benchmarks+------------------++To build the benchmarks:++ make deps+ make full++To run the benchmarks:++ make bench++To use a smaller sample size so the benchmarks run faster:++ cabal bench --benchmark-options='-s 20'++To run just the markdown benchmarks:++ cabal bench --benchmark-options='markdown'+++[GHC]: http://www.haskell.org/ghc/+[Haskell platform]: http://hackage.haskell.org/platform/+[cabal-install]: http://hackage.haskell.org/trac/hackage/wiki/CabalInstall+[zip-archive]: http://hackage.haskell.org/package/zip-archive+[highlighting-kate]: http://hackage.haskell.org/package/highlighting-kate+[blaze-html]: http://hackage.haskell.org/package/blaze-html+[Cabal User's Guide]: http://www.haskell.org/cabal/release/latest/doc/users-guide/builders.html#setup-configure-paths+[Homebrew]: http://brew.sh+[hvr-PPA]: https://launchpad.net/~hvr/+archive/ubuntu/ghc
@@ -0,0 +1,47 @@+version=$(shell grep '^Version:' scholdoc.cabal | awk '{print $$2;}')++quick:+ cabal configure --enable-tests --disable-optimization+ cabal build++full:+ cabal configure --enable-tests --enable-optimization -ftryscholdoc -fembed_data_files --enable-benchmarks+ cabal build+ cabal haddock++deps:+ cabal install --only-dependencies --enable-tests -ftryscholdoc -fembed_data_files --enable-benchmarks++prof:+ cabal configure --enable-library-profiling --enable-executable-profiling --enable-optimization --enable-tests+ cabal build++test:+ cabal test++bench:+ cabal bench++install: full+ cabal copy+ cabal register++dist:+ cabal sdist+ rm -rf "scholdoc-${version}"+ tar xvzf dist/scholdoc-${version}.tar.gz+ cd scholdoc-${version}+ cabal configure ${CABALARGS} && cabal build && cabal test && cd .. && rm -rf "scholdoc-${version}"++osxpkg:+ ./make_osx_package.sh++unuseddeps: # finds redundant Cabal package dependencies, requires `packunused`+ cabal configure --enable-tests --enable-benchmarks -ftryscholdoc -fembed_data_files --disable-optimization+ cabal build --ghc-option="-ddump-minimal-imports"+ packunused++clean:+ cabal clean++.PHONY: deps quick full install clean test bench haddock osxpkg dist prof unuseddeps
@@ -0,0 +1,3191 @@+% Pandoc User's Guide+% John MacFarlane+% August 30, 2014++Synopsis+========++pandoc [*options*] [*input-file*]...++Description+===========++Pandoc is a [Haskell] library for converting from one markup format to+another, and a command-line tool that uses this library. It can read+[markdown] and (subsets of) [Textile], [reStructuredText], [HTML],+[LaTeX], [MediaWiki markup], [Haddock markup], [OPML], [Emacs+Org-mode], [DocBook], [txt2tags], [EPUB] and [Word docx]; and it can write plain text,+[markdown], [reStructuredText], [XHTML], [HTML 5], [LaTeX] (including+[beamer] slide shows), [ConTeXt], [RTF], [OPML], [DocBook],+[OpenDocument], [ODT], [Word docx], [GNU Texinfo], [MediaWiki markup],+[DokuWiki markup], [Haddock markup], [EPUB] (v2 or v3), [FictionBook2],+[Textile], [groff man] pages, [Emacs Org-Mode], [AsciiDoc], [InDesign ICML],+and [Slidy], [Slideous], [DZSlides], [reveal.js] or [S5] HTML slide shows.+It can also produce [PDF] output on systems where LaTeX is installed.++Pandoc's enhanced version of markdown includes syntax for footnotes,+tables, flexible ordered lists, definition lists, fenced code blocks,+superscript, subscript, strikeout, title blocks, automatic tables of+contents, embedded LaTeX math, citations, and markdown inside HTML block+elements. (These enhancements, described below under+[Pandoc's markdown](#pandocs-markdown), can be disabled using the+`markdown_strict` input or output format.)++In contrast to most existing tools for converting markdown to HTML, which+use regex substitutions, Pandoc has a modular design: it consists of a+set of readers, which parse text in a given format and produce a native+representation of the document, and a set of writers, which convert+this native representation into a target format. Thus, adding an input+or output format requires only adding a reader or writer.++Using `pandoc`+--------------++If no *input-file* is specified, input is read from *stdin*.+Otherwise, the *input-files* are concatenated (with a blank+line between each) and used as input. Output goes to *stdout* by+default (though output to *stdout* is disabled for the `odt`, `docx`,+`epub`, and `epub3` output formats). For output to a file, use the+`-o` option:++ pandoc -o output.html input.txt++Instead of a file, an absolute URI may be given. In this case+pandoc will fetch the content using HTTP:++ pandoc -f html -t markdown http://www.fsf.org++If multiple input files are given, `pandoc` will concatenate them all (with+blank lines between them) before parsing. This feature is disabled for+ binary input formats such as `EPUB` and `docx`.++The format of the input and output can be specified explicitly using+command-line options. The input format can be specified using the+`-r/--read` or `-f/--from` options, the output format using the+`-w/--write` or `-t/--to` options. Thus, to convert `hello.txt` from+markdown to LaTeX, you could type:++ pandoc -f markdown -t latex hello.txt++To convert `hello.html` from html to markdown:++ pandoc -f html -t markdown hello.html++Supported output formats are listed below under the `-t/--to` option.+Supported input formats are listed below under the `-f/--from` option. Note+that the `rst`, `textile`, `latex`, and `html` readers are not complete;+there are some constructs that they do not parse.++If the input or output format is not specified explicitly, `pandoc`+will attempt to guess it from the extensions of+the input and output filenames. Thus, for example,++ pandoc -o hello.tex hello.txt++will convert `hello.txt` from markdown to LaTeX. If no output file+is specified (so that output goes to *stdout*), or if the output file's+extension is unknown, the output format will default to HTML.+If no input file is specified (so that input comes from *stdin*), or+if the input files' extensions are unknown, the input format will+be assumed to be markdown unless explicitly specified.++Pandoc uses the UTF-8 character encoding for both input and output.+If your local character encoding is not UTF-8, you+should pipe input and output through `iconv`:++ iconv -t utf-8 input.txt | pandoc | iconv -f utf-8++Creating a PDF+--------------++Earlier versions of pandoc came with a program, `markdown2pdf`, that+used pandoc and pdflatex to produce a PDF. This is no longer needed,+since `pandoc` can now produce `pdf` output itself. To produce a PDF, simply+specify an output file with a `.pdf` extension. Pandoc will create a latex+file and use pdflatex (or another engine, see `--latex-engine`) to convert it+to PDF:++ pandoc test.txt -o test.pdf++Production of a PDF requires that a LaTeX engine be installed (see+`--latex-engine`, below), and assumes that the following LaTeX packages are+available: `amssymb`, `amsmath`, `ifxetex`, `ifluatex`, `listings` (if the+`--listings` option is used), `fancyvrb`, `longtable`, `booktabs`, `url`,+`graphicx`, `hyperref`, `ulem`, `babel` (if the `lang` variable is set),+`fontspec` (if `xelatex` or `lualatex` is used as the LaTeX engine), `xltxtra`+and `xunicode` (if `xelatex` is used).++`hsmarkdown`+------------++A user who wants a drop-in replacement for `Markdown.pl` may create+a symbolic link to the `pandoc` executable called `hsmarkdown`. When+invoked under the name `hsmarkdown`, `pandoc` will behave as if+invoked with `-f markdown_strict --email-obfuscation=references`,+and all command-line options will be treated as regular arguments.+However, this approach does not work under Cygwin, due to problems with+its simulation of symbolic links.++[Cygwin]: http://www.cygwin.com/+[`iconv`]: http://www.gnu.org/software/libiconv/+[CTAN]: http://www.ctan.org "Comprehensive TeX Archive Network"+[TeX Live]: http://www.tug.org/texlive/+[MacTeX]: http://www.tug.org/mactex/++Options+=======++General options+---------------++`-f` *FORMAT*, `-r` *FORMAT*, `--from=`*FORMAT*, `--read=`*FORMAT*+: Specify input format. *FORMAT* can be `native` (native Haskell),+ `json` (JSON version of native AST), `markdown` (pandoc's+ extended markdown), `markdown_strict` (original unextended markdown),+ `markdown_phpextra` (PHP Markdown Extra extended markdown),+ `markdown_github` (github extended markdown),+ `textile` (Textile), `rst` (reStructuredText), `html` (HTML),+ `docbook` (DocBook), `t2t` (txt2tags), `docx` (docx), `epub` (EPUB),+ `opml` (OPML), `org` (Emacs Org-mode), `mediawiki` (MediaWiki markup),+ `haddock` (Haddock markup), or `latex` (LaTeX). If `+lhs` is appended+ to `markdown`, `rst`,+ `latex`, or `html`, the input will be treated as literate Haskell+ source: see [Literate Haskell support](#literate-haskell-support),+ below. Markdown syntax extensions can be individually enabled or+ disabled by appending `+EXTENSION` or `-EXTENSION` to the format+ name. So, for example, `markdown_strict+footnotes+definition_lists`+ is strict markdown with footnotes and definition lists enabled,+ and `markdown-pipe_tables+hard_line_breaks` is pandoc's markdown+ without pipe tables and with hard line breaks. See [Pandoc's+ markdown](#pandocs-markdown), below, for a list of extensions and+ their names.++`-t` *FORMAT*, `-w` *FORMAT*, `--to=`*FORMAT*, `--write=`*FORMAT*+: Specify output format. *FORMAT* can be `native` (native Haskell),+ `json` (JSON version of native AST), `plain` (plain text),+ `markdown` (pandoc's extended markdown), `markdown_strict` (original+ unextended markdown), `markdown_phpextra` (PHP Markdown extra+ extended markdown), `markdown_github` (github extended markdown),+ `rst` (reStructuredText), `html` (XHTML 1), `html5` (HTML 5),+ `latex` (LaTeX), `beamer` (LaTeX beamer slide show),+ `context` (ConTeXt), `man` (groff man), `mediawiki` (MediaWiki markup),+ `dokuwiki` (DokuWiki markup),+ `textile` (Textile), `org` (Emacs Org-Mode), `texinfo` (GNU Texinfo),+ `opml` (OPML), `docbook` (DocBook), `opendocument` (OpenDocument), `odt`+ (OpenOffice text document), `docx` (Word docx), `haddock` (Haddock+ markup), `rtf` (rich text format), `epub` (EPUB v2 book), `epub3`+ (EPUB v3), `fb2` (FictionBook2 e-book), `asciidoc` (AsciiDoc),+ `icml` (InDesign ICML), `slidy` (Slidy HTML and javascript slide show),+ `slideous` (Slideous HTML and javascript slide show), `dzslides`+ (DZSlides HTML5 + javascript slide show), `revealjs` (reveal.js+ HTML5 + javascript slide show), `s5` (S5 HTML and javascript slide show),+ or the path of a custom lua writer (see [Custom writers](#custom-writers),+ below). Note that `odt`, `epub`, and `epub3` output will not be directed+ to *stdout*; an output filename must be specified using the `-o/--output`+ option. If `+lhs` is appended to `markdown`, `rst`, `latex`, `beamer`,+ `html`, or `html5`, the output will be rendered as literate Haskell+ source: see [Literate Haskell support](#literate-haskell-support), below.+ Markdown syntax extensions can be individually enabled or disabled by+ appending `+EXTENSION` or `-EXTENSION` to the format name, as described+ above under `-f`.++`-o` *FILE*, `--output=`*FILE*+: Write output to *FILE* instead of *stdout*. If *FILE* is+ `-`, output will go to *stdout*. (Exception: if the output+ format is `odt`, `docx`, `epub`, or `epub3`, output to stdout is disabled.)++`--data-dir=`*DIRECTORY*+: Specify the user data directory to search for pandoc data files.+ If this option is not specified, the default user data directory+ will be used. This is++ $HOME/.pandoc++ in unix,++ C:\Documents And Settings\USERNAME\Application Data\pandoc++ in Windows XP, and++ C:\Users\USERNAME\AppData\Roaming\pandoc++ in Windows 7. (You can find the default user data directory+ on your system by looking at the output of `pandoc --version`.)+ A `reference.odt`, `reference.docx`, `default.csl`,+ `epub.css`, `templates`, `slidy`, `slideous`, or `s5` directory+ placed in this directory will override pandoc's normal defaults.++`-v`, `--version`+: Print version.++`-h`, `--help`+: Show usage message.++Reader options+--------------++`-R`, `--parse-raw`+: Parse untranslatable HTML codes and LaTeX environments as raw HTML+ or LaTeX, instead of ignoring them. Affects only HTML and LaTeX+ input. Raw HTML can be printed in markdown, reStructuredText, HTML,+ Slidy, Slideous, DZSlides, reveal.js, and S5 output; raw LaTeX+ can be printed in markdown, reStructuredText, LaTeX, and ConTeXt output.+ The default is for the readers to omit untranslatable HTML codes and+ LaTeX environments. (The LaTeX reader does pass through untranslatable+ LaTeX *commands*, even if `-R` is not specified.)++`-S`, `--smart`+: Produce typographically correct output, converting straight quotes+ to curly quotes, `---` to em-dashes, `--` to en-dashes, and+ `...` to ellipses. Nonbreaking spaces are inserted after certain+ abbreviations, such as "Mr." (Note: This option is significant only when+ the input format is `markdown`, `markdown_strict`, or `textile`. It+ is selected automatically when the input format is `textile` or the+ output format is `latex` or `context`, unless `--no-tex-ligatures`+ is used.)++`--old-dashes`+: Selects the pandoc <= 1.8.2.1 behavior for parsing smart dashes: `-` before+ a numeral is an en-dash, and `--` is an em-dash. This option is selected+ automatically for `textile` input.++`--base-header-level=`*NUMBER*+: Specify the base level for headers (defaults to 1).++`--indented-code-classes=`*CLASSES*+: Specify classes to use for indented code blocks--for example,+ `perl,numberLines` or `haskell`. Multiple classes may be separated+ by spaces or commas.++`--default-image-extension=`*EXTENSION*+: Specify a default extension to use when image paths/URLs have no+ extension. This allows you to use the same source for formats that+ require different kinds of images. Currently this option only affects+ the markdown and LaTeX readers.++`--filter=`*EXECUTABLE*+: Specify an executable to be used as a filter transforming the+ Pandoc AST after the input is parsed and before the output is+ written. The executable should read JSON from stdin and write+ JSON to stdout. The JSON must be formatted like pandoc's own+ JSON input and output. The name of the output format will be+ passed to the filter as the first argument. Hence,++ pandoc --filter ./caps.py -t latex++ is equivalent to++ pandoc -t json | ./caps.py latex | pandoc -f json -t latex++ The latter form may be useful for debugging filters.++ Filters may be written in any language. `Text.Pandoc.JSON`+ exports `toJSONFilter` to facilitate writing filters in Haskell.+ Those who would prefer to write filters in python can use the+ module `pandocfilters`, installable from PyPI. See+ <http://github.com/jgm/pandocfilters> for the module and several+ examples. Note that the *EXECUTABLE* will be sought in the user's+ `PATH`, and not in the working directory, if no directory is+ provided. If you want to run a script in the working directory,+ preface the filename with `./`.++`-M` *KEY[=VAL]*, `--metadata=`*KEY[:VAL]*+: Set the metadata field *KEY* to the value *VAL*. A value specified+ on the command line overrides a value specified in the document.+ Values will be parsed as YAML boolean or string values. If no value is+ specified, the value will be treated as Boolean true. Like+ `--variable`, `--metadata` causes template variables to be set.+ But unlike `--variable`, `--metadata` affects the metadata of the+ underlying document (which is accessible from filters and may be+ printed in some output formats).++`--normalize`+: Normalize the document after reading: merge adjacent+ `Str` or `Emph` elements, for example, and remove repeated `Space`s.++`-p`, `--preserve-tabs`+: Preserve tabs instead of converting them to spaces (the default).+ Note that this will only affect tabs in literal code spans and code+ blocks; tabs in regular text will be treated as spaces.++`--tab-stop=`*NUMBER*+: Specify the number of spaces per tab (default is 4).++`--track-changes=`*accept|reject|all*+: Specifies what to do with insertions and deletions produced by the MS+ Word "track-changes" feature. *accept* (the default), inserts all+ insertions, and ignores all deletions. *reject* inserts all+ deletions and ignores insertions. *all* puts in both insertions+ and deletions, wrapped in spans with `insertion` and `deletion`+ classes, respectively. The author and time of change is+ included. *all* is useful for scripting: only accepting changes+ from a certain reviewer, say, or before a certain date. This+ option only affects the docx reader.++`--extract-media=`*DIR*+: Extract images and other media contained in a docx or epub container+ to the path *DIR*, creating it if necessary, and adjust the images+ references in the document so they point to the extracted files.+ This option only affects the docx and epub readers.++General writer options+----------------------++`-s`, `--standalone`+: Produce output with an appropriate header and footer (e.g. a+ standalone HTML, LaTeX, or RTF file, not a fragment). This option+ is set automatically for `pdf`, `epub`, `epub3`, `fb2`, `docx`, and `odt`+ output.++`--template=`*FILE*+: Use *FILE* as a custom template for the generated document. Implies+ `--standalone`. See [Templates](#templates) below for a description+ of template syntax. If no extension is specified, an extension+ corresponding to the writer will be added, so that `--template=special`+ looks for `special.html` for HTML output. If the template is not+ found, pandoc will search for it in the user data directory+ (see `--data-dir`). If this option is not used, a default+ template appropriate for the output format will be used (see+ `-D/--print-default-template`).++`-V` *KEY[=VAL]*, `--variable=`*KEY[:VAL]*+: Set the template variable *KEY* to the value *VAL* when rendering the+ document in standalone mode. This is generally only useful when the+ `--template` option is used to specify a custom template, since+ pandoc automatically sets the variables used in the default+ templates. If no *VAL* is specified, the key will be given the+ value `true`.++`-D` *FORMAT*, `--print-default-template=`*FORMAT*+: Print the default template for an output *FORMAT*. (See `-t`+ for a list of possible *FORMAT*s.)++`--print-default-data-file=`*FILE*+: Print a default data file.++`--no-wrap`+: Disable text wrapping in output. By default, text is wrapped+ appropriately for the output format.++`--columns`=*NUMBER*+: Specify length of lines in characters (for text wrapping).++`--toc`, `--table-of-contents`+: Include an automatically generated table of contents (or, in+ the case of `latex`, `context`, and `rst`, an instruction to create+ one) in the output document. This option has no effect on `man`,+ `docbook`, `slidy`, `slideous`, `s5`, `docx`, or `odt` output.++`--toc-depth=`*NUMBER*+: Specify the number of section levels to include in the table+ of contents. The default is 3 (which means that level 1, 2, and 3+ headers will be listed in the contents).++`--no-highlight`+: Disables syntax highlighting for code blocks and inlines, even when+ a language attribute is given.++`--highlight-style`=*STYLE*+: Specifies the coloring style to be used in highlighted source code.+ Options are `pygments` (the default), `kate`, `monochrome`,+ `espresso`, `zenburn`, `haddock`, and `tango`.++`-H` *FILE*, `--include-in-header=`*FILE*+: Include contents of *FILE*, verbatim, at the end of the header.+ This can be used, for example, to include special+ CSS or javascript in HTML documents. This option can be used+ repeatedly to include multiple files in the header. They will be+ included in the order specified. Implies `--standalone`.++`-B` *FILE*, `--include-before-body=`*FILE*+: Include contents of *FILE*, verbatim, at the beginning of the+ document body (e.g. after the `<body>` tag in HTML, or the+ `\begin{document}` command in LaTeX). This can be used to include+ navigation bars or banners in HTML documents. This option can be+ used repeatedly to include multiple files. They will be included in+ the order specified. Implies `--standalone`.++`-A` *FILE*, `--include-after-body=`*FILE*+: Include contents of *FILE*, verbatim, at the end of the document+ body (before the `</body>` tag in HTML, or the+ `\end{document}` command in LaTeX). This option can be be used+ repeatedly to include multiple files. They will be included in the+ order specified. Implies `--standalone`.++Options affecting specific writers+----------------------------------++`--self-contained`+: Produce a standalone HTML file with no external dependencies, using+ `data:` URIs to incorporate the contents of linked scripts, stylesheets,+ images, and videos. The resulting file should be "self-contained,"+ in the sense that it needs no external files and no net access to be+ displayed properly by a browser. This option works only with HTML output+ formats, including `html`, `html5`, `html+lhs`, `html5+lhs`, `s5`,+ `slidy`, `slideous`, `dzslides`, and `revealjs`. Scripts, images, and+ stylesheets at absolute URLs will be downloaded; those at relative URLs+ will be sought relative to the working directory (if the first source+ file is local) or relative to the base URL (if the first source+ file is remote). `--self-contained` does not work with `--mathjax`.++`--offline`+: Deprecated synonym for `--self-contained`.++`-5`, `--html5`+: Produce HTML5 instead of HTML4. This option has no effect for writers+ other than `html`. (*Deprecated:* Use the `html5` output format instead.)++`--html-q-tags`+: Use `<q>` tags for quotes in HTML.++`--ascii`+: Use only ascii characters in output. Currently supported only+ for HTML output (which uses numerical entities instead of+ UTF-8 when this option is selected).++`--reference-links`+: Use reference-style links, rather than inline links, in writing markdown+ or reStructuredText. By default inline links are used.++`--atx-headers`+: Use ATX style headers in markdown and asciidoc output. The default is+ to use setext-style headers for levels 1-2, and then ATX headers.++`--chapters`+: Treat top-level headers as chapters in LaTeX, ConTeXt, and DocBook+ output. When the LaTeX template uses the report, book, or+ memoir class, this option is implied. If `beamer` is the output+ format, top-level headers will become `\part{..}`.++`-N`, `--number-sections`+: Number section headings in LaTeX, ConTeXt, HTML, or EPUB output.+ By default, sections are not numbered. Sections with class+ `unnumbered` will never be numbered, even if `--number-sections`+ is specified.++`--number-offset`=*NUMBER[,NUMBER,...]*,+: Offset for section headings in HTML output (ignored in other+ output formats). The first number is added to the section number for+ top-level headers, the second for second-level headers, and so on.+ So, for example, if you want the first top-level header in your+ document to be numbered "6", specify `--number-offset=5`.+ If your document starts with a level-2 header which you want to+ be numbered "1.5", specify `--number-offset=1,4`.+ Offsets are 0 by default. Implies `--number-sections`.++`--no-tex-ligatures`+: Do not convert quotation marks, apostrophes, and dashes to+ the TeX ligatures when writing LaTeX or ConTeXt. Instead, just+ use literal unicode characters. This is needed for using advanced+ OpenType features with XeLaTeX and LuaLaTeX. Note: normally+ `--smart` is selected automatically for LaTeX and ConTeXt+ output, but it must be specified explicitly if `--no-tex-ligatures`+ is selected. If you use literal curly quotes, dashes, and ellipses+ in your source, then you may want to use `--no-tex-ligatures`+ without `--smart`.++`--listings`+: Use listings package for LaTeX code blocks++`-i`, `--incremental`+: Make list items in slide shows display incrementally (one by one).+ The default is for lists to be displayed all at once.++`--slide-level`=*NUMBER*+: Specifies that headers with the specified level create+ slides (for `beamer`, `s5`, `slidy`, `slideous`, `dzslides`). Headers+ above this level in the hierarchy are used to divide the+ slide show into sections; headers below this level create+ subheads within a slide. The default is to set the slide level+ based on the contents of the document; see+ [Structuring the slide show](#structuring-the-slide-show), below.++`--section-divs`+: Wrap sections in `<div>` tags (or `<section>` tags in HTML5),+ and attach identifiers to the enclosing `<div>` (or `<section>`)+ rather than the header itself.+ See [Section identifiers](#header-identifiers-in-html-latex-and-context), below.++`--email-obfuscation=`*none|javascript|references*+: Specify a method for obfuscating `mailto:` links in HTML documents.+ *none* leaves `mailto:` links as they are. *javascript* obfuscates+ them using javascript. *references* obfuscates them by printing their+ letters as decimal or hexadecimal character references.++`--id-prefix`=*STRING*+: Specify a prefix to be added to all automatically generated identifiers+ in HTML and DocBook output, and to footnote numbers in markdown output.+ This is useful for preventing duplicate identifiers when generating+ fragments to be included in other pages.++`-T` *STRING*, `--title-prefix=`*STRING*+: Specify *STRING* as a prefix at the beginning of the title+ that appears in the HTML header (but not in the title as it+ appears at the beginning of the HTML body). Implies+ `--standalone`.++`-c` *URL*, `--css=`*URL*+: Link to a CSS style sheet. This option can be be used repeatedly to+ include multiple files. They will be included in the order specified.++`--reference-odt=`*FILE*+: Use the specified file as a style reference in producing an ODT.+ For best results, the reference ODT should be a modified version+ of an ODT produced using pandoc. The contents of the reference ODT+ are ignored, but its stylesheets are used in the new ODT. If no+ reference ODT is specified on the command line, pandoc will look+ for a file `reference.odt` in the user data directory (see+ `--data-dir`). If this is not found either, sensible defaults will be+ used.++`--reference-docx=`*FILE*+: Use the specified file as a style reference in producing a docx file.+ For best results, the reference docx should be a modified version+ of a docx file produced using pandoc. The contents of the reference docx+ are ignored, but its stylesheets and document properties (including+ margins, page size, header, and footer) are used in the new docx. If no+ reference docx is specified on the command line, pandoc will look+ for a file `reference.docx` in the user data directory (see+ `--data-dir`). If this is not found either, sensible defaults will be+ used. The following styles are used by pandoc: [paragraph]+ Normal, Compact, Title, Subtitle, Authors, Date, Abstract, Heading 1,+ Heading 2, Heading 3, Heading 4, Heading 5, Block Quote, Definition Term,+ Definition, Bibliography, Body Text, Table Caption, Image Caption;+ [character] Default Paragraph Font, Body Text Char, Verbatim Char,+ Footnote Ref, Link.++`--epub-stylesheet=`*FILE*+: Use the specified CSS file to style the EPUB. If no stylesheet+ is specified, pandoc will look for a file `epub.css` in the+ user data directory (see `--data-dir`). If it is not+ found there, sensible defaults will be used.++`--epub-cover-image=`*FILE*+: Use the specified image as the EPUB cover. It is recommended+ that the image be less than 1000px in width and height. Note that+ in a markdown source document you can also specify `cover-image`+ in a YAML metadata block (see [EPUB Metadata], below).++`--epub-metadata=`*FILE*+: Look in the specified XML file for metadata for the EPUB.+ The file should contain a series of Dublin Core elements,+ as documented at <http://dublincore.org/documents/dces/>.+ For example:++ <dc:rights>Creative Commons</dc:rights>+ <dc:language>es-AR</dc:language>++ By default, pandoc will include the following metadata elements:+ `<dc:title>` (from the document title), `<dc:creator>` (from the+ document authors), `<dc:date>` (from the document date, which should+ be in [ISO 8601 format]), `<dc:language>` (from the `lang`+ variable, or, if is not set, the locale), and `<dc:identifier+ id="BookId">` (a randomly generated UUID). Any of these may be+ overridden by elements in the metadata file.++ Note: if the source document is markdown, a YAML metadata block+ in the document can be used instead. See below under+ [EPUB Metadata].++`--epub-embed-font=`*FILE*+: Embed the specified font in the EPUB. This option can be repeated+ to embed multiple fonts. To use embedded fonts, you+ will need to add declarations like the following to your CSS (see+ `--epub-stylesheet`):++ @font-face {+ font-family: DejaVuSans;+ font-style: normal;+ font-weight: normal;+ src:url("DejaVuSans-Regular.ttf");+ }+ @font-face {+ font-family: DejaVuSans;+ font-style: normal;+ font-weight: bold;+ src:url("DejaVuSans-Bold.ttf");+ }+ @font-face {+ font-family: DejaVuSans;+ font-style: italic;+ font-weight: normal;+ src:url("DejaVuSans-Oblique.ttf");+ }+ @font-face {+ font-family: DejaVuSans;+ font-style: italic;+ font-weight: bold;+ src:url("DejaVuSans-BoldOblique.ttf");+ }+ body { font-family: "DejaVuSans"; }++`--epub-chapter-level=`*NUMBER*+: Specify the header level at which to split the EPUB into separate+ "chapter" files. The default is to split into chapters at level 1+ headers. This option only affects the internal composition of the+ EPUB, not the way chapters and sections are displayed to users. Some+ readers may be slow if the chapter files are too large, so for large+ documents with few level 1 headers, one might want to use a chapter+ level of 2 or 3.++`--latex-engine=`*pdflatex|lualatex|xelatex*+: Use the specified LaTeX engine when producing PDF output.+ The default is `pdflatex`. If the engine is not in your PATH,+ the full path of the engine may be specified here.++Citation rendering+------------------++`--bibliography=`*FILE*+: Set the `bibliography` field in the document's metadata to *FILE*,+ overriding any value set in the metadata, and process citations+ using `pandoc-citeproc`. (This is equivalent to+ `--metadata bibliography=FILE --filter pandoc-citeproc`.)++`--csl=`*FILE*+: Set the `csl` field in the document's metadata to *FILE*,+ overriding any value set in the metadata. (This is equivalent to+ `--metadata csl=FILE`.)++`--citation-abbreviations=`*FILE*+: Set the `citation-abbreviations` field in the document's metadata to+ *FILE*, overriding any value set in the metadata. (This is equivalent to+ `--metadata citation-abbreviations=FILE`.)++`--natbib`+: Use natbib for citations in LaTeX output. This option is not for use+ with the `pandoc-citeproc` filter or with PDF output. It is intended for+ use in producing a LaTeX file that can be processed with pdflatex and+ bibtex.++`--biblatex`+: Use biblatex for citations in LaTeX output. This option is not for use+ with the `pandoc-citeproc` filter or with PDF output. It is intended for+ use in producing a LaTeX file that can be processed with pdflatex and+ bibtex or biber.++Math rendering in HTML+----------------------++`-m` [*URL*], `--latexmathml`[=*URL*]+: Use the [LaTeXMathML] script to display embedded TeX math in HTML output.+ To insert a link to a local copy of the `LaTeXMathML.js` script,+ provide a *URL*. If no *URL* is provided, the contents of the+ script will be inserted directly into the HTML header, preserving+ portability at the price of efficiency. If you plan to use math on+ several pages, it is much better to link to a copy of the script,+ so it can be cached.++`--mathml`[=*URL*]+: Convert TeX math to MathML (in `docbook` as well as `html` and `html5`).+ In standalone `html` output, a small javascript (or a link to such a+ script if a *URL* is supplied) will be inserted that allows the MathML to+ be viewed on some browsers.++`--jsmath`[=*URL*]+: Use [jsMath] to display embedded TeX math in HTML output.+ The *URL* should point to the jsMath load script (e.g.+ `jsMath/easy/load.js`); if provided, it will be linked to in+ the header of standalone HTML documents. If a *URL* is not provided,+ no link to the jsMath load script will be inserted; it is then+ up to the author to provide such a link in the HTML template.++`--mathjax`[=*URL*]+: Use [MathJax] to display embedded TeX math in HTML output.+ The *URL* should point to the `MathJax.js` load script.+ If a *URL* is not provided, a link to the MathJax CDN will+ be inserted.++`--gladtex`+: Enclose TeX math in `<eq>` tags in HTML output. These can then+ be processed by [gladTeX] to produce links to images of the typeset+ formulas.++`--mimetex`[=*URL*]+: Render TeX math using the [mimeTeX] CGI script. If *URL* is not+ specified, it is assumed that the script is at `/cgi-bin/mimetex.cgi`.++`--webtex`[=*URL*]+: Render TeX formulas using an external script that converts TeX+ formulas to images. The formula will be concatenated with the URL+ provided. If *URL* is not specified, the Google Chart API will be used.++`--katex`[=*URL*]+: Use [KaTeX] to display embedded TeX math in HTML output.+ The *URL* should point to the `katex.js` load script. If a *URL* is+ not provided, a link to the KaTeX CDN will be inserted.++`--katex-stylesheet=*URL*`+: The *URL* should point to the `katex.css` stylesheet. If this option is+ not specified, a link to the KaTeX CDN will be inserted. Note that this+ option does not imply `--katex`.++Options for wrapper scripts+---------------------------++`--dump-args`+: Print information about command-line arguments to *stdout*, then exit.+ This option is intended primarily for use in wrapper scripts.+ The first line of output contains the name of the output file specified+ with the `-o` option, or `-` (for *stdout*) if no output file was+ specified. The remaining lines contain the command-line arguments,+ one per line, in the order they appear. These do not include regular+ Pandoc options and their arguments, but do include any options appearing+ after a `--` separator at the end of the line.++`--ignore-args`+: Ignore command-line arguments (for use in wrapper scripts).+ Regular Pandoc options are not ignored. Thus, for example,++ pandoc --ignore-args -o foo.html -s foo.txt -- -e latin1++ is equivalent to++ pandoc -o foo.html -s++[LaTeXMathML]: http://math.etsu.edu/LaTeXMathML/+[jsMath]: http://www.math.union.edu/~dpvc/jsmath/+[MathJax]: http://www.mathjax.org/+[gladTeX]: http://ans.hsh.no/home/mgg/gladtex/+[mimeTeX]: http://www.forkosh.com/mimetex.html+[CSL]: http://CitationStyles.org++Templates+=========++When the `-s/--standalone` option is used, pandoc uses a template to+add header and footer material that is needed for a self-standing+document. To see the default template that is used, just type++ pandoc -D FORMAT++where `FORMAT` is the name of the output format. A custom template+can be specified using the `--template` option. You can also override+the system default templates for a given output format `FORMAT`+by putting a file `templates/default.FORMAT` in the user data+directory (see `--data-dir`, above). *Exceptions:* For `odt` output,+customize the `default.opendocument` template. For `pdf` output,+customize the `default.latex` template.++Templates may contain *variables*. Variable names are sequences of+alphanumerics, `-`, and `_`, starting with a letter. A variable name+surrounded by `$` signs will be replaced by its value. For example,+the string `$title$` in++ <title>$title$</title>++will be replaced by the document title.++To write a literal `$` in a template, use `$$`.++Some variables are set automatically by pandoc. These vary somewhat+depending on the output format, but include metadata fields (such+as `title`, `author`, and `date`) as well as the following:++`header-includes`+: contents specified by `-H/--include-in-header` (may have multiple+ values)++`toc`+: non-null value if `--toc/--table-of-contents` was specified++`include-before`+: contents specified by `-B/--include-before-body` (may have+ multiple values)++`include-after`+: contents specified by `-A/--include-after-body` (may have+ multiple values)++`body`+: body of document++`lang`+: language code for HTML or LaTeX documents++`slidy-url`+: base URL for Slidy documents (defaults to+ `http://www.w3.org/Talks/Tools/Slidy2`)++`slideous-url`+: base URL for Slideous documents (defaults to `slideous`)++`s5-url`+: base URL for S5 documents (defaults to `s5/default`)++`revealjs-url`+: base URL for reveal.js documents (defaults to `reveal.js`)++`theme`+: reveal.js or LaTeX beamer theme++`transition`+: reveal.js transition++`fontsize`+: font size (10pt, 11pt, 12pt) for LaTeX documents++`documentclass`+: document class for LaTeX documents++`classoption`+: option for LaTeX documentclass, e.g. `oneside`; may be repeated+ for multiple options++`geometry`+: options for LaTeX `geometry` class, e.g. `margin=1in`;+ may be repeated for multiple options++`linestretch`+: adjusts line spacing (requires the `setspace` package)++`fontfamily`+: font package to use for LaTeX documents (with pdflatex):+ TeXLive has `bookman` (Bookman), `utopia` or `fourier` (Utopia),+ `fouriernc` (New Century Schoolbook), `times` or `txfonts` (Times),+ `mathpazo` or `pxfonts` or `mathpple` (Palatino),+ `libertine` (Linux Libertine), `arev` (Arev Sans),+ and the default `lmodern`, among others.++`mainfont`, `sansfont`, `monofont`, `mathfont`+: fonts for LaTeX documents (works only with xelatex+ and lualatex)++`colortheme`+: colortheme for LaTeX beamer documents++`fonttheme`+: fonttheme for LaTeX beamer documents++`linkcolor`+: color for internal links in LaTeX documents (`red`, `green`,+ `magenta`, `cyan`, `blue`, `black`)++`urlcolor`+: color for external links in LaTeX documents++`citecolor`+: color for citation links in LaTeX documents++`links-as-notes`+: causes links to be printed as footnotes in LaTeX documents++`toc`+: include table of contents in LaTeX documents++`toc-depth`+: level of section to include in table of contents in LaTeX documents++`lof`+: include list of figures in LaTeX documents++`lot`+: include list of tables in LaTeX documents++`biblio-style`+: bibliography style in LaTeX, when used with `--natbib`++`biblio-files`+: bibliography files to use in LaTeX, with `--natbib` or `--biblatex`++`section`+: section number in man pages++`header`+: header in man pages++`footer`+: footer in man pages++Variables may be set at the command line using the `-V/--variable`+option. Variables set in this way override metadata fields with+the same name.++Templates may contain conditionals. The syntax is as follows:++ $if(variable)$+ X+ $else$+ Y+ $endif$++This will include `X` in the template if `variable` has a non-null+value; otherwise it will include `Y`. `X` and `Y` are placeholders for+any valid template text, and may include interpolated variables or other+conditionals. The `$else$` section may be omitted.++When variables can have multiple values (for example, `author` in+a multi-author document), you can use the `$for$` keyword:++ $for(author)$+ <meta name="author" content="$author$" />+ $endfor$++You can optionally specify a separator to be used between+consecutive items:++ $for(author)$$author$$sep$, $endfor$++A dot can be used to select a field of a variable that takes+an object as its value. So, for example:++ $author.name$ ($author.affiliation$)++If you use custom templates, you may need to revise them as pandoc+changes. We recommend tracking the changes in the default templates,+and modifying your custom templates accordingly. An easy way to do this+is to fork the pandoc-templates repository+(<http://github.com/jgm/pandoc-templates>) and merge in changes after each+pandoc release.++Pandoc's markdown+=================++Pandoc understands an extended and slightly revised version of+John Gruber's [markdown] syntax. This document explains the syntax,+noting differences from standard markdown. Except where noted, these+differences can be suppressed by using the `markdown_strict` format instead+of `markdown`. An extensions can be enabled by adding `+EXTENSION`+to the format name and disabled by adding `-EXTENSION`. For example,+`markdown_strict+footnotes` is strict markdown with footnotes+enabled, while `markdown-footnotes-pipe_tables` is pandoc's+markdown without footnotes or pipe tables.++Philosophy+----------++Markdown is designed to be easy to write, and, even more importantly,+easy to read:++> A Markdown-formatted document should be publishable as-is, as plain+> text, without looking like it's been marked up with tags or formatting+> instructions.+> -- [John Gruber](http://daringfireball.net/projects/markdown/syntax#philosophy)++This principle has guided pandoc's decisions in finding syntax for+tables, footnotes, and other extensions.++There is, however, one respect in which pandoc's aims are different+from the original aims of markdown. Whereas markdown was originally+designed with HTML generation in mind, pandoc is designed for multiple+output formats. Thus, while pandoc allows the embedding of raw HTML,+it discourages it, and provides other, non-HTMLish ways of representing+important document elements like definition lists, tables, mathematics, and+footnotes.++Paragraphs+----------++A paragraph is one or more lines of text followed by one or more blank line.+Newlines are treated as spaces, so you can reflow your paragraphs as you like.+If you need a hard line break, put two or more spaces at the end of a line.++#### Extension: `escaped_line_breaks` ####++A backslash followed by a newline is also a hard line break.+Note: in multiline and grid table cells, this is the only way+to create a hard line break, since trailing spaces in the cells+are ignored.++Headers+-------++There are two kinds of headers, Setext and atx.++### Setext-style headers ###++A setext-style header is a line of text "underlined" with a row of `=` signs+(for a level one header) or `-` signs (for a level two header):++ A level-one header+ ==================++ A level-two header+ ------------------++The header text can contain inline formatting, such as emphasis (see+[Inline formatting](#inline-formatting), below).+++### Atx-style headers ###++An Atx-style header consists of one to six `#` signs and a line of+text, optionally followed by any number of `#` signs. The number of+`#` signs at the beginning of the line is the header level:++ ## A level-two header++ ### A level-three header ###++As with setext-style headers, the header text can contain formatting:++ # A level-one header with a [link](/url) and *emphasis*++#### Extension: `blank_before_header` ####++Standard markdown syntax does not require a blank line before a header.+Pandoc does require this (except, of course, at the beginning of the+document). The reason for the requirement is that it is all too easy for a+`#` to end up at the beginning of a line by accident (perhaps through line+wrapping). Consider, for example:++ I like several of their flavors of ice cream:+ #22, for example, and #5.+++### Header identifiers in HTML, LaTeX, and ConTeXt ###++#### Extension: `header_attributes` ####++Headers can be assigned attributes using this syntax at the end+of the line containing the header text:++ {#identifier .class .class key=value key=value}++Thus, for example, the following headers will all be assigned the identifier+`foo`:++ # My header {#foo}++ ## My header ## {#foo}++ My other header {#foo}+ ---------------++(This syntax is compatible with [PHP Markdown Extra].)++Note that although this syntax allows assignment of classes and key/value+attributes, writers generally don't use all of this information. Identifiers,+classes, and key/value attributes are used in HTML and HTML-based formats such+as EPUB and slidy. Identifiers are used for labels and link anchors in the+LaTeX, ConTeXt, Textile, and AsciiDoc writers.++Headers with the class `unnumbered` will not be numbered, even if+`--number-sections` is specified. A single hyphen (`-`) in an attribute+context is equivalent to `.unnumbered`, and preferable in non-English+documents. So,++ # My header {-}++is just the same as++ # My header {.unnumbered}++#### Extension: `auto_identifiers` ####++A header without an explicitly specified identifier will be+automatically assigned a unique identifier based on the header text.+To derive the identifier from the header text,++ - Remove all formatting, links, etc.+ - Remove all footnotes.+ - Remove all punctuation, except underscores, hyphens, and periods.+ - Replace all spaces and newlines with hyphens.+ - Convert all alphabetic characters to lowercase.+ - Remove everything up to the first letter (identifiers may+ not begin with a number or punctuation mark).+ - If nothing is left after this, use the identifier `section`.++Thus, for example,++ Header Identifier+ ------------------------------- ----------------------------+ Header identifiers in HTML `header-identifiers-in-html`+ *Dogs*?--in *my* house? `dogs--in-my-house`+ [HTML], [S5], or [RTF]? `html-s5-or-rtf`+ 3. Applications `applications`+ 33 `section`++These rules should, in most cases, allow one to determine the identifier+from the header text. The exception is when several headers have the+same text; in this case, the first will get an identifier as described+above; the second will get the same identifier with `-1` appended; the+third with `-2`; and so on.++These identifiers are used to provide link targets in the table of+contents generated by the `--toc|--table-of-contents` option. They+also make it easy to provide links from one section of a document to+another. A link to this section, for example, might look like this:++ See the section on+ [header identifiers](#header-identifiers-in-html-latex-and-context).++Note, however, that this method of providing links to sections works+only in HTML, LaTeX, and ConTeXt formats.++If the `--section-divs` option is specified, then each section will+be wrapped in a `div` (or a `section`, if `--html5` was specified),+and the identifier will be attached to the enclosing `<div>`+(or `<section>`) tag rather than the header itself. This allows entire+sections to be manipulated using javascript or treated differently in+CSS.++#### Extension: `implicit_header_references` ####++Pandoc behaves as if reference links have been defined for each header.+So, instead of++ [header identifiers](#header-identifiers-in-html)++you can simply write++ [header identifiers]++or++ [header identifiers][]++or++ [the section on header identifiers][header identifiers]++If there are multiple headers with identical text, the corresponding+reference will link to the first one only, and you will need to use explicit+links to link to the others, as described above.++Unlike regular reference links, these references are case-sensitive.++Note: if you have defined an explicit identifier for a header,+then implicit references to it will not work.++Block quotations+----------------++Markdown uses email conventions for quoting blocks of text.+A block quotation is one or more paragraphs or other block elements+(such as lists or headers), with each line preceded by a `>` character+and a space. (The `>` need not start at the left margin, but it should+not be indented more than three spaces.)++ > This is a block quote. This+ > paragraph has two lines.+ >+ > 1. This is a list inside a block quote.+ > 2. Second item.++A "lazy" form, which requires the `>` character only on the first+line of each block, is also allowed:++ > This is a block quote. This+ paragraph has two lines.++ > 1. This is a list inside a block quote.+ 2. Second item.++Among the block elements that can be contained in a block quote are+other block quotes. That is, block quotes can be nested:++ > This is a block quote.+ >+ > > A block quote within a block quote.++#### Extension: `blank_before_blockquote` ####++Standard markdown syntax does not require a blank line before a block+quote. Pandoc does require this (except, of course, at the beginning of the+document). The reason for the requirement is that it is all too easy for a+`>` to end up at the beginning of a line by accident (perhaps through line+wrapping). So, unless the `markdown_strict` format is used, the following does+not produce a nested block quote in pandoc:++ > This is a block quote.+ >> Nested.+++Verbatim (code) blocks+----------------------++### Indented code blocks ###++A block of text indented four spaces (or one tab) is treated as verbatim+text: that is, special characters do not trigger special formatting,+and all spaces and line breaks are preserved. For example,++ if (a > 3) {+ moveShip(5 * gravity, DOWN);+ }++The initial (four space or one tab) indentation is not considered part+of the verbatim text, and is removed in the output.++Note: blank lines in the verbatim text need not begin with four spaces.+++### Fenced code blocks ###++#### Extension: `fenced_code_blocks` ####++In addition to standard indented code blocks, Pandoc supports+*fenced* code blocks. These begin with a row of three or more+tildes (`~`) or backticks (`` ` ``) and end with a row of tildes or+backticks that must be at least as long as the starting row. Everything+between these lines is treated as code. No indentation is necessary:++ ~~~~~~~+ if (a > 3) {+ moveShip(5 * gravity, DOWN);+ }+ ~~~~~~~++Like regular code blocks, fenced code blocks must be separated+from surrounding text by blank lines.++If the code itself contains a row of tildes or backticks, just use a longer+row of tildes or backticks at the start and end:++ ~~~~~~~~~~~~~~~~+ ~~~~~~~~~~+ code including tildes+ ~~~~~~~~~~+ ~~~~~~~~~~~~~~~~++#### Extension: `fenced_code_attributes` ####++Optionally, you may attach attributes to the code block using+this syntax:++ ~~~~ {#mycode .haskell .numberLines startFrom="100"}+ qsort [] = []+ qsort (x:xs) = qsort (filter (< x) xs) ++ [x] +++ qsort (filter (>= x) xs)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Here `mycode` is an identifier, `haskell` and `numberLines` are classes, and+`startFrom` is an attribute with value `100`. Some output formats can use this+information to do syntax highlighting. Currently, the only output formats+that uses this information are HTML and LaTeX. If highlighting is supported+for your output format and language, then the code block above will appear+highlighted, with numbered lines. (To see which languages are supported, do+`pandoc --version`.) Otherwise, the code block above will appear as follows:++ <pre id="mycode" class="haskell numberLines" startFrom="100">+ <code>+ ...+ </code>+ </pre>++A shortcut form can also be used for specifying the language of+the code block:++ ```haskell+ qsort [] = []+ ```++This is equivalent to:++ ``` {.haskell}+ qsort [] = []+ ```++If the `fenced_code_attributes` extension is disabled, but+input contains class attribute(s) for the codeblock, the first+class attribute will be printed after the opening fence as a bare+word.++To prevent all highlighting, use the `--no-highlight` flag.+To set the highlighting style, use `--highlight-style`.++Line blocks+-----------++#### Extension: `line_blocks` ####++A line block is a sequence of lines beginning with a vertical bar (`|`)+followed by a space. The division into lines will be preserved in+the output, as will any leading spaces; otherwise, the lines will+be formatted as markdown. This is useful for verse and addresses:++ | The limerick packs laughs anatomical+ | In space that is quite economical.+ | But the good ones I've seen+ | So seldom are clean+ | And the clean ones so seldom are comical++ | 200 Main St.+ | Berkeley, CA 94718++The lines can be hard-wrapped if needed, but the continuation+line must begin with a space.++ | The Right Honorable Most Venerable and Righteous Samuel L.+ Constable, Jr.+ | 200 Main St.+ | Berkeley, CA 94718++This syntax is borrowed from [reStructuredText].++Lists+-----++### Bullet lists ###++A bullet list is a list of bulleted list items. A bulleted list+item begins with a bullet (`*`, `+`, or `-`). Here is a simple+example:++ * one+ * two+ * three++This will produce a "compact" list. If you want a "loose" list, in which+each item is formatted as a paragraph, put spaces between the items:++ * one++ * two++ * three++The bullets need not be flush with the left margin; they may be+indented one, two, or three spaces. The bullet must be followed+by whitespace.++List items look best if subsequent lines are flush with the first+line (after the bullet):++ * here is my first+ list item.+ * and my second.++But markdown also allows a "lazy" format:++ * here is my first+ list item.+ * and my second.++### The four-space rule ###++A list item may contain multiple paragraphs and other block-level+content. However, subsequent paragraphs must be preceded by a blank line+and indented four spaces or a tab. The list will look better if the first+paragraph is aligned with the rest:++ * First paragraph.++ Continued.++ * Second paragraph. With a code block, which must be indented+ eight spaces:++ { code }++List items may include other lists. In this case the preceding blank+line is optional. The nested list must be indented four spaces or+one tab:++ * fruits+ + apples+ - macintosh+ - red delicious+ + pears+ + peaches+ * vegetables+ + broccoli+ + chard++As noted above, markdown allows you to write list items "lazily," instead of+indenting continuation lines. However, if there are multiple paragraphs or+other blocks in a list item, the first line of each must be indented.++ + A lazy, lazy, list+ item.++ + Another one; this looks+ bad but is legal.++ Second paragraph of second+ list item.++**Note:** Although the four-space rule for continuation paragraphs+comes from the official [markdown syntax guide], the reference implementation,+`Markdown.pl`, does not follow it. So pandoc will give different results than+`Markdown.pl` when authors have indented continuation paragraphs fewer than+four spaces.++The [markdown syntax guide] is not explicit whether the four-space+rule applies to *all* block-level content in a list item; it only+mentions paragraphs and code blocks. But it implies that the rule+applies to all block-level content (including nested lists), and+pandoc interprets it that way.++ [markdown syntax guide]:+ http://daringfireball.net/projects/markdown/syntax#list++### Ordered lists ###++Ordered lists work just like bulleted lists, except that the items+begin with enumerators rather than bullets.++In standard markdown, enumerators are decimal numbers followed+by a period and a space. The numbers themselves are ignored, so+there is no difference between this list:++ 1. one+ 2. two+ 3. three++and this one:++ 5. one+ 7. two+ 1. three++#### Extension: `fancy_lists` ####++Unlike standard markdown, Pandoc allows ordered list items to be marked+with uppercase and lowercase letters and roman numerals, in addition to+arabic numerals. List markers may be enclosed in parentheses or followed by a+single right-parentheses or period. They must be separated from the+text that follows by at least one space, and, if the list marker is a+capital letter with a period, by at least two spaces.[^2]++[^2]: The point of this rule is to ensure that normal paragraphs+ starting with people's initials, like++ B. Russell was an English philosopher.++ do not get treated as list items.++ This rule will not prevent++ (C) 2007 Joe Smith++ from being interpreted as a list item. In this case, a backslash+ escape can be used:++ (C\) 2007 Joe Smith++The `fancy_lists` extension also allows '`#`' to be used as an+ordered list marker in place of a numeral:++ #. one+ #. two++#### Extension: `startnum` ####++Pandoc also pays attention to the type of list marker used, and to the+starting number, and both of these are preserved where possible in the+output format. Thus, the following yields a list with numbers followed+by a single parenthesis, starting with 9, and a sublist with lowercase+roman numerals:++ 9) Ninth+ 10) Tenth+ 11) Eleventh+ i. subone+ ii. subtwo+ iii. subthree++Pandoc will start a new list each time a different type of list+marker is used. So, the following will create three lists:++ (2) Two+ (5) Three+ 1. Four+ * Five++If default list markers are desired, use `#.`:++ #. one+ #. two+ #. three+++### Definition lists ###++#### Extension: `definition_lists` ####++Pandoc supports definition lists, using the syntax of+[PHP Markdown Extra] with some extensions.[^3]++ Term 1++ : Definition 1++ Term 2 with *inline markup*++ : Definition 2++ { some code, part of Definition 2 }++ Third paragraph of definition 2.++Each term must fit on one line, which may optionally be followed by+a blank line, and must be followed by one or more definitions.+A definition begins with a colon or tilde, which may be indented one+or two spaces.++A term may have multiple definitions, and each definition may consist of one or+more block elements (paragraph, code block, list, etc.), each indented four+spaces or one tab stop. The body of the definition (including the first line,+aside from the colon or tilde) should be indented four spaces. However,+as with other markdown lists, you can "lazily" omit indentation except+at the beginning of a paragraph or other block element:++ Term 1++ : Definition+ with lazy continuation.++ Second paragraph of the definition.++If you leave space before the definition (as in the example above),+the text of the definition will be treated as a paragraph. In some+output formats, this will mean greater spacing between term/definition+pairs. For a more compact definition list, omit the space before the+definition:++ Term 1+ ~ Definition 1++ Term 2+ ~ Definition 2a+ ~ Definition 2b++Note that space between items in a definition list is required.+(A variant that loosens this requirement, but disallows "lazy"+hard wrapping, can be activated with `compact_definition_lists`: see+[Non-pandoc extensions](#non-pandoc-extensions), below.)++[^3]: I have been influenced by the suggestions of [David Wheeler](http://www.justatheory.com/computers/markup/modest-markdown-proposal.html).++[PHP Markdown Extra]: http://www.michelf.com/projects/php-markdown/extra/+++### Numbered example lists ###++#### Extension: `example_lists` ####++The special list marker `@` can be used for sequentially numbered+examples. The first list item with a `@` marker will be numbered '1',+the next '2', and so on, throughout the document. The numbered examples+need not occur in a single list; each new list using `@` will take up+where the last stopped. So, for example:++ (@) My first example will be numbered (1).+ (@) My second example will be numbered (2).++ Explanation of examples.++ (@) My third example will be numbered (3).++Numbered examples can be labeled and referred to elsewhere in the+document:++ (@good) This is a good example.++ As (@good) illustrates, ...++The label can be any string of alphanumeric characters, underscores,+or hyphens.+++### Compact and loose lists ###++Pandoc behaves differently from `Markdown.pl` on some "edge+cases" involving lists. Consider this source:++ + First+ + Second:+ - Fee+ - Fie+ - Foe++ + Third++Pandoc transforms this into a "compact list" (with no `<p>` tags around+"First", "Second", or "Third"), while markdown puts `<p>` tags around+"Second" and "Third" (but not "First"), because of the blank space+around "Third". Pandoc follows a simple rule: if the text is followed by+a blank line, it is treated as a paragraph. Since "Second" is followed+by a list, and not a blank line, it isn't treated as a paragraph. The+fact that the list is followed by a blank line is irrelevant. (Note:+Pandoc works this way even when the `markdown_strict` format is specified. This+behavior is consistent with the official markdown syntax description,+even though it is different from that of `Markdown.pl`.)+++### Ending a list ###++What if you want to put an indented code block after a list?++ - item one+ - item two++ { my code block }++Trouble! Here pandoc (like other markdown implementations) will treat+`{ my code block }` as the second paragraph of item two, and not as+a code block.++To "cut off" the list after item two, you can insert some non-indented+content, like an HTML comment, which won't produce visible output in+any format:++ - item one+ - item two++ <!-- end of list -->++ { my code block }++You can use the same trick if you want two consecutive lists instead+of one big list:++ 1. one+ 2. two+ 3. three++ <!-- -->++ 1. uno+ 2. dos+ 3. tres++Horizontal rules+----------------++A line containing a row of three or more `*`, `-`, or `_` characters+(optionally separated by spaces) produces a horizontal rule:++ * * * *++ ---------------+++Tables+------++Four kinds of tables may be used. The first three kinds presuppose the use of+a fixed-width font, such as Courier. The fourth kind can be used with+proportionally spaced fonts, as it does not require lining up columns.++#### Extension: `table_captions` ####++A caption may optionally be provided with all 4 kinds of tables (as+illustrated in the examples below). A caption is a paragraph beginning+with the string `Table:` (or just `:`), which will be stripped off.+It may appear either before or after the table.++#### Extension: `simple_tables` ####++Simple tables look like this:++ Right Left Center Default+ ------- ------ ---------- -------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1++ Table: Demonstration of simple table syntax.++The headers and table rows must each fit on one line. Column+alignments are determined by the position of the header text relative+to the dashed line below it:[^4]++ - If the dashed line is flush with the header text on the right side+ but extends beyond it on the left, the column is right-aligned.+ - If the dashed line is flush with the header text on the left side+ but extends beyond it on the right, the column is left-aligned.+ - If the dashed line extends beyond the header text on both sides,+ the column is centered.+ - If the dashed line is flush with the header text on both sides,+ the default alignment is used (in most cases, this will be left).++[^4]: This scheme is due to Michel Fortin, who proposed it on the+ [Markdown discussion list](http://six.pairlist.net/pipermail/markdown-discuss/2005-March/001097.html).++The table must end with a blank line, or a line of dashes followed by+a blank line.++The column headers may be omitted, provided a dashed line is used+to end the table. For example:++ ------- ------ ---------- -------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1+ ------- ------ ---------- -------++When headers are omitted, column alignments are determined on the basis+of the first line of the table body. So, in the tables above, the columns+would be right, left, center, and right aligned, respectively.++#### Extension: `multiline_tables` ####++Multiline tables allow headers and table rows to span multiple lines+of text (but cells that span multiple columns or rows of the table are+not supported). Here is an example:++ -------------------------------------------------------------+ Centered Default Right Left+ Header Aligned Aligned Aligned+ ----------- ------- --------------- -------------------------+ First row 12.0 Example of a row that+ spans multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ -------------------------------------------------------------++ Table: Here's the caption. It, too, may span+ multiple lines.++These work like simple tables, but with the following differences:++ - They must begin with a row of dashes, before the header text+ (unless the headers are omitted).+ - They must end with a row of dashes, then a blank line.+ - The rows must be separated by blank lines.++In multiline tables, the table parser pays attention to the widths of+the columns, and the writers try to reproduce these relative widths in+the output. So, if you find that one of the columns is too narrow in the+output, try widening it in the markdown source.++Headers may be omitted in multiline tables as well as simple tables:++ ----------- ------- --------------- -------------------------+ First row 12.0 Example of a row that+ spans multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ ----------- ------- --------------- -------------------------++ : Here's a multiline table without headers.++It is possible for a multiline table to have just one row, but the row+should be followed by a blank line (and then the row of dashes that ends+the table), or the table may be interpreted as a simple table.++#### Extension: `grid_tables` ####++Grid tables look like this:++ : Sample grid table.++ +---------------+---------------+--------------------++ | Fruit | Price | Advantages |+ +===============+===============+====================++ | Bananas | $1.34 | - built-in wrapper |+ | | | - bright color |+ +---------------+---------------+--------------------++ | Oranges | $2.10 | - cures scurvy |+ | | | - tasty |+ +---------------+---------------+--------------------+++The row of `=`s separates the header from the table body, and can be+omitted for a headerless table. The cells of grid tables may contain+arbitrary block elements (multiple paragraphs, code blocks, lists,+etc.). Alignments are not supported, nor are cells that span multiple+columns or rows. Grid tables can be created easily using [Emacs table mode].++ [Emacs table mode]: http://table.sourceforge.net/++#### Extension: `pipe_tables` ####++Pipe tables look like this:++ | Right | Left | Default | Center |+ |------:|:-----|---------|:------:|+ | 12 | 12 | 12 | 12 |+ | 123 | 123 | 123 | 123 |+ | 1 | 1 | 1 | 1 |++ : Demonstration of pipe table syntax.++The syntax is [the same as in PHP markdown extra]. The beginning and+ending pipe characters are optional, but pipes are required between all+columns. The colons indicate column alignment as shown. The header+can be omitted, but the horizontal line must still be included, as+it defines column alignments.++Since the pipes indicate column boundaries, columns need not be vertically+aligned, as they are in the above example. So, this is a perfectly+legal (though ugly) pipe table:++ fruit| price+ -----|-----:+ apple|2.05+ pear|1.37+ orange|3.09++The cells of pipe tables cannot contain block elements like paragraphs+and lists, and cannot span multiple lines. Note also that in LaTeX/PDF+output, the cells produced by pipe tables will not wrap, since there+is no information available about relative widths. If you want content+to wrap within cells, use multiline or grid tables.++ [the same as in PHP markdown extra]:+ http://michelf.ca/projects/php-markdown/extra/#table++Note: Pandoc also recognizes pipe tables of the following+form, as can produced by Emacs' orgtbl-mode:++ | One | Two |+ |-----+-------|+ | my | table |+ | is | nice |++The difference is that `+` is used instead of `|`. Other orgtbl features+are not supported. In particular, to get non-default column alignment,+you'll need to add colons as above.++Metadata blocks+---------------++#### Extension: `pandoc_title_block` ####++If the file begins with a title block++ % title+ % author(s) (separated by semicolons)+ % date++it will be parsed as bibliographic information, not regular text. (It+will be used, for example, in the title of standalone LaTeX or HTML+output.) The block may contain just a title, a title and an author,+or all three elements. If you want to include an author but no+title, or a title and a date but no author, you need a blank line:++ %+ % Author++ % My title+ %+ % June 15, 2006++The title may occupy multiple lines, but continuation lines must+begin with leading space, thus:++ % My title+ on multiple lines++If a document has multiple authors, the authors may be put on+separate lines with leading space, or separated by semicolons, or+both. So, all of the following are equivalent:++ % Author One+ Author Two++ % Author One; Author Two++ % Author One;+ Author Two++The date must fit on one line.++All three metadata fields may contain standard inline formatting+(italics, links, footnotes, etc.).++Title blocks will always be parsed, but they will affect the output only+when the `--standalone` (`-s`) option is chosen. In HTML output, titles+will appear twice: once in the document head -- this is the title that+will appear at the top of the window in a browser -- and once at the+beginning of the document body. The title in the document head can have+an optional prefix attached (`--title-prefix` or `-T` option). The title+in the body appears as an H1 element with class "title", so it can be+suppressed or reformatted with CSS. If a title prefix is specified with+`-T` and no title block appears in the document, the title prefix will+be used by itself as the HTML title.++The man page writer extracts a title, man page section number, and+other header and footer information from the title line. The title+is assumed to be the first word on the title line, which may optionally+end with a (single-digit) section number in parentheses. (There should+be no space between the title and the parentheses.) Anything after+this is assumed to be additional footer and header text. A single pipe+character (`|`) should be used to separate the footer text from the header+text. Thus,++ % PANDOC(1)++will yield a man page with the title `PANDOC` and section 1.++ % PANDOC(1) Pandoc User Manuals++will also have "Pandoc User Manuals" in the footer.++ % PANDOC(1) Pandoc User Manuals | Version 4.0++will also have "Version 4.0" in the header.++#### Extension: `yaml_metadata_block` ####++A YAML metadata block is a valid YAML object, delimited by a line of three+hyphens (`---`) at the top and a line of three hyphens (`---`) or three dots+(`...`) at the bottom. A YAML metadata block may occur anywhere in the+document, but if it is not at the beginning, it must be preceded by a blank+line. (Note that, because of the way pandoc concatenates input files when+several are provided, you may also keep the metadata in a separate YAML file+and pass it to pandoc as an argument, along with your markdown files:++ pandoc chap1.md chap2.md chap3.md metadata.yaml -s -o book.html++Just be sure that the YAML file begins with `---` and ends with `---` or+`...`.)++Metadata will be taken from the fields of the YAML object and added to any+existing document metadata. Metadata can contain lists and objects (nested+arbitrarily), but all string scalars will be interpreted as markdown. Fields+with names ending in an underscore will be ignored by pandoc. (They may be+given a role by external processors.)++A document may contain multiple metadata blocks. The metadata fields will+be combined through a *left-biased union*: if two metadata blocks attempt+to set the same field, the value from the first block will be taken.++Note that YAML escaping rules must be followed. Thus, for example,+if a title contains a colon, it must be quoted. The pipe character+(`|`) can be used to begin an indented block that will be interpreted+literally, without need for escaping. This form is necessary+when the field contains blank lines:++ ---+ title: 'This is the title: it contains a colon'+ author:+ - name: Author One+ affiliation: University of Somewhere+ - name: Author Two+ affiliation: University of Nowhere+ tags: [nothing, nothingness]+ abstract: |+ This is the abstract.++ It consists of two paragraphs.+ ...++Template variables will be set automatically from the metadata. Thus, for+example, in writing HTML, the variable `abstract` will be set to the HTML+equivalent of the markdown in the `abstract` field:++ <p>This is the abstract.</p>+ <p>It consists of two paragraphs.</p>++Note: The `author` variable in the default templates expects a simple list or+string. To use the structured authors in the example, you would need a+custom template. For example:++ $for(author)$+ $if(author.name)$+ $author.name$$if(author.affiliation)$ ($author.affiliation$)$endif$+ $else$+ $author$+ $endif$+ $endfor$+++Backslash escapes+-----------------++#### Extension: `all_symbols_escapable` ####++Except inside a code block or inline code, any punctuation or space+character preceded by a backslash will be treated literally, even if it+would normally indicate formatting. Thus, for example, if one writes++ *\*hello\**++one will get++ <em>*hello*</em>++instead of++ <strong>hello</strong>++This rule is easier to remember than standard markdown's rule,+which allows only the following characters to be backslash-escaped:++ \`*_{}[]()>#+-.!++(However, if the `markdown_strict` format is used, the standard markdown rule+will be used.)++A backslash-escaped space is parsed as a nonbreaking space. It will+appear in TeX output as `~` and in HTML and XML as `\ ` or+`\ `.++A backslash-escaped newline (i.e. a backslash occurring at the end of+a line) is parsed as a hard line break. It will appear in TeX output as+`\\` and in HTML as `<br />`. This is a nice alternative to+markdown's "invisible" way of indicating hard line breaks using+two trailing spaces on a line.++Backslash escapes do not work in verbatim contexts.++Smart punctuation+-----------------++#### Extension ####++If the `--smart` option is specified, pandoc will produce typographically+correct output, converting straight quotes to curly quotes, `---` to+em-dashes, `--` to en-dashes, and `...` to ellipses. Nonbreaking spaces+are inserted after certain abbreviations, such as "Mr."++Note: if your LaTeX template uses the `csquotes` package, pandoc will+detect automatically this and use `\enquote{...}` for quoted text.++Inline formatting+-----------------++### Emphasis ###++To *emphasize* some text, surround it with `*`s or `_`, like this:++ This text is _emphasized with underscores_, and this+ is *emphasized with asterisks*.++Double `*` or `_` produces **strong emphasis**:++ This is **strong emphasis** and __with underscores__.++A `*` or `_` character surrounded by spaces, or backslash-escaped,+will not trigger emphasis:++ This is * not emphasized *, and \*neither is this\*.++#### Extension: `intraword_underscores` ####++Because `_` is sometimes used inside words and identifiers,+pandoc does not interpret a `_` surrounded by alphanumeric+characters as an emphasis marker. If you want to emphasize+just part of a word, use `*`:++ feas*ible*, not feas*able*.+++### Strikeout ###++#### Extension: `strikeout` ####++To strikeout a section of text with a horizontal line, begin and end it+with `~~`. Thus, for example,++ This ~~is deleted text.~~+++### Superscripts and subscripts ###++#### Extension: `superscript`, `subscript` ####++Superscripts may be written by surrounding the superscripted text by `^`+characters; subscripts may be written by surrounding the subscripted+text by `~` characters. Thus, for example,++ H~2~O is a liquid. 2^10^ is 1024.++If the superscripted or subscripted text contains spaces, these spaces+must be escaped with backslashes. (This is to prevent accidental+superscripting and subscripting through the ordinary use of `~` and `^`.)+Thus, if you want the letter P with 'a cat' in subscripts, use+`P~a\ cat~`, not `P~a cat~`.+++### Verbatim ###++To make a short span of text verbatim, put it inside backticks:++ What is the difference between `>>=` and `>>`?++If the verbatim text includes a backtick, use double backticks:++ Here is a literal backtick `` ` ``.++(The spaces after the opening backticks and before the closing+backticks will be ignored.)++The general rule is that a verbatim span starts with a string+of consecutive backticks (optionally followed by a space)+and ends with a string of the same number of backticks (optionally+preceded by a space).++Note that backslash-escapes (and other markdown constructs) do not+work in verbatim contexts:++ This is a backslash followed by an asterisk: `\*`.++#### Extension: `inline_code_attributes` ####++Attributes can be attached to verbatim text, just as with+[fenced code blocks](#fenced-code-blocks):++ `<$>`{.haskell}++### Small caps ###++To write small caps, you can use an HTML span tag:++ <span style="font-variant:small-caps;">Small caps</span>++(The semicolon is optional and there may be space after the+colon.) This will work in all output formats that support small caps.++Math+----++#### Extension: `tex_math_dollars` ####++Anything between two `$` characters will be treated as TeX math. The+opening `$` must have a non-space character immediately to its right,+while the closing `$` must have a non-space character immediately to its+left, and must not be followed immediately by a digit. Thus,+`$20,000 and $30,000` won't parse as math. If for some reason+you need to enclose text in literal `$` characters, backslash-escape+them and they won't be treated as math delimiters.++TeX math will be printed in all output formats. How it is rendered+depends on the output format:++Markdown, LaTeX, Org-Mode, ConTeXt+ ~ It will appear verbatim between `$` characters.++reStructuredText+ ~ It will be rendered using an interpreted text role `:math:`, as described+ [here](http://www.american.edu/econ/itex2mml/mathhack.rst).++AsciiDoc+ ~ It will be rendered as `latexmath:[...]`.++Texinfo+ ~ It will be rendered inside a `@math` command.++groff man+ ~ It will be rendered verbatim without `$`'s.++MediaWiki, DokuWiki+ ~ It will be rendered inside `<math>` tags.++Textile+ ~ It will be rendered inside `<span class="math">` tags.++RTF, OpenDocument, ODT+ ~ It will be rendered, if possible, using unicode characters,+ and will otherwise appear verbatim.++Docbook+ ~ If the `--mathml` flag is used, it will be rendered using mathml+ in an `inlineequation` or `informalequation` tag. Otherwise it+ will be rendered, if possible, using unicode characters.++Docx+ ~ It will be rendered using OMML math markup.++FictionBook2+ ~ If the `--webtex` option is used, formulas are rendered as images+ using Google Charts or other compatible web service, downloaded+ and embedded in the e-book. Otherwise, they will appear verbatim.++HTML, Slidy, DZSlides, S5, EPUB+ ~ The way math is rendered in HTML will depend on the+ command-line options selected:++ 1. The default is to render TeX math as far as possible using unicode+ characters, as with RTF, DocBook, and OpenDocument output. Formulas+ are put inside a `span` with `class="math"`, so that they may be+ styled differently from the surrounding text if needed.++ 2. If the `--latexmathml` option is used, TeX math will be displayed+ between `$` or `$$` characters and put in `<span>` tags with class `LaTeX`.+ The [LaTeXMathML] script will be used to render it as formulas.+ (This trick does not work in all browsers, but it works in Firefox.+ In browsers that do not support LaTeXMathML, TeX math will appear+ verbatim between `$` characters.)++ 3. If the `--jsmath` option is used, TeX math will be put inside+ `<span>` tags (for inline math) or `<div>` tags (for display math)+ with class `math`. The [jsMath] script will be used to render+ it.++ 4. If the `--mimetex` option is used, the [mimeTeX] CGI script will+ be called to generate images for each TeX formula. This should+ work in all browsers. The `--mimetex` option takes an optional URL+ as argument. If no URL is specified, it will be assumed that the+ mimeTeX CGI script is at `/cgi-bin/mimetex.cgi`.++ 5. If the `--gladtex` option is used, TeX formulas will be enclosed+ in `<eq>` tags in the HTML output. The resulting `htex` file may then+ be processed by [gladTeX], which will produce image files for each+ formula and an `html` file with links to these images. So, the+ procedure is:++ pandoc -s --gladtex myfile.txt -o myfile.htex+ gladtex -d myfile-images myfile.htex+ # produces myfile.html and images in myfile-images++ 6. If the `--webtex` option is used, TeX formulas will be converted+ to `<img>` tags that link to an external script that converts+ formulas to images. The formula will be URL-encoded and concatenated+ with the URL provided. If no URL is specified, the Google Chart+ API will be used (`http://chart.apis.google.com/chart?cht=tx&chl=`).++ 7. If the `--mathjax` option is used, TeX math will be displayed+ between `\(...\)` (for inline math) or `\[...\]` (for display+ math) and put in `<span>` tags with class `math`.+ The [MathJax] script will be used to render it as formulas.++Raw HTML+--------++#### Extension: `raw_html` ####++Markdown allows you to insert raw HTML (or DocBook) anywhere in a document+(except verbatim contexts, where `<`, `>`, and `&` are interpreted+literally). (Technically this is not an extension, since standard+markdown allows it, but it has been made an extension so that it can+be disabled if desired.)++The raw HTML is passed through unchanged in HTML, S5, Slidy, Slideous,+DZSlides, EPUB, Markdown, and Textile output, and suppressed in other+formats.++#### Extension: `markdown_in_html_blocks` ####++Standard markdown allows you to include HTML "blocks": blocks+of HTML between balanced tags that are separated from the surrounding text+with blank lines, and start and end at the left margin. Within+these blocks, everything is interpreted as HTML, not markdown;+so (for example), `*` does not signify emphasis.++Pandoc behaves this way when the `markdown_strict` format is used; but+by default, pandoc interprets material between HTML block tags as markdown.+Thus, for example, Pandoc will turn++ <table>+ <tr>+ <td>*one*</td>+ <td>[a link](http://google.com)</td>+ </tr>+ </table>++into++ <table>+ <tr>+ <td><em>one</em></td>+ <td><a href="http://google.com">a link</a></td>+ </tr>+ </table>++whereas `Markdown.pl` will preserve it as is.++There is one exception to this rule: text between `<script>` and+`<style>` tags is not interpreted as markdown.++This departure from standard markdown should make it easier to mix+markdown with HTML block elements. For example, one can surround+a block of markdown text with `<div>` tags without preventing it+from being interpreted as markdown.++#### Extension: `native_divs` ####++Use native pandoc `Div` blocks for content inside `<div>` tags.+For the most part this should give the same output as+`markdown_in_html_blocks`, but it makes it easier to write pandoc+filters to manipulate groups of blocks.++#### Extension: `native_spans` ####++Use native pandoc `Span` blocks for content inside `<span>` tags.+For the most part this should give the same output as `raw_html`,+but it makes it easier to write pandoc filters to manipulate groups+of inlines.++Raw TeX+-------++#### Extension: `raw_tex` ####++In addition to raw HTML, pandoc allows raw LaTeX, TeX, and ConTeXt to be+included in a document. Inline TeX commands will be preserved and passed+unchanged to the LaTeX and ConTeXt writers. Thus, for example, you can use+LaTeX to include BibTeX citations:++ This result was proved in \cite{jones.1967}.++Note that in LaTeX environments, like++ \begin{tabular}{|l|l|}\hline+ Age & Frequency \\ \hline+ 18--25 & 15 \\+ 26--35 & 33 \\+ 36--45 & 22 \\ \hline+ \end{tabular}++the material between the begin and end tags will be interpreted as raw+LaTeX, not as markdown.++Inline LaTeX is ignored in output formats other than Markdown, LaTeX,+and ConTeXt.++LaTeX macros+------------++#### Extension: `latex_macros` ####++For output formats other than LaTeX, pandoc will parse LaTeX `\newcommand` and+`\renewcommand` definitions and apply the resulting macros to all LaTeX+math. So, for example, the following will work in all output formats,+not just LaTeX:++ \newcommand{\tuple}[1]{\langle #1 \rangle}++ $\tuple{a, b, c}$++In LaTeX output, the `\newcommand` definition will simply be passed+unchanged to the output.+++Links+-----++Markdown allows links to be specified in several ways.++### Automatic links ###++If you enclose a URL or email address in pointy brackets, it+will become a link:++ <http://google.com>+ <sam@green.eggs.ham>++### Inline links ###++An inline link consists of the link text in square brackets,+followed by the URL in parentheses. (Optionally, the URL can+be followed by a link title, in quotes.)++ This is an [inline link](/url), and here's [one with+ a title](http://fsf.org "click here for a good time!").++There can be no space between the bracketed part and the parenthesized part.+The link text can contain formatting (such as emphasis), but the title cannot.+++### Reference links ###++An *explicit* reference link has two parts, the link itself and the link+definition, which may occur elsewhere in the document (either+before or after the link).++The link consists of link text in square brackets, followed by a label in+square brackets. (There can be space between the two.) The link definition+consists of the bracketed label, followed by a colon and a space, followed by+the URL, and optionally (after a space) a link title either in quotes or in+parentheses.++Here are some examples:++ [my label 1]: /foo/bar.html "My title, optional"+ [my label 2]: /foo+ [my label 3]: http://fsf.org (The free software foundation)+ [my label 4]: /bar#special 'A title in single quotes'++The URL may optionally be surrounded by angle brackets:++ [my label 5]: <http://foo.bar.baz>++The title may go on the next line:++ [my label 3]: http://fsf.org+ "The free software foundation"++Note that link labels are not case sensitive. So, this will work:++ Here is [my link][FOO]++ [Foo]: /bar/baz++In an *implicit* reference link, the second pair of brackets is+empty, or omitted entirely:++ See [my website][], or [my website].++ [my website]: http://foo.bar.baz++Note: In `Markdown.pl` and most other markdown implementations,+reference link definitions cannot occur in nested constructions+such as list items or block quotes. Pandoc lifts this arbitrary+seeming restriction. So the following is fine in pandoc, though+not in most other implementations:++ > My block [quote].+ >+ > [quote]: /foo++### Internal links ###++To link to another section of the same document, use the automatically+generated identifier (see [Header identifiers in HTML, LaTeX, and+ConTeXt](#header-identifiers-in-html-latex-and-context), below).+For example:++ See the [Introduction](#introduction).++or++ See the [Introduction].++ [Introduction]: #introduction++Internal links are currently supported for HTML formats (including+HTML slide shows and EPUB), LaTeX, and ConTeXt.++Images+------++A link immediately preceded by a `!` will be treated as an image.+The link text will be used as the image's alt text:++ ++ ![movie reel]++ [movie reel]: movie.gif++#### Extension: `implicit_figures` ####++An image occurring by itself in a paragraph will be rendered as+a figure with a caption.[^5] (In LaTeX, a figure environment will be+used; in HTML, the image will be placed in a `div` with class+`figure`, together with a caption in a `p` with class `caption`.)+The image's alt text will be used as the caption.++ ++[^5]: This feature is not yet implemented for RTF, OpenDocument, or+ ODT. In those formats, you'll just get an image in a paragraph by+ itself, with no caption.++If you just want a regular inline image, just make sure it is not+the only thing in the paragraph. One way to do this is to insert a+nonbreaking space after the image:++ \+++Footnotes+---------++#### Extension: `footnotes` ####++Pandoc's markdown allows footnotes, using the following syntax:++ Here is a footnote reference,[^1] and another.[^longnote]++ [^1]: Here is the footnote.++ [^longnote]: Here's one with multiple blocks.++ Subsequent paragraphs are indented to show that they+ belong to the previous footnote.++ { some.code }++ The whole paragraph can be indented, or just the first+ line. In this way, multi-paragraph footnotes work like+ multi-paragraph list items.++ This paragraph won't be part of the note, because it+ isn't indented.++The identifiers in footnote references may not contain spaces, tabs,+or newlines. These identifiers are used only to correlate the+footnote reference with the note itself; in the output, footnotes+will be numbered sequentially.++The footnotes themselves need not be placed at the end of the+document. They may appear anywhere except inside other block elements+(lists, block quotes, tables, etc.).++#### Extension: `inline_notes` ####++Inline footnotes are also allowed (though, unlike regular notes,+they cannot contain multiple paragraphs). The syntax is as follows:++ Here is an inline note.^[Inlines notes are easier to write, since+ you don't have to pick an identifier and move down to type the+ note.]++Inline and regular footnotes may be mixed freely.+++Citations+---------++#### Extension: `citations` ####++Using an external filter, `pandoc-citeproc`, pandoc can automatically generate+citations and a bibliography in a number of styles. Basic usage is++ pandoc --filter pandoc-citeproc myinput.txt++In order to use this feature, you will need to specify a bibliography file+using the `bibliography` metadata field in a YAML metadata section.+The bibliography may have any of these formats:++ Format File extension+ ------------ --------------+ MODS .mods+ BibLaTeX .bib+ BibTeX .bibtex+ RIS .ris+ EndNote .enl+ EndNote XML .xml+ ISI .wos+ MEDLINE .medline+ Copac .copac+ JSON citeproc .json++Note that `.bib` can generally be used with both BibTeX and BibLaTeX+files, but you can use `.bibtex` to force BibTeX.++Alternatively you can use a `references` field in the document's YAML+metadata. This should include an array of YAML-encoded references,+for example:++ ---+ references:+ - id: fenner2012a+ title: One-click science marketing+ author:+ - family: Fenner+ given: Martin+ container-title: Nature Materials+ volume: 11+ URL: 'http://dx.doi.org/10.1038/nmat3283'+ DOI: 10.1038/nmat3283+ issue: 4+ publisher: Nature Publishing Group+ page: 261-263+ type: article-journal+ issued:+ year: 2012+ month: 3+ ...++(The program `mods2yaml`, which comes with `pandoc-citeproc`, can help produce+these from a MODS reference collection.)++By default, `pandoc-citeproc` will use a Chicago author-date format for+citations and references. To use another style, you will need to specify+a [CSL] 1.0 style file in the `csl` metadata field. A primer on creating and+modifying CSL styles can be found at+<http://citationstyles.org/downloads/primer.html>. A repository of CSL styles+can be found at <https://github.com/citation-style-language/styles>. See also+<http://zotero.org/styles> for easy browsing.++Citations go inside square brackets and are separated by semicolons.+Each citation must have a key, composed of '@' + the citation+identifier from the database, and may optionally have a prefix,+a locator, and a suffix. The citation key must begin with a letter+or `_`, and may contain alphanumerics, `_`, and internal punctuation+characters (`:.#$%&-+?<>~/`). Here are some examples:++ Blah blah [see @doe99, pp. 33-35; also @smith04, ch. 1].++ Blah blah [@doe99, pp. 33-35, 38-39 and *passim*].++ Blah blah [@smith04; @doe99].++A minus sign (`-`) before the `@` will suppress mention of+the author in the citation. This can be useful when the+author is already mentioned in the text:++ Smith says blah [-@smith04].++You can also write an in-text citation, as follows:++ @smith04 says blah.++ @smith04 [p. 33] says blah.++If the style calls for a list of works cited, it will be placed+at the end of the document. Normally, you will want to end your+document with an appropriate header:++ last paragraph...++ # References++The bibliography will be inserted after this header. Note that+the `unnumbered` class will be added to this header, so that the+section will not be numbered.++If you want to include items in the bibliography without actually+citing them in the body text, you can define a dummy `nocite` metadata+field and put the citations there:++ ---+ nocite: |+ @item1, @item2+ ...++ @item3++In this example, the document will contain a citation for `item3`+only, but the bibliography will contain entries for `item1`, `item2`, and+`item3`.++Non-pandoc extensions+---------------------++The following markdown syntax extensions are not enabled by default+in pandoc, but may be enabled by adding `+EXTENSION` to the format+name, where `EXTENSION` is the name of the extension. Thus, for+example, `markdown+hard_line_breaks` is markdown with hard line breaks.++#### Extension: `lists_without_preceding_blankline` ####++Allow a list to occur right after a paragraph, with no intervening+blank space.++#### Extension: `hard_line_breaks` ####++Causes all newlines within a paragraph to be interpreted as hard line+breaks instead of spaces.++#### Extension: `ignore_line_breaks` ####++Causes newlines within a paragraph to be ignored, rather than being+treated as spaces or as hard line breaks. This option is intended for+use with East Asian languages where spaces are not used between words,+but text is divided into lines for readability.++#### Extension: `tex_math_single_backslash` ####++Causes anything between `\(` and `\)` to be interpreted as inline+TeX math, and anything between `\[` and `\]` to be interpreted+as display TeX math. Note: a drawback of this extension is that+it precludes escaping `(` and `[`.++#### Extension: `tex_math_double_backslash` ####++Causes anything between `\\(` and `\\)` to be interpreted as inline+TeX math, and anything between `\\[` and `\\]` to be interpreted+as display TeX math.++#### Extension: `markdown_attribute` ####++By default, pandoc interprets material inside block-level tags as markdown.+This extension changes the behavior so that markdown is only parsed+inside block-level tags if the tags have the attribute `markdown=1`.++#### Extension: `mmd_title_block` ####++Enables a [MultiMarkdown] style title block at the top of+the document, for example:++ Title: My title+ Author: John Doe+ Date: September 1, 2008+ Comment: This is a sample mmd title block, with+ a field spanning multiple lines.++See the MultiMarkdown documentation for details. If `pandoc_title_block` or+`yaml_metadata_block` is enabled, it will take precedence over+`mmd_title_block`.++ [MultiMarkdown]: http://fletcherpenney.net/multimarkdown/++#### Extension: `abbreviations` ####++Parses PHP Markdown Extra abbreviation keys, like++ *[HTML]: Hyper Text Markup Language++Note that the pandoc document model does not support+abbreviations, so if this extension is enabled, abbreviation keys are+simply skipped (as opposed to being parsed as paragraphs).++#### Extension: `autolink_bare_uris` ####++Makes all absolute URIs into links, even when not surrounded by+pointy braces `<...>`.++#### Extension: `ascii_identifiers` ####++Causes the identifiers produced by `auto_identifiers` to be pure ASCII.+Accents are stripped off of accented latin letters, and non-latin+letters are omitted.++#### Extension: `link_attributes` ####++Parses multimarkdown style key-value attributes on link and image references.+Note that pandoc's internal document model provides nowhere to put+these, so they are presently just ignored.++#### Extension: `mmd_header_identifiers` ####++Parses multimarkdown style header identifiers (in square brackets,+after the header but before any trailing `#`s in an ATX header).++#### Extension: `compact_definition_lists` ####++Activates the definition list syntax of pandoc 1.12.x and earlier.+This syntax differs from the one described [above](#definition-lists)+in several respects:++ - No blank line is required between consecutive items of the+ definition list.+ - To get a "tight" or "compact" list, omit space between consecutive+ items; the space between a term and its definition does not affect+ anything.+ - Lazy wrapping of paragraphs is not allowed: the entire definition must+ be indented four spaces.[^6]++[^6]: To see why laziness is incompatible with relaxing the requirement+ of a blank line between items, consider the following example:++ bar+ : definition+ foo+ : definition++ Is this a single list item with two definitions of "bar," the first of+ which is lazily wrapped, or two list items? To remove the ambiguity+ we must either disallow lazy wrapping or require a blank line between+ list items.++Markdown variants+-----------------++In addition to pandoc's extended markdown, the following markdown+variants are supported:++`markdown_phpextra` (PHP Markdown Extra)+: `footnotes`, `pipe_tables`, `raw_html`, `markdown_attribute`,+ `fenced_code_blocks`, `definition_lists`, `intraword_underscores`,+ `header_attributes`, `abbreviations`.++`markdown_github` (Github-flavored Markdown)+: `pipe_tables`, `raw_html`, `tex_math_single_backslash`,+ `fenced_code_blocks`, `auto_identifiers`,+ `ascii_identifiers`, `backtick_code_blocks`, `autolink_bare_uris`,+ `intraword_underscores`, `strikeout`, `hard_line_breaks`++`markdown_mmd` (MultiMarkdown)+: `pipe_tables` `raw_html`, `markdown_attribute`, `link_attributes`,+ `raw_tex`, `tex_math_double_backslash`, `intraword_underscores`,+ `mmd_title_block`, `footnotes`, `definition_lists`,+ `all_symbols_escapable`, `implicit_header_references`,+ `auto_identifiers`, `mmd_header_identifiers`++`markdown_strict` (Markdown.pl)+: `raw_html`++Extensions with formats other than markdown+-------------------------------------------++Some of the extensions discussed above can be used with formats+other than markdown:++* `auto_identifiers` can be used with `latex`, `rst`, `mediawiki`,+ and `textile` input (and is used by default).++* `tex_math_dollars`, `tex_math_single_backslash`, and+ `tex_math_double_backslash` can be used with `html` input.+ (This is handy for reading web pages formatted using MathJax,+ for example.)++Producing slide shows with Pandoc+=================================++You can use Pandoc to produce an HTML + javascript slide presentation+that can be viewed via a web browser. There are five ways to do this,+using [S5], [DZSlides], [Slidy], [Slideous], or [reveal.js].+You can also produce a PDF slide show using LaTeX [beamer].++Here's the markdown source for a simple slide show, `habits.txt`:++ % Habits+ % John Doe+ % March 22, 2005++ # In the morning++ ## Getting up++ - Turn off alarm+ - Get out of bed++ ## Breakfast++ - Eat eggs+ - Drink coffee++ # In the evening++ ## Dinner++ - Eat spaghetti+ - Drink wine++ ------------------++ ++ ## Going to sleep++ - Get in bed+ - Count sheep++To produce an HTML/javascript slide show, simply type++ pandoc -t FORMAT -s habits.txt -o habits.html++where `FORMAT` is either `s5`, `slidy`, `slideous`, `dzslides`, or `revealjs`.++For Slidy, Slideous, reveal.js, and S5, the file produced by pandoc with the+`-s/--standalone` option embeds a link to javascripts and CSS files, which are+assumed to be available at the relative path `s5/default` (for S5), `slideous`+(for Slideous), `reveal.js` (for reveal.js), or at the Slidy website at+`w3.org` (for Slidy). (These paths can be changed by setting the `slidy-url`,+`slideous-url`, `revealjs-url`, or `s5-url` variables; see `--variable`,+above.) For DZSlides, the (relatively short) javascript and css are included in+the file by default.++With all HTML slide formats, the `--self-contained` option can be used to+produce a single file that contains all of the data necessary to display the+slide show, including linked scripts, stylesheets, images, and videos.++To produce a PDF slide show using beamer, type++ pandoc -t beamer habits.txt -o habits.pdf++Note that a reveal.js slide show can also be converted to a PDF+by printing it to a file from the browser.++Structuring the slide show+--------------------------++By default, the *slide level* is the highest header level in+the hierarchy that is followed immediately by content, and not another+header, somewhere in the document. In the example above, level 1 headers+are always followed by level 2 headers, which are followed by content,+so 2 is the slide level. This default can be overridden using+the `--slide-level` option.++The document is carved up into slides according to the following+rules:++ * A horizontal rule always starts a new slide.++ * A header at the slide level always starts a new slide.++ * Headers *below* the slide level in the hierarchy create+ headers *within* a slide.++ * Headers *above* the slide level in the hierarchy create+ "title slides," which just contain the section title+ and help to break the slide show into sections.++ * A title page is constructed automatically from the document's title+ block, if present. (In the case of beamer, this can be disabled+ by commenting out some lines in the default template.)++These rules are designed to support many different styles of slide show. If+you don't care about structuring your slides into sections and subsections,+you can just use level 1 headers for all each slide. (In that case, level 1+will be the slide level.) But you can also structure the slide show into+sections, as in the example above.++Note: in reveal.js slide shows, if slide level is 2, a two-dimensional+layout will be produced, with level 1 headers building horizontally+and level 2 headers building vertically. It is not recommended that+you use deeper nesting of section levels with reveal.js.++Incremental lists+-----------------++By default, these writers produces lists that display "all at once."+If you want your lists to display incrementally (one item at a time),+use the `-i` option. If you want a particular list to depart from the+default (that is, to display incrementally without the `-i` option and+all at once with the `-i` option), put it in a block quote:++ > - Eat spaghetti+ > - Drink wine++In this way incremental and nonincremental lists can be mixed in+a single document.++Inserting pauses+----------------++You can add "pauses" within a slide by including a paragraph containing+three dots, separated by spaces:++ # Slide with a pause++ content before the pause++ . . .++ content after the pause++Styling the slides+------------------++You can change the style of HTML slides by putting customized CSS files+in `$DATADIR/s5/default` (for S5), `$DATADIR/slidy` (for Slidy),+or `$DATADIR/slideous` (for Slideous),+where `$DATADIR` is the user data directory (see `--data-dir`, above).+The originals may be found in pandoc's system data directory (generally+`$CABALDIR/pandoc-VERSION/s5/default`). Pandoc will look there for any+files it does not find in the user data directory.++For dzslides, the CSS is included in the HTML file itself, and may+be modified there.++For reveal.js, themes can be used by setting the `theme` variable,+for example:++ -V theme=moon++Or you can specify a custom stylesheet using the `--css` option.++To style beamer slides, you can specify a beamer "theme" or "colortheme"+using the `-V` option:++ pandoc -t beamer habits.txt -V theme:Warsaw -o habits.pdf++Note that header attributes will turn into slide attributes+(on a `<div>` or `<section>`) in HTML slide formats, allowing you+to style individual slides. In Beamer, the only header attribute+that affects slides is the `allowframebreaks` class, which sets the+`allowframebreaks` option, causing multiple slides to be created+if the content overfills the frame. This is recommended especially for+bibliographies:++ # References {.allowframebreaks}++Speaker notes+-------------++reveal.js has good support for speaker notes. You can add notes to your+markdown document thus:++ <div class="notes">+ This is my note.++ - It can contain markdown+ - like this list++ </div>++To show the notes window, press `s` while viewing the presentation.+Notes are not yet supported for other slide formats, but the notes+will not appear on the slides themselves.++EPUB Metadata+=============++EPUB metadata may be specified using the `--epub-metadata` option, but+if the source document is markdown, it is better to use a YAML metadata+block. Here is an example:++ ---+ title:+ - type: main+ text: My Book+ - type: subtitle+ text: An investigation of metadata+ creator:+ - role: author+ text: John Smith+ - role: editor+ text: Sarah Jones+ identifier:+ - scheme: DOI+ text: doi:10.234234.234/33+ publisher: My Press+ rights: © 2007 John Smith, CC BY-NC+ ...++The following fields are recognized:++`identifier`+ ~ Either a string value or an object with fields `text` and+ `scheme`. Valid values for `scheme` are `ISBN-10`,+ `GTIN-13`, `UPC`, `ISMN-10`, `DOI`, `LCCN`, `GTIN-14`,+ `ISBN-13`, `Legal deposit number`, `URN`, `OCLC`,+ `ISMN-13`, `ISBN-A`, `JP`, `OLCC`.++`title`+ ~ Either a string value, or an object with fields `file-as` and+ `type`, or a list of such objects. Valid values for `type` are+ `main`, `subtitle`, `short`, `collection`, `edition`, `extended`.++`creator`+ ~ Either a string value, or an object with fields `role`, `file-as`,+ and `text`, or a list of such objects. Valid values for `role` are+ [marc relators](http://www.loc.gov/marc/relators/relaterm.html), but+ pandoc will attempt to translate the human-readable versions+ (like "author" and "editor") to the appropriate marc relators.++`contributor`+ ~ Same format as `creator`.++`date`+ ~ A string value in `YYYY-MM-DD` format. (Only the year is necessary.)+ Pandoc will attempt to convert other common date formats.++`language`+ ~ A string value in [RFC5646] format. Pandoc will default to the local+ language if nothing is specified.++`subject`+ ~ A string value or a list of such values.++`description`+ ~ A string value.++`type`+ ~ A string value.++`format`+ ~ A string value.++`relation`+ ~ A string value.++`coverage`+ ~ A string value.++`rights`+ ~ A string value.++`cover-image`+ ~ A string value (path to cover image).++`stylesheet`+ ~ A string value (path to CSS stylesheet).++`page-progression-direction`+ ~ Either `ltr` or `rtl`. Specifies the `page-progression-direction`+ spine [attribute][EPUBspine].++Literate Haskell support+========================++If you append `+lhs` (or `+literate_haskell`) to an appropriate input or output+format (`markdown`, `markdown_strict`, `rst`, or `latex` for input or output;+`beamer`, `html` or `html5` for output only), pandoc will treat the document as+literate Haskell source. This means that++ - In markdown input, "bird track" sections will be parsed as Haskell+ code rather than block quotations. Text between `\begin{code}`+ and `\end{code}` will also be treated as Haskell code.++ - In markdown output, code blocks with classes `haskell` and `literate`+ will be rendered using bird tracks, and block quotations will be+ indented one space, so they will not be treated as Haskell code.+ In addition, headers will be rendered setext-style (with underlines)+ rather than atx-style (with '#' characters). (This is because ghc+ treats '#' characters in column 1 as introducing line numbers.)++ - In restructured text input, "bird track" sections will be parsed+ as Haskell code.++ - In restructured text output, code blocks with class `haskell` will+ be rendered using bird tracks.++ - In LaTeX input, text in `code` environments will be parsed as+ Haskell code.++ - In LaTeX output, code blocks with class `haskell` will be rendered+ inside `code` environments.++ - In HTML output, code blocks with class `haskell` will be rendered+ with class `literatehaskell` and bird tracks.++Examples:++ pandoc -f markdown+lhs -t html++reads literate Haskell source formatted with markdown conventions and writes+ordinary HTML (without bird tracks).++ pandoc -f markdown+lhs -t html+lhs++writes HTML with the Haskell code in bird tracks, so it can be copied+and pasted as literate Haskell source.++Custom writers+==============++Pandoc can be extended with custom writers written in [lua]. (Pandoc+includes a lua interpreter, so lua need not be installed separately.)++To use a custom writer, simply specify the path to the lua script+in place of the output format. For example:++ pandoc -t data/sample.lua++Creating a custom writer requires writing a lua function for each+possible element in a pandoc document. To get a documented example+which you can modify according to your needs, do++ pandoc --print-default-data-file sample.lua++Authors+=======++© 2006-2013 John MacFarlane (jgm at berkeley dot edu). Released under the+[GPL], version 2 or greater. This software carries no warranty of+any kind. (See COPYRIGHT for full copyright and warranty notices.)+Other contributors include Recai Oktaş, Paulo Tanimoto, Peter Wang,+Andrea Rossato, Eric Kow, infinity0x, Luke Plant, shreevatsa.public,+Puneeth Chaganti, Paul Rivier, rodja.trappe, Bradley Kuhn, thsutton,+Nathan Gass, Jonathan Daugherty, Jérémy Bobbio, Justin Bogner, qerub,+Christopher Sawicki, Kelsey Hightower, Masayoshi Takahashi, Antoine+Latter, Ralf Stephan, Eric Seidel, B. Scott Michel, Gavin Beatty,+Sergey Astanin, Arlo O'Keeffe, Denis Laxalde, Brent Yorgey, David Lazar,+Jamie F. Olson, Matthew Pickering, Albert Krewinkel, mb21, Jesse+Rosenthal.++[markdown]: http://daringfireball.net/projects/markdown/+[reStructuredText]: http://docutils.sourceforge.net/docs/ref/rst/introduction.html+[S5]: http://meyerweb.com/eric/tools/s5/+[Slidy]: http://www.w3.org/Talks/Tools/Slidy/+[Slideous]: http://goessner.net/articles/slideous/+[HTML]: http://www.w3.org/TR/html40/+[HTML 5]: http://www.w3.org/TR/html5/+[XHTML]: http://www.w3.org/TR/xhtml1/+[LaTeX]: http://www.latex-project.org/+[beamer]: http://www.tex.ac.uk/CTAN/macros/latex/contrib/beamer+[ConTeXt]: http://www.pragma-ade.nl/+[RTF]: http://en.wikipedia.org/wiki/Rich_Text_Format+[DocBook]: http://www.docbook.org/+[OPML]: http://dev.opml.org/spec2.html+[OpenDocument]: http://opendocument.xml.org/+[ODT]: http://en.wikipedia.org/wiki/OpenDocument+[Textile]: http://redcloth.org/textile+[MediaWiki markup]: http://www.mediawiki.org/wiki/Help:Formatting+[DokuWiki markup]: https://www.dokuwiki.org/dokuwiki+[Haddock markup]: http://www.haskell.org/haddock/doc/html/ch03s08.html+[groff man]: http://developer.apple.com/DOCUMENTATION/Darwin/Reference/ManPages/man7/groff_man.7.html+[Haskell]: http://www.haskell.org/+[GNU Texinfo]: http://www.gnu.org/software/texinfo/+[Emacs Org-Mode]: http://orgmode.org+[AsciiDoc]: http://www.methods.co.nz/asciidoc/+[GPL]: http://www.gnu.org/copyleft/gpl.html "GNU General Public License"+[DZSlides]: http://paulrouget.com/dzslides/+[ISO 8601 format]: http://www.w3.org/TR/NOTE-datetime+[Word docx]: http://www.microsoft.com/interop/openup/openxml/default.aspx+[PDF]: http://www.adobe.com/pdf/+[reveal.js]: http://lab.hakim.se/reveal-js/+[FictionBook2]: http://www.fictionbook.org/index.php/Eng:XML_Schema_Fictionbook_2.1+[lua]: http://www.lua.org+[marc relators]: http://www.loc.gov/marc/relators/relaterm.html+[RFC5646]: http://tools.ietf.org/html/rfc5646+[InDesign ICML]: https://www.adobe.com/content/dam/Adobe/en/devnet/indesign/cs55-docs/IDML/idml-specification.pdf+[txt2tags]: http://txt2tags.org/+[EPUB]: http://idpf.org/epub+[EPUBspine]: http://www.idpf.org/epub/301/spec/epub-publications.html#sec-spine-elem+[KaTeX]: https://github.com/Khan/KaTeX
@@ -0,0 +1,74 @@+Scholdoc+========++### Converts [ScholarlyMarkdown][scholmd] documents into HTML5, LaTeX, or Docx++**Current stable version:** 0.1.3++**Development build status** [![build status][scholarly-devel-travisimage]][travis_stat] +**Stable build status** [![build status][scholarly-travisimage]][travis_stat]++**Scholdoc** is a command-line utility that converts+[ScholarlyMarkdown][scholmd] documents into the HTML5, LaTeX, and Docx (OOML)+formats. It is intended to facilitate academic writing in a cross-platform,+semantic-aware, plaintext format that can be quickly used in modern publishing+pipelines.++Scholdoc is implemented as fork of [Pandoc][pandoc], and mostly retains the+same user interface (including the custom [template][pandocTemplate] and+[filter][pandocFilters] system). It essentially understands a new input format+`markdown_scholarly` (implemented in the markdown reader a superset of+`markdown_pandoc` features), and limits itself to HTML5/LaTeX/Docx output.+Scholdoc defaults to `standalone` output and has its own [custom+templates][scholdoc-templates] to ensure output compatibility with+[ScholarlyMarkdown][scholmd].++See the [Pandoc Guide][pandocReadme] for more about Pandoc, its usage, and the+Markdown dialect that Pandoc (and hence Scholdoc) [understands][pandocMarkdown].++Scholdoc is currently up to date with [Pandoc][pandoc] version 1.13.1 (commit 8b60d430)+++### HTML output++***Important:*** *A ScholarlyMarkdown [core CSS][corecss] is required for proper+formatting of most HTML files output by Scholdoc.*++Scholdoc's HTML output is strictly limited to HTML5 due to its enhanced+semantic capabilities (such as the `figure` and `figcaption` element), and+relies on some CSS3 features for layout (mostly for multi-image figures with+subcaptions). It adheres to a fairly straightforward [schema][html-schema]. No+formatting information is written to the HTML by Scholdoc, so a+ScholarlyMarkdown [core CSS][corecss] is required for bare minimum proper+formatting. You can also write your own CSS that target the schema.++By default, the `html` output format generates a complete (but bare-bones)+HTML5 document that can be used immediately. To have Scholdoc generate just the+bare content (everything inside [`scholmd-content`][html-schema-content]), use+the `html_bodyonly` output format. By default, Scholdoc will always include+proper [MathJax] settings for the way [ScholarlyMarkdown][scholmd] prescribes+math content in HTML.++### Docx output++The Docx writer currently isn't fully functional yet. It does not yet output structures specific to ScholarlyMarkdown (such as figures).++[scholmd]: http://scholarlymarkdown.com+[scholdoc]: https://github.com/timtylin/scholdoc+[scholdoc-types]: https://github.com/timtylin/scholdoc-types+[texmath]: https://github.com/jgm/texmath+[pandoc]: http://johnmacfarlane.net/pandoc/+[pandocReadme]: http://johnmacfarlane.net/pandoc/README.html+[pandocMarkdown]: http://johnmacfarlane.net/pandoc/README.html#pandocs-markdown+[pandocTemplate]: http://johnmacfarlane.net/pandoc/README.html#templates+[pandocFilters]: https://github.com/jgm/pandocfilters+[pandocWriters]: http://johnmacfarlane.net/pandoc/README.html#custom-writers+[pandoc-types]: https://github.com/jgm/pandoc-types+[travis_stat]: https://travis-ci.org/timtylin/scholdoc-texmath+[scholarly-devel-travisimage]: https://travis-ci.org/timtylin/scholdoc.svg?branch=scholarly-devel+[scholarly-travisimage]: https://travis-ci.org/timtylin/scholdoc.svg?branch=scholarly+[scholdoc-templates]: https://github.com/timtylin/scholdoc-templates+[html-schema]: http://scholarlymarkdown.com/Scholarly-Markdown-HTML-Schema.html+[html-schema-content]: http://scholarlymarkdown.com/Scholarly-Markdown-HTML-Schema.html#content+[corecss]: http://scholarlymarkdown.com/scholdoc-distribution/css/core/scholmd-core-latest.css+[mathjax]: http://www.mathjax.org
@@ -0,0 +1,51 @@+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++import Distribution.Simple+import Distribution.Simple.PreProcess+import Distribution.PackageDescription (PackageDescription(..), Executable(..))+import System.Process ( rawSystem )+import System.FilePath ( (</>) )+import System.Directory ( findExecutable )+import Distribution.Simple.Utils (info)++main :: IO ()+main = defaultMainWithHooks $ simpleUserHooks {+ -- enable hsb2hs preprocessor for .hsb files+ hookedPreProcessors = [ppBlobSuffixHandler]+ -- ensure that make-pandoc-man-pages doesn't get installed to bindir+ , copyHook = \pkgdescr ->+ (copyHook simpleUserHooks) pkgdescr{ executables =+ [x | x <- executables pkgdescr, exeName x /= "make-pandoc-man-pages"] }+ , instHook = \pkgdescr ->+ (instHook simpleUserHooks) pkgdescr{ executables =+ [x | x <- executables pkgdescr, exeName x /= "make-pandoc-man-pages"] }+ }++ppBlobSuffixHandler :: PPSuffixHandler+ppBlobSuffixHandler = ("hsb", \_ _ ->+ PreProcessor {+ platformIndependent = True,+ runPreProcessor = mkSimplePreProcessor $ \infile outfile verbosity ->+ do info verbosity $ "Preprocessing " ++ infile ++ " to " ++ outfile+ hsb2hsPath <- findExecutable "hsb2hs"+ case hsb2hsPath of+ Just p -> rawSystem p [infile, infile, outfile]+ Nothing -> error "hsb2hs is needed to build this program: cabal install hsb2hs"+ return ()+ })
@@ -0,0 +1,57 @@+{-+Copyright (C) 2012-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}+import Text.Pandoc+import Criterion.Main+import Criterion.Config+import System.Environment (getArgs)+import Data.Monoid+import Data.Maybe (mapMaybe)+import Debug.Trace (trace)++readerBench :: Pandoc+ -> (String, ReaderOptions -> String -> IO Pandoc)+ -> Maybe Benchmark+readerBench doc (name, reader) = case lookup name writers of+ Just (PureStringWriter writer) ->+ let inp = writer def{ writerWrapText = True} doc+ in return $ bench (name ++ " reader") $ nfIO $+ (reader def{ readerSmart = True }) inp+ _ -> trace ("\nCould not find writer for " ++ name ++ "\n") Nothing++writerBench :: Pandoc+ -> (String, WriterOptions -> Pandoc -> String)+ -> Benchmark+writerBench doc (name, writer) = bench (name ++ " writer") $ nf+ (writer def{ writerWrapText = True }) doc++main :: IO ()+main = do+ args <- getArgs+ (conf,_) <- parseArgs defaultConfig{ cfgSamples = Last $ Just 20 }+ defaultOptions args+ inp <- readFile "tests/testsuite.txt"+ let opts = def{ readerSmart = True }+ let doc = readMarkdown opts inp+ let readers' = [(n,r) | (n, StringReader r) <- readers]+ let readerBs = mapMaybe (readerBench doc)+ $ filter (\(n,_) -> n /="haddock") readers'+ let writers' = [(n,w) | (n, PureStringWriter w) <- writers]+ let writerBs = map (writerBench doc)+ $ writers'+ defaultMainWith conf (return ()) $+ writerBs ++ readerBs
@@ -0,0 +1,198 @@+/*+LaTeXMathML.js from http://math.etsu.edu/LaTeXMathML/+Adapted by Jeff Knisely and Douglas Woodall from ASCIIMathML.js v. 1.4.7,+(c) 2005 Peter Jipsen http://www.chapman.edu/~jipsen.+Released under the GNU General Public License version 2 or later.+See the GNU General Public License (at http://www.gnu.org/copyleft/gpl.html)+for more details.+*/+var checkForMathML=true;var notifyIfNoMathML=true;var alertIfNoMathML=false;var mathcolor="";var mathfontfamily="";var showasciiformulaonhover=true;var isIE=document.createElementNS==null;if(document.getElementById==null)+alert("This webpage requires a recent browser such as \nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer")+function AMcreateElementXHTML(t){if(isIE)return document.createElement(t);else return document.createElementNS("http://www.w3.org/1999/xhtml",t);}+function AMnoMathMLNote(){var nd=AMcreateElementXHTML("h3");nd.setAttribute("align","center")+nd.appendChild(AMcreateElementXHTML("p"));nd.appendChild(document.createTextNode("To view the "));var an=AMcreateElementXHTML("a");an.appendChild(document.createTextNode("LaTeXMathML"));an.setAttribute("href","http://www.maths.nott.ac.uk/personal/drw/lm.html");nd.appendChild(an);nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+"));an=AMcreateElementXHTML("a");an.appendChild(document.createTextNode("MathPlayer"));an.setAttribute("href","http://www.dessci.com/en/products/mathplayer/download.htm");nd.appendChild(an);nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox"));nd.appendChild(AMcreateElementXHTML("p"));return nd;}+function AMisMathMLavailable(){if(navigator.appName.slice(0,8)=="Netscape")+if(navigator.appVersion.slice(0,1)>="5")return null;else return AMnoMathMLNote();else if(navigator.appName.slice(0,9)=="Microsoft")+try{var ActiveX=new ActiveXObject("MathPlayer.Factory.1");return null;}catch(e){return AMnoMathMLNote();}+else return AMnoMathMLNote();}+var AMcal=[0xEF35,0x212C,0xEF36,0xEF37,0x2130,0x2131,0xEF38,0x210B,0x2110,0xEF39,0xEF3A,0x2112,0x2133,0xEF3B,0xEF3C,0xEF3D,0xEF3E,0x211B,0xEF3F,0xEF40,0xEF41,0xEF42,0xEF43,0xEF44,0xEF45,0xEF46];var AMfrk=[0xEF5D,0xEF5E,0x212D,0xEF5F,0xEF60,0xEF61,0xEF62,0x210C,0x2111,0xEF63,0xEF64,0xEF65,0xEF66,0xEF67,0xEF68,0xEF69,0xEF6A,0x211C,0xEF6B,0xEF6C,0xEF6D,0xEF6E,0xEF6F,0xEF70,0xEF71,0x2128];var AMbbb=[0xEF8C,0xEF8D,0x2102,0xEF8E,0xEF8F,0xEF90,0xEF91,0x210D,0xEF92,0xEF93,0xEF94,0xEF95,0xEF96,0x2115,0xEF97,0x2119,0x211A,0x211D,0xEF98,0xEF99,0xEF9A,0xEF9B,0xEF9C,0xEF9D,0xEF9E,0x2124];var CONST=0,UNARY=1,BINARY=2,INFIX=3,LEFTBRACKET=4,RIGHTBRACKET=5,SPACE=6,UNDEROVER=7,DEFINITION=8,TEXT=9,BIG=10,LONG=11,STRETCHY=12,MATRIX=13;var AMsqrt={input:"\\sqrt",tag:"msqrt",output:"sqrt",ttype:UNARY},AMroot={input:"\\root",tag:"mroot",output:"root",ttype:BINARY},AMfrac={input:"\\frac",tag:"mfrac",output:"/",ttype:BINARY},AMover={input:"\\stackrel",tag:"mover",output:"stackrel",ttype:BINARY},AMatop={input:"\\atop",tag:"mfrac",output:"",ttype:INFIX},AMchoose={input:"\\choose",tag:"mfrac",output:"",ttype:INFIX},AMsub={input:"_",tag:"msub",output:"_",ttype:INFIX},AMsup={input:"^",tag:"msup",output:"^",ttype:INFIX},AMtext={input:"\\mathrm",tag:"mtext",output:"text",ttype:TEXT},AMmbox={input:"\\mbox",tag:"mtext",output:"mbox",ttype:TEXT};var AMsymbols=[{input:"\\alpha",tag:"mi",output:"\u03B1",ttype:CONST},{input:"\\beta",tag:"mi",output:"\u03B2",ttype:CONST},{input:"\\gamma",tag:"mi",output:"\u03B3",ttype:CONST},{input:"\\delta",tag:"mi",output:"\u03B4",ttype:CONST},{input:"\\epsilon",tag:"mi",output:"\u03B5",ttype:CONST},{input:"\\varepsilon",tag:"mi",output:"\u025B",ttype:CONST},{input:"\\zeta",tag:"mi",output:"\u03B6",ttype:CONST},{input:"\\eta",tag:"mi",output:"\u03B7",ttype:CONST},{input:"\\theta",tag:"mi",output:"\u03B8",ttype:CONST},{input:"\\vartheta",tag:"mi",output:"\u03D1",ttype:CONST},{input:"\\iota",tag:"mi",output:"\u03B9",ttype:CONST},{input:"\\kappa",tag:"mi",output:"\u03BA",ttype:CONST},{input:"\\lambda",tag:"mi",output:"\u03BB",ttype:CONST},{input:"\\mu",tag:"mi",output:"\u03BC",ttype:CONST},{input:"\\nu",tag:"mi",output:"\u03BD",ttype:CONST},{input:"\\xi",tag:"mi",output:"\u03BE",ttype:CONST},{input:"\\pi",tag:"mi",output:"\u03C0",ttype:CONST},{input:"\\varpi",tag:"mi",output:"\u03D6",ttype:CONST},{input:"\\rho",tag:"mi",output:"\u03C1",ttype:CONST},{input:"\\varrho",tag:"mi",output:"\u03F1",ttype:CONST},{input:"\\varsigma",tag:"mi",output:"\u03C2",ttype:CONST},{input:"\\sigma",tag:"mi",output:"\u03C3",ttype:CONST},{input:"\\tau",tag:"mi",output:"\u03C4",ttype:CONST},{input:"\\upsilon",tag:"mi",output:"\u03C5",ttype:CONST},{input:"\\phi",tag:"mi",output:"\u03C6",ttype:CONST},{input:"\\varphi",tag:"mi",output:"\u03D5",ttype:CONST},{input:"\\chi",tag:"mi",output:"\u03C7",ttype:CONST},{input:"\\psi",tag:"mi",output:"\u03C8",ttype:CONST},{input:"\\omega",tag:"mi",output:"\u03C9",ttype:CONST},{input:"\\Gamma",tag:"mo",output:"\u0393",ttype:CONST},{input:"\\Delta",tag:"mo",output:"\u0394",ttype:CONST},{input:"\\Theta",tag:"mo",output:"\u0398",ttype:CONST},{input:"\\Lambda",tag:"mo",output:"\u039B",ttype:CONST},{input:"\\Xi",tag:"mo",output:"\u039E",ttype:CONST},{input:"\\Pi",tag:"mo",output:"\u03A0",ttype:CONST},{input:"\\Sigma",tag:"mo",output:"\u03A3",ttype:CONST},{input:"\\Upsilon",tag:"mo",output:"\u03A5",ttype:CONST},{input:"\\Phi",tag:"mo",output:"\u03A6",ttype:CONST},{input:"\\Psi",tag:"mo",output:"\u03A8",ttype:CONST},{input:"\\Omega",tag:"mo",output:"\u03A9",ttype:CONST},{input:"\\frac12",tag:"mo",output:"\u00BD",ttype:CONST},{input:"\\frac14",tag:"mo",output:"\u00BC",ttype:CONST},{input:"\\frac34",tag:"mo",output:"\u00BE",ttype:CONST},{input:"\\frac13",tag:"mo",output:"\u2153",ttype:CONST},{input:"\\frac23",tag:"mo",output:"\u2154",ttype:CONST},{input:"\\frac15",tag:"mo",output:"\u2155",ttype:CONST},{input:"\\frac25",tag:"mo",output:"\u2156",ttype:CONST},{input:"\\frac35",tag:"mo",output:"\u2157",ttype:CONST},{input:"\\frac45",tag:"mo",output:"\u2158",ttype:CONST},{input:"\\frac16",tag:"mo",output:"\u2159",ttype:CONST},{input:"\\frac56",tag:"mo",output:"\u215A",ttype:CONST},{input:"\\frac18",tag:"mo",output:"\u215B",ttype:CONST},{input:"\\frac38",tag:"mo",output:"\u215C",ttype:CONST},{input:"\\frac58",tag:"mo",output:"\u215D",ttype:CONST},{input:"\\frac78",tag:"mo",output:"\u215E",ttype:CONST},{input:"\\pm",tag:"mo",output:"\u00B1",ttype:CONST},{input:"\\mp",tag:"mo",output:"\u2213",ttype:CONST},{input:"\\triangleleft",tag:"mo",output:"\u22B2",ttype:CONST},{input:"\\triangleright",tag:"mo",output:"\u22B3",ttype:CONST},{input:"\\cdot",tag:"mo",output:"\u22C5",ttype:CONST},{input:"\\star",tag:"mo",output:"\u22C6",ttype:CONST},{input:"\\ast",tag:"mo",output:"\u002A",ttype:CONST},{input:"\\times",tag:"mo",output:"\u00D7",ttype:CONST},{input:"\\div",tag:"mo",output:"\u00F7",ttype:CONST},{input:"\\circ",tag:"mo",output:"\u2218",ttype:CONST},{input:"\\bullet",tag:"mo",output:"\u2022",ttype:CONST},{input:"\\oplus",tag:"mo",output:"\u2295",ttype:CONST},{input:"\\ominus",tag:"mo",output:"\u2296",ttype:CONST},{input:"\\otimes",tag:"mo",output:"\u2297",ttype:CONST},{input:"\\bigcirc",tag:"mo",output:"\u25CB",ttype:CONST},{input:"\\oslash",tag:"mo",output:"\u2298",ttype:CONST},{input:"\\odot",tag:"mo",output:"\u2299",ttype:CONST},{input:"\\land",tag:"mo",output:"\u2227",ttype:CONST},{input:"\\wedge",tag:"mo",output:"\u2227",ttype:CONST},{input:"\\lor",tag:"mo",output:"\u2228",ttype:CONST},{input:"\\vee",tag:"mo",output:"\u2228",ttype:CONST},{input:"\\cap",tag:"mo",output:"\u2229",ttype:CONST},{input:"\\cup",tag:"mo",output:"\u222A",ttype:CONST},{input:"\\sqcap",tag:"mo",output:"\u2293",ttype:CONST},{input:"\\sqcup",tag:"mo",output:"\u2294",ttype:CONST},{input:"\\uplus",tag:"mo",output:"\u228E",ttype:CONST},{input:"\\amalg",tag:"mo",output:"\u2210",ttype:CONST},{input:"\\bigtriangleup",tag:"mo",output:"\u25B3",ttype:CONST},{input:"\\bigtriangledown",tag:"mo",output:"\u25BD",ttype:CONST},{input:"\\dag",tag:"mo",output:"\u2020",ttype:CONST},{input:"\\dagger",tag:"mo",output:"\u2020",ttype:CONST},{input:"\\ddag",tag:"mo",output:"\u2021",ttype:CONST},{input:"\\ddagger",tag:"mo",output:"\u2021",ttype:CONST},{input:"\\lhd",tag:"mo",output:"\u22B2",ttype:CONST},{input:"\\rhd",tag:"mo",output:"\u22B3",ttype:CONST},{input:"\\unlhd",tag:"mo",output:"\u22B4",ttype:CONST},{input:"\\unrhd",tag:"mo",output:"\u22B5",ttype:CONST},{input:"\\sum",tag:"mo",output:"\u2211",ttype:UNDEROVER},{input:"\\prod",tag:"mo",output:"\u220F",ttype:UNDEROVER},{input:"\\bigcap",tag:"mo",output:"\u22C2",ttype:UNDEROVER},{input:"\\bigcup",tag:"mo",output:"\u22C3",ttype:UNDEROVER},{input:"\\bigwedge",tag:"mo",output:"\u22C0",ttype:UNDEROVER},{input:"\\bigvee",tag:"mo",output:"\u22C1",ttype:UNDEROVER},{input:"\\bigsqcap",tag:"mo",output:"\u2A05",ttype:UNDEROVER},{input:"\\bigsqcup",tag:"mo",output:"\u2A06",ttype:UNDEROVER},{input:"\\coprod",tag:"mo",output:"\u2210",ttype:UNDEROVER},{input:"\\bigoplus",tag:"mo",output:"\u2A01",ttype:UNDEROVER},{input:"\\bigotimes",tag:"mo",output:"\u2A02",ttype:UNDEROVER},{input:"\\bigodot",tag:"mo",output:"\u2A00",ttype:UNDEROVER},{input:"\\biguplus",tag:"mo",output:"\u2A04",ttype:UNDEROVER},{input:"\\int",tag:"mo",output:"\u222B",ttype:CONST},{input:"\\oint",tag:"mo",output:"\u222E",ttype:CONST},{input:":=",tag:"mo",output:":=",ttype:CONST},{input:"\\lt",tag:"mo",output:"<",ttype:CONST},{input:"\\gt",tag:"mo",output:">",ttype:CONST},{input:"\\ne",tag:"mo",output:"\u2260",ttype:CONST},{input:"\\neq",tag:"mo",output:"\u2260",ttype:CONST},{input:"\\le",tag:"mo",output:"\u2264",ttype:CONST},{input:"\\leq",tag:"mo",output:"\u2264",ttype:CONST},{input:"\\leqslant",tag:"mo",output:"\u2264",ttype:CONST},{input:"\\ge",tag:"mo",output:"\u2265",ttype:CONST},{input:"\\geq",tag:"mo",output:"\u2265",ttype:CONST},{input:"\\geqslant",tag:"mo",output:"\u2265",ttype:CONST},{input:"\\equiv",tag:"mo",output:"\u2261",ttype:CONST},{input:"\\ll",tag:"mo",output:"\u226A",ttype:CONST},{input:"\\gg",tag:"mo",output:"\u226B",ttype:CONST},{input:"\\doteq",tag:"mo",output:"\u2250",ttype:CONST},{input:"\\prec",tag:"mo",output:"\u227A",ttype:CONST},{input:"\\succ",tag:"mo",output:"\u227B",ttype:CONST},{input:"\\preceq",tag:"mo",output:"\u227C",ttype:CONST},{input:"\\succeq",tag:"mo",output:"\u227D",ttype:CONST},{input:"\\subset",tag:"mo",output:"\u2282",ttype:CONST},{input:"\\supset",tag:"mo",output:"\u2283",ttype:CONST},{input:"\\subseteq",tag:"mo",output:"\u2286",ttype:CONST},{input:"\\supseteq",tag:"mo",output:"\u2287",ttype:CONST},{input:"\\sqsubset",tag:"mo",output:"\u228F",ttype:CONST},{input:"\\sqsupset",tag:"mo",output:"\u2290",ttype:CONST},{input:"\\sqsubseteq",tag:"mo",output:"\u2291",ttype:CONST},{input:"\\sqsupseteq",tag:"mo",output:"\u2292",ttype:CONST},{input:"\\sim",tag:"mo",output:"\u223C",ttype:CONST},{input:"\\simeq",tag:"mo",output:"\u2243",ttype:CONST},{input:"\\approx",tag:"mo",output:"\u2248",ttype:CONST},{input:"\\cong",tag:"mo",output:"\u2245",ttype:CONST},{input:"\\Join",tag:"mo",output:"\u22C8",ttype:CONST},{input:"\\bowtie",tag:"mo",output:"\u22C8",ttype:CONST},{input:"\\in",tag:"mo",output:"\u2208",ttype:CONST},{input:"\\ni",tag:"mo",output:"\u220B",ttype:CONST},{input:"\\owns",tag:"mo",output:"\u220B",ttype:CONST},{input:"\\propto",tag:"mo",output:"\u221D",ttype:CONST},{input:"\\vdash",tag:"mo",output:"\u22A2",ttype:CONST},{input:"\\dashv",tag:"mo",output:"\u22A3",ttype:CONST},{input:"\\models",tag:"mo",output:"\u22A8",ttype:CONST},{input:"\\perp",tag:"mo",output:"\u22A5",ttype:CONST},{input:"\\smile",tag:"mo",output:"\u2323",ttype:CONST},{input:"\\frown",tag:"mo",output:"\u2322",ttype:CONST},{input:"\\asymp",tag:"mo",output:"\u224D",ttype:CONST},{input:"\\notin",tag:"mo",output:"\u2209",ttype:CONST},{input:"\\begin{eqnarray}",output:"X",ttype:MATRIX,invisible:true},{input:"\\begin{array}",output:"X",ttype:MATRIX,invisible:true},{input:"\\\\",output:"}&{",ttype:DEFINITION},{input:"\\end{eqnarray}",output:"}}",ttype:DEFINITION},{input:"\\end{array}",output:"}}",ttype:DEFINITION},{input:"\\big",tag:"mo",output:"X",atval:"1.2",ieval:"2.2",ttype:BIG},{input:"\\Big",tag:"mo",output:"X",atval:"1.6",ieval:"2.6",ttype:BIG},{input:"\\bigg",tag:"mo",output:"X",atval:"2.2",ieval:"3.2",ttype:BIG},{input:"\\Bigg",tag:"mo",output:"X",atval:"2.9",ieval:"3.9",ttype:BIG},{input:"\\left",tag:"mo",output:"X",ttype:LEFTBRACKET},{input:"\\right",tag:"mo",output:"X",ttype:RIGHTBRACKET},{input:"{",output:"{",ttype:LEFTBRACKET,invisible:true},{input:"}",output:"}",ttype:RIGHTBRACKET,invisible:true},{input:"(",tag:"mo",output:"(",atval:"1",ttype:STRETCHY},{input:"[",tag:"mo",output:"[",atval:"1",ttype:STRETCHY},{input:"\\lbrack",tag:"mo",output:"[",atval:"1",ttype:STRETCHY},{input:"\\{",tag:"mo",output:"{",atval:"1",ttype:STRETCHY},{input:"\\lbrace",tag:"mo",output:"{",atval:"1",ttype:STRETCHY},{input:"\\langle",tag:"mo",output:"\u2329",atval:"1",ttype:STRETCHY},{input:"\\lfloor",tag:"mo",output:"\u230A",atval:"1",ttype:STRETCHY},{input:"\\lceil",tag:"mo",output:"\u2308",atval:"1",ttype:STRETCHY},{input:")",tag:"mo",output:")",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"]",tag:"mo",output:"]",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\rbrack",tag:"mo",output:"]",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\}",tag:"mo",output:"}",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\rbrace",tag:"mo",output:"}",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\rangle",tag:"mo",output:"\u232A",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\rfloor",tag:"mo",output:"\u230B",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\rceil",tag:"mo",output:"\u2309",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"|",tag:"mo",output:"\u2223",atval:"1",ttype:STRETCHY},{input:"\\|",tag:"mo",output:"\u2225",atval:"1",ttype:STRETCHY},{input:"\\vert",tag:"mo",output:"\u2223",atval:"1",ttype:STRETCHY},{input:"\\Vert",tag:"mo",output:"\u2225",atval:"1",ttype:STRETCHY},{input:"\\mid",tag:"mo",output:"\u2223",atval:"1",ttype:STRETCHY},{input:"\\parallel",tag:"mo",output:"\u2225",atval:"1",ttype:STRETCHY},{input:"/",tag:"mo",output:"/",atval:"1.01",ttype:STRETCHY},{input:"\\backslash",tag:"mo",output:"\u2216",atval:"1",ttype:STRETCHY},{input:"\\setminus",tag:"mo",output:"\\",ttype:CONST},{input:"\\!",tag:"mspace",atname:"width",atval:"-0.167em",ttype:SPACE},{input:"\\,",tag:"mspace",atname:"width",atval:"0.167em",ttype:SPACE},{input:"\\>",tag:"mspace",atname:"width",atval:"0.222em",ttype:SPACE},{input:"\\:",tag:"mspace",atname:"width",atval:"0.222em",ttype:SPACE},{input:"\\;",tag:"mspace",atname:"width",atval:"0.278em",ttype:SPACE},{input:"~",tag:"mspace",atname:"width",atval:"0.333em",ttype:SPACE},{input:"\\quad",tag:"mspace",atname:"width",atval:"1em",ttype:SPACE},{input:"\\qquad",tag:"mspace",atname:"width",atval:"2em",ttype:SPACE},{input:"\\prime",tag:"mo",output:"\u2032",ttype:CONST},{input:"'",tag:"mo",output:"\u02B9",ttype:CONST},{input:"''",tag:"mo",output:"\u02BA",ttype:CONST},{input:"'''",tag:"mo",output:"\u2034",ttype:CONST},{input:"''''",tag:"mo",output:"\u2057",ttype:CONST},{input:"\\ldots",tag:"mo",output:"\u2026",ttype:CONST},{input:"\\cdots",tag:"mo",output:"\u22EF",ttype:CONST},{input:"\\vdots",tag:"mo",output:"\u22EE",ttype:CONST},{input:"\\ddots",tag:"mo",output:"\u22F1",ttype:CONST},{input:"\\forall",tag:"mo",output:"\u2200",ttype:CONST},{input:"\\exists",tag:"mo",output:"\u2203",ttype:CONST},{input:"\\Re",tag:"mo",output:"\u211C",ttype:CONST},{input:"\\Im",tag:"mo",output:"\u2111",ttype:CONST},{input:"\\aleph",tag:"mo",output:"\u2135",ttype:CONST},{input:"\\hbar",tag:"mo",output:"\u210F",ttype:CONST},{input:"\\ell",tag:"mo",output:"\u2113",ttype:CONST},{input:"\\wp",tag:"mo",output:"\u2118",ttype:CONST},{input:"\\emptyset",tag:"mo",output:"\u2205",ttype:CONST},{input:"\\infty",tag:"mo",output:"\u221E",ttype:CONST},{input:"\\surd",tag:"mo",output:"\\sqrt{}",ttype:DEFINITION},{input:"\\partial",tag:"mo",output:"\u2202",ttype:CONST},{input:"\\nabla",tag:"mo",output:"\u2207",ttype:CONST},{input:"\\triangle",tag:"mo",output:"\u25B3",ttype:CONST},{input:"\\therefore",tag:"mo",output:"\u2234",ttype:CONST},{input:"\\angle",tag:"mo",output:"\u2220",ttype:CONST},{input:"\\diamond",tag:"mo",output:"\u22C4",ttype:CONST},{input:"\\Diamond",tag:"mo",output:"\u25C7",ttype:CONST},{input:"\\neg",tag:"mo",output:"\u00AC",ttype:CONST},{input:"\\lnot",tag:"mo",output:"\u00AC",ttype:CONST},{input:"\\bot",tag:"mo",output:"\u22A5",ttype:CONST},{input:"\\top",tag:"mo",output:"\u22A4",ttype:CONST},{input:"\\square",tag:"mo",output:"\u25AB",ttype:CONST},{input:"\\Box",tag:"mo",output:"\u25A1",ttype:CONST},{input:"\\wr",tag:"mo",output:"\u2240",ttype:CONST},{input:"\\arccos",tag:"mi",output:"arccos",ttype:UNARY,func:true},{input:"\\arcsin",tag:"mi",output:"arcsin",ttype:UNARY,func:true},{input:"\\arctan",tag:"mi",output:"arctan",ttype:UNARY,func:true},{input:"\\arg",tag:"mi",output:"arg",ttype:UNARY,func:true},{input:"\\cos",tag:"mi",output:"cos",ttype:UNARY,func:true},{input:"\\cosh",tag:"mi",output:"cosh",ttype:UNARY,func:true},{input:"\\cot",tag:"mi",output:"cot",ttype:UNARY,func:true},{input:"\\coth",tag:"mi",output:"coth",ttype:UNARY,func:true},{input:"\\csc",tag:"mi",output:"csc",ttype:UNARY,func:true},{input:"\\deg",tag:"mi",output:"deg",ttype:UNARY,func:true},{input:"\\det",tag:"mi",output:"det",ttype:UNARY,func:true},{input:"\\dim",tag:"mi",output:"dim",ttype:UNARY,func:true},{input:"\\exp",tag:"mi",output:"exp",ttype:UNARY,func:true},{input:"\\gcd",tag:"mi",output:"gcd",ttype:UNARY,func:true},{input:"\\hom",tag:"mi",output:"hom",ttype:UNARY,func:true},{input:"\\inf",tag:"mo",output:"inf",ttype:UNDEROVER},{input:"\\ker",tag:"mi",output:"ker",ttype:UNARY,func:true},{input:"\\lg",tag:"mi",output:"lg",ttype:UNARY,func:true},{input:"\\lim",tag:"mo",output:"lim",ttype:UNDEROVER},{input:"\\liminf",tag:"mo",output:"liminf",ttype:UNDEROVER},{input:"\\limsup",tag:"mo",output:"limsup",ttype:UNDEROVER},{input:"\\ln",tag:"mi",output:"ln",ttype:UNARY,func:true},{input:"\\log",tag:"mi",output:"log",ttype:UNARY,func:true},{input:"\\max",tag:"mo",output:"max",ttype:UNDEROVER},{input:"\\min",tag:"mo",output:"min",ttype:UNDEROVER},{input:"\\Pr",tag:"mi",output:"Pr",ttype:UNARY,func:true},{input:"\\sec",tag:"mi",output:"sec",ttype:UNARY,func:true},{input:"\\sin",tag:"mi",output:"sin",ttype:UNARY,func:true},{input:"\\sinh",tag:"mi",output:"sinh",ttype:UNARY,func:true},{input:"\\sup",tag:"mo",output:"sup",ttype:UNDEROVER},{input:"\\tan",tag:"mi",output:"tan",ttype:UNARY,func:true},{input:"\\tanh",tag:"mi",output:"tanh",ttype:UNARY,func:true},{input:"\\gets",tag:"mo",output:"\u2190",ttype:CONST},{input:"\\leftarrow",tag:"mo",output:"\u2190",ttype:CONST},{input:"\\to",tag:"mo",output:"\u2192",ttype:CONST},{input:"\\rightarrow",tag:"mo",output:"\u2192",ttype:CONST},{input:"\\leftrightarrow",tag:"mo",output:"\u2194",ttype:CONST},{input:"\\uparrow",tag:"mo",output:"\u2191",ttype:CONST},{input:"\\downarrow",tag:"mo",output:"\u2193",ttype:CONST},{input:"\\updownarrow",tag:"mo",output:"\u2195",ttype:CONST},{input:"\\Leftarrow",tag:"mo",output:"\u21D0",ttype:CONST},{input:"\\Rightarrow",tag:"mo",output:"\u21D2",ttype:CONST},{input:"\\Leftrightarrow",tag:"mo",output:"\u21D4",ttype:CONST},{input:"\\iff",tag:"mo",output:"~\\Longleftrightarrow~",ttype:DEFINITION},{input:"\\Uparrow",tag:"mo",output:"\u21D1",ttype:CONST},{input:"\\Downarrow",tag:"mo",output:"\u21D3",ttype:CONST},{input:"\\Updownarrow",tag:"mo",output:"\u21D5",ttype:CONST},{input:"\\mapsto",tag:"mo",output:"\u21A6",ttype:CONST},{input:"\\longleftarrow",tag:"mo",output:"\u2190",ttype:LONG},{input:"\\longrightarrow",tag:"mo",output:"\u2192",ttype:LONG},{input:"\\longleftrightarrow",tag:"mo",output:"\u2194",ttype:LONG},{input:"\\Longleftarrow",tag:"mo",output:"\u21D0",ttype:LONG},{input:"\\Longrightarrow",tag:"mo",output:"\u21D2",ttype:LONG},{input:"\\Longleftrightarrow",tag:"mo",output:"\u21D4",ttype:LONG},{input:"\\longmapsto",tag:"mo",output:"\u21A6",ttype:CONST},AMsqrt,AMroot,AMfrac,AMover,AMsub,AMsup,AMtext,AMmbox,AMatop,AMchoose,{input:"\\acute",tag:"mover",output:"\u00B4",ttype:UNARY,acc:true},{input:"\\grave",tag:"mover",output:"\u0060",ttype:UNARY,acc:true},{input:"\\breve",tag:"mover",output:"\u02D8",ttype:UNARY,acc:true},{input:"\\check",tag:"mover",output:"\u02C7",ttype:UNARY,acc:true},{input:"\\dot",tag:"mover",output:".",ttype:UNARY,acc:true},{input:"\\ddot",tag:"mover",output:"..",ttype:UNARY,acc:true},{input:"\\mathring",tag:"mover",output:"\u00B0",ttype:UNARY,acc:true},{input:"\\vec",tag:"mover",output:"\u20D7",ttype:UNARY,acc:true},{input:"\\overrightarrow",tag:"mover",output:"\u20D7",ttype:UNARY,acc:true},{input:"\\overleftarrow",tag:"mover",output:"\u20D6",ttype:UNARY,acc:true},{input:"\\hat",tag:"mover",output:"\u005E",ttype:UNARY,acc:true},{input:"\\widehat",tag:"mover",output:"\u0302",ttype:UNARY,acc:true},{input:"\\tilde",tag:"mover",output:"~",ttype:UNARY,acc:true},{input:"\\widetilde",tag:"mover",output:"\u02DC",ttype:UNARY,acc:true},{input:"\\bar",tag:"mover",output:"\u203E",ttype:UNARY,acc:true},{input:"\\overbrace",tag:"mover",output:"\uFE37",ttype:UNARY,acc:true},{input:"\\overbracket",tag:"mover",output:"\u23B4",ttype:UNARY,acc:true},{input:"\\overline",tag:"mover",output:"\u00AF",ttype:UNARY,acc:true},{input:"\\underbrace",tag:"munder",output:"\uFE38",ttype:UNARY,acc:true},{input:"\\underbracket",tag:"munder",output:"\u23B5",ttype:UNARY,acc:true},{input:"\\underline",tag:"munder",output:"\u00AF",ttype:UNARY,acc:true},{input:"\\displaystyle",tag:"mstyle",atname:"displaystyle",atval:"true",ttype:UNARY},{input:"\\textstyle",tag:"mstyle",atname:"displaystyle",atval:"false",ttype:UNARY},{input:"\\scriptstyle",tag:"mstyle",atname:"scriptlevel",atval:"1",ttype:UNARY},{input:"\\scriptscriptstyle",tag:"mstyle",atname:"scriptlevel",atval:"2",ttype:UNARY},{input:"\\textrm",tag:"mstyle",output:"\\mathrm",ttype:DEFINITION},{input:"\\mathbf",tag:"mstyle",atname:"mathvariant",atval:"bold",ttype:UNARY},{input:"\\textbf",tag:"mstyle",atname:"mathvariant",atval:"bold",ttype:UNARY},{input:"\\mathit",tag:"mstyle",atname:"mathvariant",atval:"italic",ttype:UNARY},{input:"\\textit",tag:"mstyle",atname:"mathvariant",atval:"italic",ttype:UNARY},{input:"\\mathtt",tag:"mstyle",atname:"mathvariant",atval:"monospace",ttype:UNARY},{input:"\\texttt",tag:"mstyle",atname:"mathvariant",atval:"monospace",ttype:UNARY},{input:"\\mathsf",tag:"mstyle",atname:"mathvariant",atval:"sans-serif",ttype:UNARY},{input:"\\mathbb",tag:"mstyle",atname:"mathvariant",atval:"double-struck",ttype:UNARY,codes:AMbbb},{input:"\\mathcal",tag:"mstyle",atname:"mathvariant",atval:"script",ttype:UNARY,codes:AMcal},{input:"\\mathfrak",tag:"mstyle",atname:"mathvariant",atval:"fraktur",ttype:UNARY,codes:AMfrk},{input:"\\textcolor",tag:"mstyle",atname:"mathvariant",atval:"mathcolor",ttype:BINARY},{input:"\\colorbox",tag:"mstyle",atname:"mathvariant",atval:"background",ttype:BINARY}];function compareNames(s1,s2){if(s1.input>s2.input)return 1+else return-1;}+var AMnames=[];function AMinitSymbols(){AMsymbols.sort(compareNames);for(i=0;i<AMsymbols.length;i++)AMnames[i]=AMsymbols[i].input;}+var AMmathml="http://www.w3.org/1998/Math/MathML";function AMcreateElementMathML(t){if(isIE)return document.createElement("m:"+t);else return document.createElementNS(AMmathml,t);}+function AMcreateMmlNode(t,frag){if(isIE)var node=document.createElement("m:"+t);else var node=document.createElementNS(AMmathml,t);node.appendChild(frag);return node;}+function newcommand(oldstr,newstr){AMsymbols=AMsymbols.concat([{input:oldstr,tag:"mo",output:newstr,ttype:DEFINITION}]);}+function AMremoveCharsAndBlanks(str,n){var st;st=str.slice(n);for(var i=0;i<st.length&&st.charCodeAt(i)<=32;i=i+1);return st.slice(i);}+function AMposition(arr,str,n){if(n==0){var h,m;n=-1;h=arr.length;while(n+1<h){m=(n+h)>>1;if(arr[m]<str)n=m;else h=m;}+return h;}else+for(var i=n;i<arr.length&&arr[i]<str;i++);return i;}+function AMgetSymbol(str){var k=0;var j=0;var mk;var st;var tagst;var match="";var more=true;for(var i=1;i<=str.length&&more;i++){st=str.slice(0,i);j=k;k=AMposition(AMnames,st,j);if(k<AMnames.length&&str.slice(0,AMnames[k].length)==AMnames[k]){match=AMnames[k];mk=k;i=match.length;}+more=k<AMnames.length&&str.slice(0,AMnames[k].length)>=AMnames[k];}+AMpreviousSymbol=AMcurrentSymbol;if(match!=""){AMcurrentSymbol=AMsymbols[mk].ttype;return AMsymbols[mk];}+AMcurrentSymbol=CONST;k=1;st=str.slice(0,1);if("0"<=st&&st<="9")tagst="mn";else tagst=(("A">st||st>"Z")&&("a">st||st>"z")?"mo":"mi");return{input:st,tag:tagst,output:st,ttype:CONST};}+var AMpreviousSymbol,AMcurrentSymbol;function AMparseSexpr(str){var symbol,node,result,result2,i,st,newFrag=document.createDocumentFragment();str=AMremoveCharsAndBlanks(str,0);symbol=AMgetSymbol(str);if(symbol==null||symbol.ttype==RIGHTBRACKET)+return[null,str,null];if(symbol.ttype==DEFINITION){str=symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length);symbol=AMgetSymbol(str);if(symbol==null||symbol.ttype==RIGHTBRACKET)+return[null,str,null];}+str=AMremoveCharsAndBlanks(str,symbol.input.length);switch(symbol.ttype){case SPACE:node=AMcreateElementMathML(symbol.tag);node.setAttribute(symbol.atname,symbol.atval);return[node,str,symbol.tag];case UNDEROVER:if(isIE){if(symbol.input.substr(0,4)=="\\big"){str="\\"+symbol.input.substr(4)+str;symbol=AMgetSymbol(str);symbol.ttype=UNDEROVER;str=AMremoveCharsAndBlanks(str,symbol.input.length);}}+return[AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str,symbol.tag];case CONST:var output=symbol.output;if(isIE){if(symbol.input=="'")+output="\u2032";else if(symbol.input=="''")+output="\u2033";else if(symbol.input=="'''")+output="\u2033\u2032";else if(symbol.input=="''''")+output="\u2033\u2033";else if(symbol.input=="\\square")+output="\u25A1";else if(symbol.input.substr(0,5)=="\\frac"){var denom=symbol.input.substr(6,1);if(denom=="5"||denom=="6"){str=symbol.input.replace(/\\frac/,"\\frac ")+str;return[node,str,symbol.tag];}}}+node=AMcreateMmlNode(symbol.tag,document.createTextNode(output));return[node,str,symbol.tag];case LONG:node=AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output));node.setAttribute("minsize","1.5");node.setAttribute("maxsize","1.5");node=AMcreateMmlNode("mover",node);node.appendChild(AMcreateElementMathML("mspace"));return[node,str,symbol.tag];case STRETCHY:if(isIE&&symbol.input=="\\backslash")+symbol.output="\\";node=AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output));if(symbol.input=="|"||symbol.input=="\\vert"||symbol.input=="\\|"||symbol.input=="\\Vert"){node.setAttribute("lspace","0em");node.setAttribute("rspace","0em");}+node.setAttribute("maxsize",symbol.atval);if(symbol.rtag!=null)+return[node,str,symbol.rtag];else+return[node,str,symbol.tag];case BIG:var atval=symbol.atval;if(isIE)+atval=symbol.ieval;symbol=AMgetSymbol(str);if(symbol==null)+return[null,str,null];str=AMremoveCharsAndBlanks(str,symbol.input.length);node=AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output));if(isIE){var space=AMcreateElementMathML("mspace");space.setAttribute("height",atval+"ex");node=AMcreateMmlNode("mrow",node);node.appendChild(space);}else{node.setAttribute("minsize",atval);node.setAttribute("maxsize",atval);}+return[node,str,symbol.tag];case LEFTBRACKET:if(symbol.input=="\\left"){symbol=AMgetSymbol(str);if(symbol!=null){if(symbol.input==".")+symbol.invisible=true;str=AMremoveCharsAndBlanks(str,symbol.input.length);}}+result=AMparseExpr(str,true,false);if(symbol==null||(typeof symbol.invisible=="boolean"&&symbol.invisible))+node=AMcreateMmlNode("mrow",result[0]);else{node=AMcreateMmlNode("mo",document.createTextNode(symbol.output));node=AMcreateMmlNode("mrow",node);node.appendChild(result[0]);}+return[node,result[1],result[2]];case MATRIX:if(symbol.input=="\\begin{array}"){var mask="";symbol=AMgetSymbol(str);str=AMremoveCharsAndBlanks(str,0);if(symbol==null)+mask="l";else{str=AMremoveCharsAndBlanks(str,symbol.input.length);if(symbol.input!="{")+mask="l";else do{symbol=AMgetSymbol(str);if(symbol!=null){str=AMremoveCharsAndBlanks(str,symbol.input.length);if(symbol.input!="}")+mask=mask+symbol.input;}}while(symbol!=null&&symbol.input!=""&&symbol.input!="}");}+result=AMparseExpr("{"+str,true,true);node=AMcreateMmlNode("mtable",result[0]);mask=mask.replace(/l/g,"left ");mask=mask.replace(/r/g,"right ");mask=mask.replace(/c/g,"center ");node.setAttribute("columnalign",mask);node.setAttribute("displaystyle","false");if(isIE)+return[node,result[1],null];var lspace=AMcreateElementMathML("mspace");lspace.setAttribute("width","0.167em");var rspace=AMcreateElementMathML("mspace");rspace.setAttribute("width","0.167em");var node1=AMcreateMmlNode("mrow",lspace);node1.appendChild(node);node1.appendChild(rspace);return[node1,result[1],null];}else{result=AMparseExpr("{"+str,true,true);node=AMcreateMmlNode("mtable",result[0]);if(isIE)+node.setAttribute("columnspacing","0.25em");else+node.setAttribute("columnspacing","0.167em");node.setAttribute("columnalign","right center left");node.setAttribute("displaystyle","true");node=AMcreateMmlNode("mrow",node);return[node,result[1],null];}+case TEXT:if(str.charAt(0)=="{")i=str.indexOf("}");else i=0;if(i==-1)+i=str.length;st=str.slice(1,i);if(st.charAt(0)==" "){node=AMcreateElementMathML("mspace");node.setAttribute("width","0.33em");newFrag.appendChild(node);}+newFrag.appendChild(AMcreateMmlNode(symbol.tag,document.createTextNode(st)));if(st.charAt(st.length-1)==" "){node=AMcreateElementMathML("mspace");node.setAttribute("width","0.33em");newFrag.appendChild(node);}+str=AMremoveCharsAndBlanks(str,i+1);return[AMcreateMmlNode("mrow",newFrag),str,null];case UNARY:result=AMparseSexpr(str);if(result[0]==null)return[AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str];if(typeof symbol.func=="boolean"&&symbol.func){st=str.charAt(0);if(st=="^"||st=="_"||st==","){return[AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str,symbol.tag];}else{node=AMcreateMmlNode("mrow",AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));if(isIE){var space=AMcreateElementMathML("mspace");space.setAttribute("width","0.167em");node.appendChild(space);}+node.appendChild(result[0]);return[node,result[1],symbol.tag];}}+if(symbol.input=="\\sqrt"){if(isIE){var space=AMcreateElementMathML("mspace");space.setAttribute("height","1.2ex");space.setAttribute("width","0em");node=AMcreateMmlNode(symbol.tag,result[0])+node.appendChild(space);return[node,result[1],symbol.tag];}else+return[AMcreateMmlNode(symbol.tag,result[0]),result[1],symbol.tag];}else if(typeof symbol.acc=="boolean"&&symbol.acc){node=AMcreateMmlNode(symbol.tag,result[0]);var output=symbol.output;if(isIE){if(symbol.input=="\\hat")+output="\u0302";else if(symbol.input=="\\widehat")+output="\u005E";else if(symbol.input=="\\bar")+output="\u00AF";else if(symbol.input=="\\grave")+output="\u0300";else if(symbol.input=="\\tilde")+output="\u0303";}+var node1=AMcreateMmlNode("mo",document.createTextNode(output));if(symbol.input=="\\vec"||symbol.input=="\\check")+node1.setAttribute("maxsize","1.2");if(isIE&&symbol.input=="\\bar")+node1.setAttribute("maxsize","0.5");if(symbol.input=="\\underbrace"||symbol.input=="\\underline")+node1.setAttribute("accentunder","true");else+node1.setAttribute("accent","true");node.appendChild(node1);if(symbol.input=="\\overbrace"||symbol.input=="\\underbrace")+node.ttype=UNDEROVER;return[node,result[1],symbol.tag];}else{if(!isIE&&typeof symbol.codes!="undefined"){for(i=0;i<result[0].childNodes.length;i++)+if(result[0].childNodes[i].nodeName=="mi"||result[0].nodeName=="mi"){st=(result[0].nodeName=="mi"?result[0].firstChild.nodeValue:result[0].childNodes[i].firstChild.nodeValue);var newst=[];for(var j=0;j<st.length;j++)+if(st.charCodeAt(j)>64&&st.charCodeAt(j)<91)newst=newst++String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]);else newst=newst+st.charAt(j);if(result[0].nodeName=="mi")+result[0]=AMcreateElementMathML("mo").appendChild(document.createTextNode(newst));else result[0].replaceChild(AMcreateElementMathML("mo").appendChild(document.createTextNode(newst)),result[0].childNodes[i]);}}+node=AMcreateMmlNode(symbol.tag,result[0]);node.setAttribute(symbol.atname,symbol.atval);if(symbol.input=="\\scriptstyle"||symbol.input=="\\scriptscriptstyle")+node.setAttribute("displaystyle","false");return[node,result[1],symbol.tag];}+case BINARY:result=AMparseSexpr(str);if(result[0]==null)return[AMcreateMmlNode("mo",document.createTextNode(symbol.input)),str,null];result2=AMparseSexpr(result[1]);if(result2[0]==null)return[AMcreateMmlNode("mo",document.createTextNode(symbol.input)),str,null];if(symbol.input=="\\textcolor"||symbol.input=="\\colorbox"){var tclr=str.match(/\{\s*([#\w]+)\s*\}/);str=str.replace(/\{\s*[#\w]+\s*\}/,"");if(tclr!=null){if(IsColorName.test(tclr[1].toLowerCase())){tclr=LaTeXColor[tclr[1].toLowerCase()];}else{tclr=tclr[1];}+node=AMcreateElementMathML("mstyle");node.setAttribute(symbol.atval,tclr);node.appendChild(result2[0]);return[node,result2[1],symbol.tag];}}+if(symbol.input=="\\root"||symbol.input=="\\stackrel")newFrag.appendChild(result2[0]);newFrag.appendChild(result[0]);if(symbol.input=="\\frac")newFrag.appendChild(result2[0]);return[AMcreateMmlNode(symbol.tag,newFrag),result2[1],symbol.tag];case INFIX:str=AMremoveCharsAndBlanks(str,symbol.input.length);return[AMcreateMmlNode("mo",document.createTextNode(symbol.output)),str,symbol.tag];default:return[AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str,symbol.tag];}}+function AMparseIexpr(str){var symbol,sym1,sym2,node,result,tag,underover;str=AMremoveCharsAndBlanks(str,0);sym1=AMgetSymbol(str);result=AMparseSexpr(str);node=result[0];str=result[1];tag=result[2];symbol=AMgetSymbol(str);if(symbol.ttype==INFIX){str=AMremoveCharsAndBlanks(str,symbol.input.length);result=AMparseSexpr(str);if(result[0]==null)+result[0]=AMcreateMmlNode("mo",document.createTextNode("\u25A1"));str=result[1];tag=result[2];if(symbol.input=="_"||symbol.input=="^"){sym2=AMgetSymbol(str);tag=null;underover=((sym1.ttype==UNDEROVER)||(node.ttype==UNDEROVER));if(symbol.input=="_"&&sym2.input=="^"){str=AMremoveCharsAndBlanks(str,sym2.input.length);var res2=AMparseSexpr(str);str=res2[1];tag=res2[2];node=AMcreateMmlNode((underover?"munderover":"msubsup"),node);node.appendChild(result[0]);node.appendChild(res2[0]);}else if(symbol.input=="_"){node=AMcreateMmlNode((underover?"munder":"msub"),node);node.appendChild(result[0]);}else{node=AMcreateMmlNode((underover?"mover":"msup"),node);node.appendChild(result[0]);}+node=AMcreateMmlNode("mrow",node);}else{node=AMcreateMmlNode(symbol.tag,node);if(symbol.input=="\\atop"||symbol.input=="\\choose")+node.setAttribute("linethickness","0ex");node.appendChild(result[0]);if(symbol.input=="\\choose")+node=AMcreateMmlNode("mfenced",node);}}+return[node,str,tag];}+function AMparseExpr(str,rightbracket,matrix){var symbol,node,result,i,tag,newFrag=document.createDocumentFragment();do{str=AMremoveCharsAndBlanks(str,0);result=AMparseIexpr(str);node=result[0];str=result[1];tag=result[2];symbol=AMgetSymbol(str);if(node!=undefined){if((tag=="mn"||tag=="mi")&&symbol!=null&&typeof symbol.func=="boolean"&&symbol.func){var space=AMcreateElementMathML("mspace");space.setAttribute("width","0.167em");node=AMcreateMmlNode("mrow",node);node.appendChild(space);}+newFrag.appendChild(node);}}while((symbol.ttype!=RIGHTBRACKET)&&symbol!=null&&symbol.output!="");tag=null;if(symbol.ttype==RIGHTBRACKET){if(symbol.input=="\\right"){str=AMremoveCharsAndBlanks(str,symbol.input.length);symbol=AMgetSymbol(str);if(symbol!=null&&symbol.input==".")+symbol.invisible=true;if(symbol!=null)+tag=symbol.rtag;}+if(symbol!=null)+str=AMremoveCharsAndBlanks(str,symbol.input.length);var len=newFrag.childNodes.length;if(matrix&&len>0&&newFrag.childNodes[len-1].nodeName=="mrow"&&len>1&&newFrag.childNodes[len-2].nodeName=="mo"&&newFrag.childNodes[len-2].firstChild.nodeValue=="&"){var pos=[];var m=newFrag.childNodes.length;for(i=0;matrix&&i<m;i=i+2){pos[i]=[];node=newFrag.childNodes[i];for(var j=0;j<node.childNodes.length;j++)+if(node.childNodes[j].firstChild.nodeValue=="&")+pos[i][pos[i].length]=j;}+var row,frag,n,k,table=document.createDocumentFragment();for(i=0;i<m;i=i+2){row=document.createDocumentFragment();frag=document.createDocumentFragment();node=newFrag.firstChild;n=node.childNodes.length;k=0;for(j=0;j<n;j++){if(typeof pos[i][k]!="undefined"&&j==pos[i][k]){node.removeChild(node.firstChild);row.appendChild(AMcreateMmlNode("mtd",frag));k++;}else frag.appendChild(node.firstChild);}+row.appendChild(AMcreateMmlNode("mtd",frag));if(newFrag.childNodes.length>2){newFrag.removeChild(newFrag.firstChild);newFrag.removeChild(newFrag.firstChild);}+table.appendChild(AMcreateMmlNode("mtr",row));}+return[table,str];}+if(typeof symbol.invisible!="boolean"||!symbol.invisible){node=AMcreateMmlNode("mo",document.createTextNode(symbol.output));newFrag.appendChild(node);}}+return[newFrag,str,tag];}+function AMparseMath(str){var result,node=AMcreateElementMathML("mstyle");var cclr=str.match(/\\color\s*\{\s*([#\w]+)\s*\}/);str=str.replace(/\\color\s*\{\s*[#\w]+\s*\}/g,"");if(cclr!=null){if(IsColorName.test(cclr[1].toLowerCase())){cclr=LaTeXColor[cclr[1].toLowerCase()];}else{cclr=cclr[1];}+node.setAttribute("mathcolor",cclr);}else{if(mathcolor!="")node.setAttribute("mathcolor",mathcolor);};if(mathfontfamily!="")node.setAttribute("fontfamily",mathfontfamily);node.appendChild(AMparseExpr(str.replace(/^\s+/g,""),false,false)[0]);node=AMcreateMmlNode("math",node);if(showasciiformulaonhover)+node.setAttribute("title",str.replace(/\s+/g," "));if(false){var fnode=AMcreateElementXHTML("font");fnode.setAttribute("face",mathfontfamily);fnode.appendChild(node);return fnode;}+return node;}+function AMstrarr2docFrag(arr,linebreaks){var newFrag=document.createDocumentFragment();var expr=false;for(var i=0;i<arr.length;i++){if(expr)newFrag.appendChild(AMparseMath(arr[i]));else{var arri=(linebreaks?arr[i].split("\n\n"):[arr[i]]);newFrag.appendChild(AMcreateElementXHTML("span").appendChild(document.createTextNode(arri[0])));for(var j=1;j<arri.length;j++){newFrag.appendChild(AMcreateElementXHTML("p"));newFrag.appendChild(AMcreateElementXHTML("span").appendChild(document.createTextNode(arri[j])));}}+expr=!expr;}+return newFrag;}+function AMprocessNodeR(n,linebreaks){var mtch,str,arr,frg,i;if(n.childNodes.length==0){if((n.nodeType!=8||linebreaks)&&n.parentNode.nodeName!="form"&&n.parentNode.nodeName!="FORM"&&n.parentNode.nodeName!="textarea"&&n.parentNode.nodeName!="TEXTAREA"&&n.parentNode.nodeName!="pre"&&n.parentNode.nodeName!="PRE"){str=n.nodeValue;if(!(str==null)){str=str.replace(/\r\n\r\n/g,"\n\n");str=str.replace(/\x20+/g," ");str=str.replace(/\s*\r\n/g," ");mtch=(str.indexOf("\$")==-1?false:true);str=str.replace(/([^\\])\$/g,"$1 \$");str=str.replace(/^\$/," \$");arr=str.split(" \$");for(i=0;i<arr.length;i++)+arr[i]=arr[i].replace(/\\\$/g,"\$");if(arr.length>1||mtch){if(checkForMathML){checkForMathML=false;var nd=AMisMathMLavailable();AMnoMathML=nd!=null;if(AMnoMathML&¬ifyIfNoMathML)+if(alertIfNoMathML)+alert("To view the ASCIIMathML notation use Internet Explorer 6 +\nMathPlayer (free from www.dessci.com)\nor Firefox/Mozilla/Netscape");else AMbody.insertBefore(nd,AMbody.childNodes[0]);}+if(!AMnoMathML){frg=AMstrarr2docFrag(arr,n.nodeType==8);var len=frg.childNodes.length;n.parentNode.replaceChild(frg,n);return len-1;}else return 0;}}}else return 0;}else if(n.nodeName!="math"){for(i=0;i<n.childNodes.length;i++)+i+=AMprocessNodeR(n.childNodes[i],linebreaks);}+return 0;}+function AMprocessNode(n,linebreaks,spanclassAM){var frag,st;if(spanclassAM!=null){frag=document.getElementsByTagName("span")+for(var i=0;i<frag.length;i++)+if(frag[i].className=="AM")+AMprocessNodeR(frag[i],linebreaks);}else{try{st=n.innerHTML;}catch(err){}+if(st==null||st.indexOf("\$")!=-1)+AMprocessNodeR(n,linebreaks);}+if(isIE){frag=document.getElementsByTagName('math');for(var i=0;i<frag.length;i++)frag[i].update()}}+var inAppendix=false;var sectionCntr=0;var IEcommentWarning=true;var biblist=[];var bibcntr=0;var LaTeXCounter=[];LaTeXCounter["definition"]=0;LaTeXCounter["proposition"]=0;LaTeXCounter["lemma"]=0;LaTeXCounter["theorem"]=0;LaTeXCounter["corollary"]=0;LaTeXCounter["example"]=0;LaTeXCounter["exercise"]=0;LaTeXCounter["subsection"]=0;LaTeXCounter["subsubsection"]=0;LaTeXCounter["figure"]=0;LaTeXCounter["equation"]=0;LaTeXCounter["table"]=0;var LaTeXColor=[];LaTeXColor["greenyellow"]="#D9FF4F";LaTeXColor["yellow"]="#FFFF00";LaTeXColor["goldenrod"]="#FFE529";LaTeXColor["dandelion"]="#FFB529";LaTeXColor["apricot"]="#FFAD7A";LaTeXColor["peach"]="#FF804D";LaTeXColor["melon"]="#FF8A80";LaTeXColor["yelloworange"]="#FF9400";LaTeXColor["orange"]="#FF6321";LaTeXColor["burntorange"]="#FF7D00";LaTeXColor["bittersweet"]="#C20300";LaTeXColor["redorange"]="#FF3B21";LaTeXColor["mahogany"]="#A60000";LaTeXColor["maroon"]="#AD0000";LaTeXColor["brickred"]="#B80000";LaTeXColor["red"]="#FF0000";LaTeXColor["orangered"]="#FF0080";LaTeXColor["rubinered"]="#FF00DE";LaTeXColor["wildstrawberry"]="#FF0A9C";LaTeXColor["salmon"]="#FF789E";LaTeXColor["carnationpink"]="#FF5EFF";LaTeXColor["magenta"]="#FF00FF";LaTeXColor["violetred"]="#FF30FF";LaTeXColor["rhodamine"]="#FF2EFF";LaTeXColor["mulberry"]="#A314FA";LaTeXColor["redviolet"]="#9600A8";LaTeXColor["fuchsia"]="#7303EB";LaTeXColor["lavender"]="#FF85FF";LaTeXColor["thistle"]="#E069FF";LaTeXColor["orchid"]="#AD5CFF";LaTeXColor["darkorchid"]="#9933CC";LaTeXColor["purple"]="#8C24FF";LaTeXColor["plum"]="#8000FF";LaTeXColor["violet"]="#361FFF";LaTeXColor["royalpurple"]="#401AFF";LaTeXColor["blueviolet"]="#1A0DF5";LaTeXColor["periwinkle"]="#6E73FF";LaTeXColor["cadetblue"]="#616EC4";LaTeXColor["cornflowerblue"]="#59DEFF";LaTeXColor["midnightblue"]="#007091";LaTeXColor["navyblue"]="#0F75FF";LaTeXColor["royalblue"]="#0080FF";LaTeXColor["blue"]="#0000FF";LaTeXColor["cerulean"]="#0FE3FF";LaTeXColor["cyan"]="#00FFFF";LaTeXColor["processblue"]="#0AFFFF";LaTeXColor["skyblue"]="#61FFE0";LaTeXColor["turquoise"]="#26FFCC";LaTeXColor["tealblue"]="#1FFAA3";LaTeXColor["aquamarine"]="#2EFFB2";LaTeXColor["bluegreen"]="#26FFAB";LaTeXColor["emerald"]="#00FF80";LaTeXColor["junglegreen"]="#03FF7A";LaTeXColor["seagreen"]="#4FFF80";LaTeXColor["green"]="#00FF00";LaTeXColor["forestgreen"]="#00E000";LaTeXColor["pinegreen"]="#00BF29";LaTeXColor["limegreen"]="#80FF00";LaTeXColor["yellowgreen"]="#8FFF42";LaTeXColor["springgreen"]="#BDFF3D";LaTeXColor["olivegreen"]="#009900";LaTeXColor["rawsienna"]="#8C0000";LaTeXColor["sepia"]="#4D0000";LaTeXColor["brown"]="#660000";LaTeXColor["tan"]="#DB9470";LaTeXColor["gray"]="#808080";LaTeXColor["grey"]="#808080";LaTeXColor["black"]="#000000";LaTeXColor["white"]="#FFFFFF";var IsColorName=/^(?:greenyellow|yellow|goldenrod|dandelion|apricot|peach|melon|yelloworange|orange|burntorange|bittersweet|redorange|mahogany|maroon|brickred|red|orangered|rubinered|wildstrawberry|salmon|carnationpink|magenta|violetred|rhodamine|mulberry|redviolet|fuchsia|lavender|thistle|orchid|darkorchid|purple|plum|violet|royalpurple|blueviolet|periwinkle|cadetblue|cornflowerblue|midnightblue|navyblue|royalblue|blue|cerulean|cyan|processblue|skyblue|turquoise|tealblue|aquamarine|bluegreen|emerald|junglegreen|seagreen|green|forestgreen|pinegreen|limegreen|yellowgreen|springgreen|olivegreen|rawsienna|sepia|brown|tan|gray|grey|black|white)$/;var IsCounter=/^(?:definition|proposition|lemma|theorem|corollary|example|exercise|subsection|subsubsection|figure|equation|table)$/;var IsLaTeXElement=/^(?:displayequation|title|author|address|date|abstract|keyword|section|subsection|subsubsection|ref|cite|thebibliography|definition|proposition|lemma|theorem|corollary|example|exercise|itemize|enumerate|enddefinition|endproposition|endlemma|endtheorem|endcorollary|endexample|endexercise|enditemize|endenumerate|LaTeXMathMLlabel|LaTeXMathML|smallskip|medskip|bigskip|quote|quotation|endquote|endquotation|center|endcenter|description|enddescription|inlinemath)$/;var IsTextOnlyArea=/^(?:form|textarea|pre)$/i;var tableid=0;function makeNumberString(cntr){if(sectionCntr>0){if(inAppendix){return"A"+sectionCntr+"."+cntr;}else{return sectionCntr+"."+cntr;}}else{return""+cntr;}};function LaTeXpreProcess(thebody){var TheBody=thebody;if(TheBody.hasChildNodes()){if(!(IsLaTeXElement.test(TheBody.className)))+{for(var i=0;i<TheBody.childNodes.length;i++){LaTeXpreProcess(TheBody.childNodes[i])}}}+else{if(TheBody.nodeType==3&&!(IsTextOnlyArea.test(TheBody.parentNode.nodeName)))+{var str=TheBody.nodeValue;if(!(str==null)){str=str.replace(/\\%/g,"<per>");str=str.replace(/%[^\n]*(?=\n)/g,"");str=str.replace(/%[^\r]*(?=\r)/g,"");str=str.replace(/%[^\n]*$/,"")+if(isIE&&str.match(/%/g)!=null&&IEcommentWarning){alert("Comments may not have parsed properly. Try putting in <pre class='LaTeX><div>..</div></pre> structure.");IEcommentWarning=false;}+str=str.replace(/<per>/g,"%");if(str.match(/XXX[\s\S]*/)!=null){var tmp=str.match(/XXX[\s\S]*/)[0];var tmpstr=tmp.charCodeAt(7)+"::"+tmp.charCodeAt(8)+"::"+tmp.charCodeAt(9)+"::"+tmp.charCodeAt(10)+"::"+tmp.charCodeAt(11)+"::"+tmp.charCodeAt(12)+"::"+tmp.charCodeAt(13);alert(tmpstr);}+str=str.replace(/([^\\])\\(\s)/g,"$1\u00A0$2");str=str.replace(/\\quad/g,"\u2001");str=str.replace(/\\qquad/g,"\u2001\u2001");str=str.replace(/\\enspace/g,"\u2002");str=str.replace(/\\;/g,"\u2004");str=str.replace(/\\:/g,"\u2005");str=str.replace(/\\,/g,"\u2006");str=str.replace(/\\thinspace/g,"\u200A");str=str.replace(/([^\\])~/g,"$1\u00A0");str=str.replace(/\\~/g,"~");str=str.replace(/\\\[/g," <DEQ> $\\displaystyle{");str=str.replace(/\\\]/g,"}$ <DEQ> ");str=str.replace(/\$\$/g,"${$<DEQ>$}$");str=str.replace(/\\begin\s*\{\s*array\s*\}/g,"\\begin{array}");str=str.replace(/\\end\s*\{\s*array\s*\}/g,"\\end{array}");str=str.replace(/\\begin\s*\{\s*eqnarray\s*\}/g," <DEQ>eqno$\\begin{eqnarray}");str=str.replace(/\\end\s*\{\s*eqnarray\s*\}/g,"\\end{eqnarray}$<DEQ> ");str=str.replace(/\\begin\s*\{\s*eqnarray\*\s*\}/g," <DEQ>$\\begin{eqnarray}");str=str.replace(/\\end\s*\{\s*eqnarray\*\s*\}/g,"\\end{eqnarray}$<DEQ> ");str=str.replace(/\\begin\s*\{\s*displaymath\s*\}/g," <DEQ> $\\displaystyle{");str=str.replace(/\\end\s*\{\s*displaymath\s*\}/g,"}$ <DEQ> ");str=str.replace(/\\begin\s*\{\s*equation\s*\*\s*\}/g," <DEQ> $\\displaystyle{");str=str.replace(/\\end\s*\{\s*equation\s*\*\s*\}/g,"}$ <DEQ> ");str=str.replace(/\\begin\s*\{\s*equation\s*\}/g," <DEQ>eqno$\\displaystyle{");str=str.replace(/\\end\s*\{\s*equation\s*\}/g,"}$ <DEQ> ");str=str.split("<DEQ>");var newFrag=document.createDocumentFragment();for(var i=0;i<str.length;i++){if(i%2){var DEQtable=document.createElement("table");DEQtable.className='displayequation';var DEQtbody=document.createElement("tbody");var DEQtr=document.createElement("tr");var DEQtdeq=document.createElement("td");DEQtdeq.className='eq';str[i]=str[i].replace(/\$\}\$/g,"$\\displaystyle{");str[i]=str[i].replace(/\$\{\$/g,"}");var lbl=str[i].match(/\\label\s*\{\s*(\w+)\s*\}/);var ISeqno=str[i].match(/^eqno/);str[i]=str[i].replace(/^eqno/," ");str[i]=str[i].replace(/\\label\s*\{\s*\w+\s*\}/," ");DEQtdeq.appendChild(document.createTextNode(str[i]));DEQtr.appendChild(DEQtdeq);str[i]=str[i].replace(/\\nonumber/g,"");if(ISeqno!=null||lbl!=null){var DEQtdno=document.createElement("td");DEQtdno.className='eqno';LaTeXCounter["equation"]++;var eqnoString=makeNumberString(LaTeXCounter["equation"]);var DEQanchor=document.createElement("a");if(lbl!=null){DEQanchor.id=lbl[1]};DEQanchor.className="eqno";var anchorSpan=document.createElement("span");anchorSpan.className="eqno";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(eqnoString));DEQanchor.appendChild(anchorSpan);DEQtdno.appendChild(DEQanchor);var DEQspan=document.createElement("span");DEQspan.className="eqno";DEQspan.appendChild(document.createTextNode("("+eqnoString+")"));DEQtdno.appendChild(DEQspan);DEQtr.appendChild(DEQtdno);}+DEQtbody.appendChild(DEQtr);DEQtable.appendChild(DEQtbody);newFrag.appendChild(DEQtable);}+else{str[i]=str[i].replace(/\$\}\$/g,"");str[i]=str[i].replace(/\$\{\$/g,"");str[i]=str[i].replace(/\\maketitle/g,"");str[i]=str[i].replace(/\\begin\s*\{\s*document\s*\}/g,"");str[i]=str[i].replace(/\\end\s*\{\s*document\s*\}/g,"");str[i]=str[i].replace(/\\documentclass[^\}]*?\}/g,"");str[i]=str[i].replace(/\\usepackage[^\}]*?\}/g,"");str[i]=str[i].replace(/\\noindent/g,"");str[i]=str[i].replace(/\\notag/g,"");str[i]=str[i].replace(/\\ref\s*\{\s*(\w+)\}/g," \\[ref\\]$1\\[ ");str[i]=str[i].replace(/\\url\s*\{\s*([^\}\n]+)\}/g," \\[url\\]$1\\[ ");str[i]=str[i].replace(/\\href\s*\{\s*([^\}]+)\}\s*\{\s*([^\}]+)\}/g," \\[href\\]$1\\]$2\\[ ");str[i]=str[i].replace(/\\cite\s*\{\s*(\w+)\}/g," \\[cite\\]$1\\[ ");str[i]=str[i].replace(/\\qed/g,"\u220E");str[i]=str[i].replace(/\\endproof/g,"\u220E");str[i]=str[i].replace(/\\proof/g,"\\textbf{Proof: }");str[i]=str[i].replace(/\\n(?=\s)/g," \\[br\\] \\[ ");str[i]=str[i].replace(/\\newline/g," \\[br\\] \\[ ");str[i]=str[i].replace(/\\linebreak/g," \\[br\\] \\[ ");str[i]=str[i].replace(/\\smallskip/g," \\[logicalbreak\\]smallskip\\[ ");str[i]=str[i].replace(/\\medskip/g," \\[logicalbreak\\]medskip\\[ ");str[i]=str[i].replace(/\\bigskip/g," \\[logicalbreak\\]bigskip\\[ ");str[i]=str[i].replace(/[\n\r]+[ \f\n\r\t\v\u2028\u2029]*[\n\r]+/g," \\[logicalbreak\\]LaTeXMathML\\[ ");if(isIE){str[i]=str[i].replace(/\r/g," ");}+str[i]=str[i].replace(/\\bibitem\s*([^\{]*\{\s*\w*\s*\})/g," \\[bibitem\\]$1\\[ ");str[i]=str[i].replace(/\\bibitem\s*/g," \\[bibitem\\] \\[ ");str[i]=str[i].replace(/\\item\s*\[\s*(\w+)\s*\]/g," \\[alistitem\\]$1\\[ ");str[i]=str[i].replace(/\\item\s*/g," \\[alistitem\\] \\[ ");str[i]=str[i].replace(/\\appendix/g," \\[appendix\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*figure\s*\}([\s\S]+?)\\end\s*\{\s*figure\s*\}/g," \\[figure\\]$1\\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*table\s*\}([\s\S]+?)\\end\s*\{\s*table\s*\}/g," \\[table\\]$1\\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*theorem\s*\}/g," \\[theorem\\]Theorem \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*theorem\s*\}/g," \\[endtheorem\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*definition\s*\}/g," \\[definition\\]Definition \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*definition\s*\}/g," \\[enddefinition\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*lemma\s*\}/g," \\[lemma\\]Lemma \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*lemma\s*\}/g," \\[endlemma\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*corollary\s*\}/g," \\[corollary\\]Corollary \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*corollary\s*\}/g," \\[endcorollary\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*proposition\s*\}/g," \\[proposition\\]Proposition \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*proposition\s*\}/g," \\[endproposition\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*example\s*\}/g," \\[example\\]Example \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*example\s*\}/g," \\[endexample\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*exercise\s*\}/g," \\[exercise\\]Exercise \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*exercise\s*\}/g," \\[endexercise\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*thebibliography\s*\}\s*\{\s*\w+\s*\}/g," \\[thebibliography\\]References \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*thebibliography\s*\}/g," \\[thebibliography\\]References \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*thebibliography\s*\}/g," \\[endthebibliography\\]References \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*proof\s*\}/g," \\[proof\\]Proof: \\[ ");if(isIE){str[i]=str[i].replace(/\\end\s*\{\s*proof\s*\}/g,"\u220E \\[endproof\\] \\[ ");}else{str[i]=str[i].replace(/\\end\s*\{\s*proof\s*\}/g," \\[endproof\\] \\[ ");}+str[i]=str[i].replace(/\\title\s*\{\s*([^\}]+)\}/g," \\[title\\] \\[$1 \\[endtitle\\] \\[ ");str[i]=str[i].replace(/\\author\s*\{\s*([^\}]+)\}/g," \\[author\\] \\[$1 \\[endauthor\\] \\[ ");str[i]=str[i].replace(/\\address\s*\{\s*([^\}]+)\}/g," \\[address\\] \\[$1 \\[endaddress\\] \\[ ");str[i]=str[i].replace(/\\date\s*\{\s*([^\}]+)\}/g," \\[date\\] \\[$1 \\[enddate\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*keyword\s*\}/g," \\[keyword\\] \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*keyword\s*\}/g," \\[endkeyword\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*abstract\s*\}/g," \\[abstract\\] \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*abstract\s*\}/g," \\[endabstract\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*(?!array|tabular)(\w+)\s*\}/g," \\[$1\\] \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*(?!array|tabular)(\w+)\s*\}/g," \\[end$1\\] \\[ ");var sectionIndex=str[i].search(/\\section\s*\{\s*[\s\S]+\}/);while(sectionIndex>=0){str[i]=str[i].replace(/\\section\s*\{/," \\[section\\]");var delimcnt=1;for(var ii=sectionIndex;ii<str[i].length;ii++){if(str[i].charAt(ii)=="{"){delimcnt++};if(str[i].charAt(ii)=="}"){delimcnt--};if(delimcnt==0){str[i]=str[i].substring(0,ii)+"\\[ "+str[i].substring(ii+1,str[i].length);break;}};sectionIndex=str[i].search(/\\section\s*\{\s*[\s\S]+\}/);}+sectionIndex=str[i].search(/\\subsection\s*\{\s*[\s\S]+\}/);while(sectionIndex>=0){str[i]=str[i].replace(/\\subsection\s*\{/," \\[subsection\\]");var delimcnt=1;for(var ii=sectionIndex;ii<str[i].length;ii++){if(str[i].charAt(ii)=="{"){delimcnt++};if(str[i].charAt(ii)=="}"){delimcnt--};if(delimcnt==0){str[i]=str[i].substring(0,ii)+"\\[ "+str[i].substring(ii+1,str[i].length);break;}};sectionIndex=str[i].search(/\\subsection\s*\{\s*[\s\S]+\}/);}+sectionIndex=str[i].search(/\\subsubsection\s*\{\s*[\s\S]+\}/);while(sectionIndex>=0){str[i]=str[i].replace(/\\subsubsection\s*\{/," \\[subsubsection\\]");var delimcnt=1;for(var ii=sectionIndex;ii<str[i].length;ii++){if(str[i].charAt(ii)=="{"){delimcnt++};if(str[i].charAt(ii)=="}"){delimcnt--};if(delimcnt==0){str[i]=str[i].substring(0,ii)+"\\[ "+str[i].substring(ii+1,str[i].length);break;}};sectionIndex=str[i].search(/\\subsubsection\s*\{\s*[\s\S]+\}/);}+var CatToNextEven="";var strtmp=str[i].split("\\[");for(var j=0;j<strtmp.length;j++){if(j%2){var strtmparray=strtmp[j].split("\\]");switch(strtmparray[0]){case"section":var nodeTmp=document.createElement("H2");nodeTmp.className='section';sectionCntr++;for(var div in LaTeXCounter){LaTeXCounter[div]=0};var nodeAnchor=document.createElement("a");if(inAppendix){nodeAnchor.className='appendixsection';}else{nodeAnchor.className='section';}+var nodeNumString=makeNumberString("");var anchorSpan=document.createElement("span");anchorSpan.className="section";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(nodeNumString));nodeAnchor.appendChild(anchorSpan);nodeTmp.appendChild(nodeAnchor);var nodeSpan=document.createElement("span");nodeSpan.className='section';nodeSpan.appendChild(document.createTextNode(nodeNumString+" "));nodeTmp.appendChild(nodeSpan);nodeTmp.appendChild(document.createTextNode(strtmparray[1]));newFrag.appendChild(nodeTmp);break;case"subsection":var nodeTmp=document.createElement("H3");nodeTmp.className='subsection';LaTeXCounter["subsection"]++;LaTeXCounter["subsubsection"]=0;var nodeAnchor=document.createElement("a");nodeAnchor.className='subsection';var nodeNumString=makeNumberString(LaTeXCounter["subsection"]);var anchorSpan=document.createElement("span");anchorSpan.className="subsection";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(nodeNumString));nodeAnchor.appendChild(anchorSpan);nodeTmp.appendChild(nodeAnchor);var nodeSpan=document.createElement("span");nodeSpan.className='subsection';nodeSpan.appendChild(document.createTextNode(nodeNumString+". "));nodeTmp.appendChild(nodeSpan);nodeTmp.appendChild(document.createTextNode(strtmparray[1]));newFrag.appendChild(nodeTmp);break;case"subsubsection":var nodeTmp=document.createElement("H4");nodeTmp.className='subsubsection';LaTeXCounter["subsubsection"]++;var nodeAnchor=document.createElement("a");nodeAnchor.className='subsubsection';var nodeNumString=makeNumberString(LaTeXCounter["subsection"]+"."+LaTeXCounter["subsubsection"]);var anchorSpan=document.createElement("span");anchorSpan.className="subsubsection";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(nodeNumString));nodeAnchor.appendChild(anchorSpan);nodeTmp.appendChild(nodeAnchor);var nodeSpan=document.createElement("span");nodeSpan.className='subsubsection';nodeSpan.appendChild(document.createTextNode(nodeNumString+". "));nodeTmp.appendChild(nodeSpan);nodeTmp.appendChild(document.createTextNode(strtmparray[1]));newFrag.appendChild(nodeTmp);break;case"href":var nodeTmp=document.createElement("a");nodeTmp.className='LaTeXMathML';nodeTmp.href=strtmparray[1];nodeTmp.appendChild(document.createTextNode(strtmparray[2]));newFrag.appendChild(nodeTmp);break;case"url":var nodeTmp=document.createElement("a");nodeTmp.className='LaTeXMathML';nodeTmp.href=strtmparray[1];nodeTmp.appendChild(document.createTextNode(strtmparray[1]));newFrag.appendChild(nodeTmp);break;case"figure":var nodeTmp=document.createElement("table");nodeTmp.className='figure';var FIGtbody=document.createElement("tbody");var FIGlbl=strtmparray[1].match(/\\label\s*\{\s*(\w+)\s*\}/);strtmparray[1]=strtmparray[1].replace(/\\label\s*\{\w+\}/g,"");var capIndex=strtmparray[1].search(/\\caption\s*\{[\s\S]+\}/);var FIGcap="";if(capIndex>=0){var tmp=strtmparray[1];var delimcnt=0;var capstart=-1;for(var pos=capIndex;pos<tmp.length;pos++){if(tmp.charAt(pos)=="{"){delimcnt++};if(tmp.charAt(pos)=="}"){delimcnt--};if(delimcnt==1&&capstart<0){capstart=pos+1};if(delimcnt==0&&capstart>0){capend=pos-1;FIGcap=tmp.substring(capstart,pos);break}}}+var FIGtr2=document.createElement("tr");var FIGtd2=document.createElement("td");FIGtd2.className="caption";var FIGanchor=document.createElement("a");FIGanchor.className="figure";if(FIGlbl!=null){FIGanchor.id=FIGlbl[1];}+LaTeXCounter["figure"]++;var fignmbr=makeNumberString(LaTeXCounter["figure"]);var anchorSpan=document.createElement("span");anchorSpan.className="figure";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(fignmbr));FIGanchor.appendChild(anchorSpan);FIGtd2.appendChild(FIGanchor);var FIGspan=document.createElement("span");FIGspan.className="figure";FIGspan.appendChild(document.createTextNode("Figure "+fignmbr+". "));FIGtd2.appendChild(FIGspan);FIGtd2.appendChild(document.createTextNode(""+FIGcap));FIGtr2.appendChild(FIGtd2);FIGtbody.appendChild(FIGtr2);var IsSpecial=false;var FIGinfo=strtmparray[1].match(/\\includegraphics\s*\{([^\}]+)\}/);if(FIGinfo==null){FIGinfo=strtmparray[1].match(/\\includegraphics\s*\[[^\]]*\]\s*\{\s*([^\}]+)\s*\}/);}+if(FIGinfo==null){FIGinfo=strtmparray[1].match(/\\special\s*\{\s*([^\}]+)\}/);IsSpecial=true};if(FIGinfo!=null){var FIGtr1=document.createElement("tr");var FIGtd1=document.createElement("td");FIGtd1.className="image";var FIGimg=document.createElement("img");var FIGsrc=FIGinfo[1];FIGimg.src=FIGsrc;FIGimg.alt="Figure "+FIGsrc+" did not load";FIGimg.title="Figure "+fignmbr+". "+FIGcap;FIGimg.id="figure"+fignmbr;FIGtd1.appendChild(FIGimg);FIGtr1.appendChild(FIGtd1);FIGtbody.appendChild(FIGtr1);}+nodeTmp.appendChild(FIGtbody);newFrag.appendChild(nodeTmp);break;case"table":var nodeTmp=document.createElement("table");if(strtmparray[1].search(/\\centering/)>=0){nodeTmp.className='LaTeXtable centered';nodeTmp.align="center";}else{nodeTmp.className='LaTeXtable';};tableid++;nodeTmp.id="LaTeXtable"+tableid;var TABlbl=strtmparray[1].match(/\\label\s*\{\s*(\w+)\s*\}/);strtmparray[1]=strtmparray[1].replace(/\\label\s*\{\w+\}/g,"");var capIndex=strtmparray[1].search(/\\caption\s*\{[\s\S]+\}/);var TABcap="";if(capIndex>=0){var tmp=strtmparray[1];var delimcnt=0;var capstart=-1;for(var pos=capIndex;pos<tmp.length;pos++){if(tmp.charAt(pos)=="{"){delimcnt++};if(tmp.charAt(pos)=="}"){delimcnt--};if(delimcnt==1&&capstart<0){capstart=pos+1};if(delimcnt==0&&capstart>0){capend=pos-1;TABcap=tmp.substring(capstart,pos);break}}}+if(TABcap!=""){var TABtbody=document.createElement("tbody");var TABcaption=document.createElement("caption");TABcaption.className="LaTeXtable centered";var TABanchor=document.createElement("a");TABanchor.className="LaTeXtable";if(TABlbl!=null){TABanchor.id=TABlbl[1];}+LaTeXCounter["table"]++;var tabnmbr=makeNumberString(LaTeXCounter["table"]);var anchorSpan=document.createElement("span");anchorSpan.className="LaTeXtable";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(tabnmbr));TABanchor.appendChild(anchorSpan);TABcaption.appendChild(TABanchor);var TABspan=document.createElement("span");TABspan.className="LaTeXtable";TABspan.appendChild(document.createTextNode("Table "+tabnmbr+". "));TABcaption.appendChild(TABspan);TABcaption.appendChild(document.createTextNode(""+TABcap));nodeTmp.appendChild(TABcaption);}+var TABinfo=strtmparray[1].match(/\\begin\s*\{\s*tabular\s*\}([\s\S]+)\\end\s*\{\s*tabular\s*\}/);if(TABinfo!=null){var TABtbody=document.createElement('tbody');var TABrow=null;var TABcell=null;var row=0;var col=0;var TABalign=TABinfo[1].match(/^\s*\{([^\}]+)\}/);TABinfo=TABinfo[1].replace(/^\s*\{[^\}]+\}/,"");TABinfo=TABinfo.replace(/\\hline/g,"");TABalign[1]=TABalign[1].replace(/\|/g,"");TABalign[1]=TABalign[1].replace(/\s/g,"");TABinfo=TABinfo.split("\\\\");for(row=0;row<TABinfo.length;row++){TABrow=document.createElement("tr");TABinfo[row]=TABinfo[row].split("&");for(col=0;col<TABinfo[row].length;col++){TABcell=document.createElement("td");switch(TABalign[1].charAt(col)){case"l":TABcell.align="left";break;case"c":TABcell.align="center";break;case"r":TABcell.align="right";break;default:TABcell.align="left";};TABcell.appendChild(document.createTextNode(TABinfo[row][col]));TABrow.appendChild(TABcell);}+TABtbody.appendChild(TABrow);}+nodeTmp.appendChild(TABtbody);}+newFrag.appendChild(nodeTmp);break;case"logicalbreak":var nodeTmp=document.createElement("p");nodeTmp.className=strtmparray[1];nodeTmp.appendChild(document.createTextNode("\u00A0"));newFrag.appendChild(nodeTmp);break;case"appendix":inAppendix=true;sectionCntr=0;break;case"alistitem":var EndDiv=document.createElement("div");EndDiv.className="endlistitem";newFrag.appendChild(EndDiv);var BegDiv=document.createElement("div");BegDiv.className="listitem";if(strtmparray[1]!=" "){var BegSpan=document.createElement("span");BegSpan.className="listitemmarker";var boldBegSpan=document.createElement("b");boldBegSpan.appendChild(document.createTextNode(strtmparray[1]+" "));BegSpan.appendChild(boldBegSpan);BegDiv.appendChild(BegSpan);}+newFrag.appendChild(BegDiv);break;case"br":newFrag.appendChild(document.createElement("br"));break;case"bibitem":newFrag.appendChild(document.createElement("br"));var nodeTmp=document.createElement("a");nodeTmp.className='bibitem';var nodeSpan=document.createElement("span");nodeSpan.className='bibitem';bibcntr++;var lbl=strtmparray[1].match(/\{\s*(\w+)\s*\}/);strtmparray[1]=strtmparray[1].replace(/\s*\{\s*\w+\s*\}/g,"");strtmparray[1]=strtmparray[1].replace(/^\s*\[/,"");strtmparray[1]=strtmparray[1].replace(/\s*\]$/,"");strtmparray[1]=strtmparray[1].replace(/^\s+|\s+$/g,"");if(lbl==null){biblist[bibcntr]="bibitem"+bibcntr}else{biblist[bibcntr]=lbl[1];};nodeTmp.name=biblist[bibcntr];nodeTmp.id=biblist[bibcntr];if(strtmparray[1]!=""){nodeSpan.appendChild(document.createTextNode(strtmparray[1]));}else{nodeSpan.appendChild(document.createTextNode("["+bibcntr+"]"));}+nodeTmp.appendChild(nodeSpan);newFrag.appendChild(nodeTmp);break;case"cite":var nodeTmp=document.createElement("a");nodeTmp.className='cite';nodeTmp.name='cite';nodeTmp.href="#"+strtmparray[1];newFrag.appendChild(nodeTmp);break;case"ref":var nodeTmp=document.createElement("a");nodeTmp.className='ref';nodeTmp.name='ref';nodeTmp.href="#"+strtmparray[1];newFrag.appendChild(nodeTmp);break;default:var nodeTmp=document.createElement("div");nodeTmp.className=strtmparray[0];if(IsCounter.test(strtmparray[0])){LaTeXCounter[strtmparray[0]]++;var nodeAnchor=document.createElement("a");nodeAnchor.className=strtmparray[0];var divnum=makeNumberString(LaTeXCounter[strtmparray[0]]);var anchorSpan=document.createElement("span");anchorSpan.className=strtmparray[0];anchorSpan.appendChild(document.createTextNode(divnum));anchorSpan.style.display="none";nodeAnchor.appendChild(anchorSpan);nodeTmp.appendChild(nodeAnchor);var nodeSpan=document.createElement("span");nodeSpan.className=strtmparray[0];nodeSpan.appendChild(document.createTextNode(strtmparray[1]+" "+divnum+". "));nodeTmp.appendChild(nodeSpan);}+if(isIE){if(strtmparray[0]==("thebibliography"||"abstract"||"keyword"||"proof")){var nodeSpan=document.createElement("span");nodeSpan.className=strtmparray[0];nodeSpan.appendChild(document.createTextNode(strtmparray[1]));nodeTmp.appendChild(nodeSpan);}}+if(strtmparray[0]=="endenumerate"||strtmparray[0]=="enditemize"||strtmparray[0]=="enddescription"){var endDiv=document.createElement("div");endDiv.className="endlistitem";newFrag.appendChild(endDiv);}+newFrag.appendChild(nodeTmp);if(strtmparray[0]=="enumerate"||strtmparray[0]=="itemize"||strtmparray[0]=="description"){var endDiv=document.createElement("div");endDiv.className="listitem";newFrag.appendChild(endDiv);}}}else{strtmp[j]=strtmp[j].replace(/\\\$/g,"<per>");strtmp[j]=strtmp[j].replace(/\$([^\$]+)\$/g," \\[$1\\[ ");strtmp[j]=strtmp[j].replace(/<per>/g,"\\$");strtmp[j]=strtmp[j].replace(/\\begin\s*\{\s*math\s*\}([\s\S]+?)\\end\s*\{\s*math\s*\}/g," \\[$1\\[ ");var strtmptmp=strtmp[j].split("\\[");for(var jjj=0;jjj<strtmptmp.length;jjj++){if(jjj%2){var nodeTmp=document.createElement("span");nodeTmp.className='inlinemath';nodeTmp.appendChild(document.createTextNode("$"+strtmptmp[jjj]+"$"));newFrag.appendChild(nodeTmp);}else{var TagIndex=strtmptmp[jjj].search(/\\\w+/);var tmpIndex=TagIndex;while(tmpIndex>-1){if(/^\\textcolor/.test(strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length))){strtmptmp[jjj]=strtmptmp[jjj].replace(/\\textcolor\s*\{\s*(\w+)\s*\}\s*/," \\[textcolor\\]$1\\]|");}else{if(/^\\colorbox/.test(strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length))){strtmptmp[jjj]=strtmptmp[jjj].replace(/\\colorbox\s*\{\s*(\w+)\s*\}\s*/," \\[colorbox\\]$1\\]|");}else{strtmptmp[jjj]=strtmptmp[jjj].substring(0,TagIndex)+strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).replace(/\\\s*(\w+)\s*/," \\[$1\\]|");}}+TagIndex+=strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).search(/\|/);TagIndex++;strtmptmp[jjj]=strtmptmp[jjj].replace(/\\\]\|/,"\\] ");if(strtmptmp[jjj].charAt(TagIndex)=="{"){strtmptmp[jjj]=strtmptmp[jjj].substring(0,TagIndex)+strtmptmp[jjj].substring(TagIndex+1,strtmptmp[jjj].length);var delimcnt=1;for(var kk=TagIndex;kk<strtmptmp[jjj].length;kk++){if(strtmptmp[jjj].charAt(kk)=="{"){delimcnt++};if(strtmptmp[jjj].charAt(kk)=="}"){delimcnt--};if(delimcnt==0){break;}}+strtmptmp[jjj]=strtmptmp[jjj].substring(0,kk)+"\\[ "+strtmptmp[jjj].substring(kk+1,strtmptmp[jjj].length);TagIndex=kk+3;}else{strtmptmp[jjj]=strtmptmp[jjj].substring(0,TagIndex)+"\\[ "+strtmptmp[jjj].substring(TagIndex+1,strtmptmp[jjj].length);TagIndex=TagIndex+3;}+if(TagIndex<strtmptmp[jjj].length){tmpIndex=strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).search(/\\\w+/);}+else{tmpIndex=-1};TagIndex+=tmpIndex;}+strtmptmp[jjj]=strtmptmp[jjj].replace(/\\\\\s*\\\\/g,"\\\\");strtmptmp[jjj]=strtmptmp[jjj].replace(/\\\\/g," \\[br\\] \\[ ");strtmptmp[jjj]=strtmptmp[jjj].replace(/\\label\s*\{\s*(\w+)\s*\}/g," \\[a\\]$1\\[ ");var strlbls=strtmptmp[jjj].split("\\[");for(var jj=0;jj<strlbls.length;jj++){if(jj%2){var strtmparray=strlbls[jj].split("\\]");switch(strtmparray[0]){case"textcolor":var nodeTmp=document.createElement("span");nodeTmp.className='LaTeXColor';if(IsColorName.test(strtmparray[1].toLowerCase())){nodeTmp.style.color=LaTeXColor[strtmparray[1].toLowerCase()];}else{nodeTmp.style.color=strtmparray[1];};nodeTmp.appendChild(document.createTextNode(strtmparray[2]));newFrag.appendChild(nodeTmp);break;case"colorbox":var nodeTmp=document.createElement("span");nodeTmp.className='LaTeXColor';if(IsColorName.test(strtmparray[1].toLowerCase())){nodeTmp.style.background=LaTeXColor[strtmparray[1].toLowerCase()];}else{nodeTmp.style.background=strtmparray[1];};nodeTmp.appendChild(document.createTextNode(strtmparray[2]));newFrag.appendChild(nodeTmp);break;case"br":newFrag.appendChild(document.createElement("br"));break;case"a":var nodeTmp=document.createElement("a");nodeTmp.className='LaTeXMathMLlabel';nodeTmp.id=strtmparray[1];nodeTmp.style.display="none";newFrag.appendChild(nodeTmp);break;default:var nodeTmp=document.createElement("span");nodeTmp.className=strtmparray[0];nodeTmp.appendChild(document.createTextNode(strtmparray[1]))+newFrag.appendChild(nodeTmp);}}else{newFrag.appendChild(document.createTextNode(strlbls[jj]));}}}}}}}};TheBody.parentNode.replaceChild(newFrag,TheBody);}}}+return TheBody;}+function LaTeXDivsAndRefs(thebody){var TheBody=thebody;var EndDivClass=null;var AllDivs=TheBody.getElementsByTagName("div");var lbl2id="";var lblnode=null;for(var i=AllDivs.length-1;i>=0;i--){EndDivClass=AllDivs[i].className.match(/end\w+/);if(EndDivClass!=null){EndDivClass=EndDivClass[0];var DivClass=EndDivClass.substring(3,EndDivClass.length);var EndDivNode=AllDivs[i];break;}}+while(EndDivClass!=null){var newFrag=document.createDocumentFragment();var RootNode=EndDivNode.parentNode;var ClassCount=1;while(EndDivNode.previousSibling!=null&&ClassCount>0){switch(EndDivNode.previousSibling.className){case EndDivClass:ClassCount++;newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);break;case DivClass:if(EndDivNode.previousSibling.nodeName=="DIV"){ClassCount--;if(lbl2id!=""){EndDivNode.previousSibling.id=lbl2id;lbl2id=""}+if(ClassCount==0){RootNode=EndDivNode.previousSibling;}else{newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);}};break;case'LaTeXMathMLlabel':lbl2id=EndDivNode.previousSibling.id;EndDivNode.parentNode.removeChild(EndDivNode.previousSibling);break;default:newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);}}+RootNode.appendChild(newFrag);EndDivNode.parentNode.removeChild(EndDivNode);AllDivs=TheBody.getElementsByTagName("DIV");for(i=AllDivs.length-1;i>=0;i--){EndDivClass=AllDivs[i].className.match(/end\w+/);if(EndDivClass!=null){ClassCount=0;EndDivClass=EndDivClass[0];DivClass=EndDivClass.substring(3,EndDivClass.length);EndDivNode=AllDivs[i];RootNode=EndDivNode.parentNode;break;}}}+var AllDivs=TheBody.getElementsByTagName("div");var DIV2LI=null;for(var i=0;i<AllDivs.length;i++){if(AllDivs[i].className=="itemize"||AllDivs[i].className=="enumerate"||AllDivs[i].className=="description"){if(AllDivs[i].className=="itemize"){RootNode=document.createElement("UL");}else{RootNode=document.createElement("OL");}+RootNode.className='LaTeXMathML';if(AllDivs[i].hasChildNodes()){AllDivs[i].removeChild(AllDivs[i].firstChild)};while(AllDivs[i].hasChildNodes()){if(AllDivs[i].firstChild.hasChildNodes()){DIV2LI=document.createElement("LI");while(AllDivs[i].firstChild.hasChildNodes()){DIV2LI.appendChild(AllDivs[i].firstChild.firstChild);}+if(DIV2LI.firstChild.className=="listitemmarker"){DIV2LI.style.listStyleType="none";}+RootNode.appendChild(DIV2LI)}+AllDivs[i].removeChild(AllDivs[i].firstChild);}+AllDivs[i].appendChild(RootNode);}}+var AllAnchors=TheBody.getElementsByTagName("a");for(var i=0;i<AllAnchors.length;i++){if(AllAnchors[i].className=="ref"||AllAnchors[i].className=="cite"){var label=AllAnchors[i].href.match(/\#(\w+)/);if(label!=null){var labelNode=document.getElementById(label[1]);if(labelNode!=null){var TheSpans=labelNode.getElementsByTagName("SPAN");if(TheSpans!=null){var refNode=TheSpans[0].cloneNode(true);refNode.style.display="inline"+refNode.className=AllAnchors[i].className;AllAnchors[i].appendChild(refNode);}}}}}+return TheBody;}+var AMbody;var AMnoMathML=false,AMtranslated=false;function translate(spanclassAM){if(!AMtranslated){AMtranslated=true;AMinitSymbols();var LaTeXContainers=[];var AllContainers=document.getElementsByTagName('*');var ExtendName="";for(var k=0,l=0;k<AllContainers.length;k++){ExtendName=" "+AllContainers[k].className+" ";if(ExtendName.match(/\sLaTeX\s/)!=null){LaTeXContainers[l]=AllContainers[k];l++;}};if(LaTeXContainers.length>0){for(var m=0;m<LaTeXContainers.length;m++){AMbody=LaTeXContainers[m];try{AMbody=LaTeXDivsAndRefs(LaTeXpreProcess(AMbody));}catch(err){alert("Unknown Error: Defaulting to Original LaTeXMathML");}+if(AMbody.tagName=="PRE"){var PreChilds=document.createDocumentFragment();var DivChilds=document.createElement("DIV");while(AMbody.hasChildNodes()){DivChilds.appendChild(AMbody.firstChild);}+PreChilds.appendChild(DivChilds);AMbody.parentNode.replaceChild(PreChilds,AMbody);AMbody=DivChilds;}+AMprocessNode(AMbody,false,spanclassAM);}}else{AMbody=document.getElementsByTagName("body")[0];try{AMbody=LaTeXDivsAndRefs(LaTeXpreProcess(AMbody));}catch(err){alert("Unknown Error: Defaulting to Original LaTeXMathML");}+AMprocessNode(AMbody,false,spanclassAM);}}}+if(isIE){document.write("<object id=\"mathplayer\" classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>");document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>");}+function generic()+{translate();};if(typeof window.addEventListener!='undefined')+{window.addEventListener('load',generic,false);}+else if(typeof document.addEventListener!='undefined')+{document.addEventListener('load',generic,false);}+else if(typeof window.attachEvent!='undefined')+{window.attachEvent('onload',generic);}+else+{if(typeof window.onload=='function')+{var existing=onload;window.onload=function()+{existing();generic();};}+else+{window.onload=generic;}}
@@ -0,0 +1,70 @@+/*+March 19, 2004 MathHTML (c) Peter Jipsen http://www.chapman.edu/~jipsen+Released under the GNU General Public License version 2 or later.+See the GNU General Public License (at http://www.gnu.org/copyleft/gpl.html)+for more details.+*/++function convertMath(node) {// for Gecko+ if (node.nodeType==1) {+ var newnode =+ document.createElementNS("http://www.w3.org/1998/Math/MathML",+ node.nodeName.toLowerCase());+ for(var i=0; i < node.attributes.length; i++)+ newnode.setAttribute(node.attributes[i].nodeName,+ node.attributes[i].value);+ for (var i=0; i<node.childNodes.length; i++) {+ var st = node.childNodes[i].nodeValue;+ if (st==null || st.slice(0,1)!=" " && st.slice(0,1)!="\n")+ newnode.appendChild(convertMath(node.childNodes[i]));+ }+ return newnode;+ }+ else return node;+}++function convert() {+ var mmlnode = document.getElementsByTagName("math");+ var st,str,node,newnode;+ for (var i=0; i<mmlnode.length; i++)+ if (document.createElementNS!=null)+ mmlnode[i].parentNode.replaceChild(convertMath(mmlnode[i]),mmlnode[i]);+ else { // convert for IE+ str = "";+ node = mmlnode[i];+ while (node.nodeName!="/MATH") {+ st = node.nodeName.toLowerCase();+ if (st=="#text") str += node.nodeValue;+ else {+ str += (st.slice(0,1)=="/" ? "</m:"+st.slice(1) : "<m:"+st);+ if (st.slice(0,1)!="/")+ for(var j=0; j < node.attributes.length; j++)+ if (node.attributes[j].value!="italic" &&+ node.attributes[j].value!="" &&+ node.attributes[j].value!="inherit" &&+ node.attributes[j].value!=undefined)+ str += " "+node.attributes[j].nodeName+"="++ "\""+node.attributes[j].value+"\"";+ str += ">";+ }+ node = node.nextSibling;+ node.parentNode.removeChild(node.previousSibling);+ }+ str += "</m:math>";+ newnode = document.createElement("span");+ node.parentNode.replaceChild(newnode,node);+ newnode.innerHTML = str;+ }+}++if (document.createElementNS==null) {+ document.write("<object id=\"mathplayer\"\+ classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>");+ document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>");+}+if(typeof window.addEventListener != 'undefined'){+ window.addEventListener('load', convert, false);+}+if(typeof window.attachEvent != 'undefined') {+ window.attachEvent('onload', convert);+}
@@ -0,0 +1,585 @@+<!DOCTYPE html>++<meta charset="utf-8">+<title>The Title Of Your Presentation</title>++<!-- Your Slides -->+<!-- One section is one slide -->++<section>+ <!-- This is the first slide -->+ <h1>My Presentation</h1>+ <footer>by John Doe</footer>+</section>++<section>+ <p>Some random text: But I've never been to the moon! You can see how I lived before I met you. Also Zoidberg.+ I could if you hadn't turned on the light and shut off my stereo.</p>+</section>++<section>+ <h3>An incremental list</h3>+ <ul class="incremental">+ <li>Item 1+ <li>Item 2+ <li>Item 3+ </ul>+ <details>Some notes. They are only visible using onstage shell.</details>+</section>++<section>+ <q>+ Who's brave enough to fly into something we all keep calling a death sphere?+ </q>+</section>++<section>+ <h2>Part two</h2>+</section>++<section>+ <figure> <!-- Figures are used to display images and videos fullpage -->+ <img src="http://placekitten.com/g/800/600">+ <figcaption>An image</figcaption>+ </figure>+ <details>Kittens are so cute!</details>+</section>++<section>+ <figure> <!-- Videos are automatically played -->+ <video src="http://videos-cdn.mozilla.net/brand/Mozilla_Firefox_Manifesto_v0.2_640.webm" poster="http://www.mozilla.org/images/about/poster.jpg"></video>+ <figcaption>A video</figcaption>+ </figure>+</section>++<section>+ <h2>End!</h2>+</section>++<!-- Your Style -->+<!-- Define the style of your presentation -->++<!-- Maybe a font from http://www.google.com/webfonts ? -->+<link href='http://fonts.googleapis.com/css?family=Oswald' rel='stylesheet'>++<style>+ html { background-color: black; }+ body { background-color: white; border-radius: 12px}+ /* A section is a slide. It's size is 800x600, and this will never change */+ section {+ /* The font from Google */+ font-family: 'Oswald', arial, serif;+ font-size: 30px;+ }+ h1, h2 {+ margin-top: 200px;+ text-align: center;+ font-size: 80px;+ }+ h3 {+ margin: 100px 0 50px 100px;+ }++ ul {+ margin: 50px 200px;+ }++ p {+ margin: 75px;+ font-size: 50px;+ }++ q {+ display: block;+ width: 100%;+ height: 100%;+ background-color: black;+ color: white;+ font-size: 60px;+ padding: 50px;+ }++ /* Figures are displayed full-page, with the caption+ on top of the image/video */+ figure {+ background-color: black;+ }+ figcaption {+ margin: 70px;+ font-size: 50px;+ }++ footer {+ position: absolute;+ bottom: 0;+ width: 100%;+ padding: 40px;+ text-align: right;+ background-color: #F3F4F8;+ border-top: 1px solid #CCC;+ }++ /* Transition effect */+ /* Feel free to change the transition effect for original+ animations. See here:+ https://developer.mozilla.org/en/CSS/CSS_transitions+ How to use CSS3 Transitions: */+ section {+ -moz-transition: left 400ms linear 0s;+ -webkit-transition: left 400ms linear 0s;+ -ms-transition: left 400ms linear 0s;+ transition: left 400ms linear 0s;+ }++ /* Before */+ section { left: -150%; }+ /* Now */+ section[aria-selected] { left: 0; }+ /* After */+ section[aria-selected] ~ section { left: +150%; }++ /* Incremental elements */++ /* By default, visible */+ .incremental > * { opacity: 1; }++ /* The current item */+ .incremental > *[aria-selected] { opacity: 1; }++ /* The items to-be-selected */+ .incremental > *[aria-selected] ~ * { opacity: 0; }++ /* The progressbar, at the bottom of the slides, show the global+ progress of the presentation. */+ #progress-bar {+ height: 2px;+ background: #AAA;+ }+</style>++<!-- {{{{ dzslides core+#+#+# __ __ __ . __ ___ __+# | \ / /__` | | | \ |__ /__`+# |__/ /_ .__/ |___ | |__/ |___ .__/ core :€+#+#+# The following block of code is not supposed to be edited.+# But if you want to change the behavior of these slides,+# feel free to hack it!+#+-->++<div id="progress-bar"></div>++<!-- Default Style -->+<style>+ * { margin: 0; padding: 0; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }+ details { display: none; }+ body {+ width: 800px; height: 600px;+ margin-left: -400px; margin-top: -300px;+ position: absolute; top: 50%; left: 50%;+ overflow: hidden;+ }+ section {+ position: absolute;+ pointer-events: none;+ width: 100%; height: 100%;+ }+ section[aria-selected] { pointer-events: auto; }+ html { overflow: hidden; }+ body { display: none; }+ body.loaded { display: block; }+ .incremental {visibility: hidden; }+ .incremental[active] {visibility: visible; }+ #progress-bar{+ bottom: 0;+ position: absolute;+ -moz-transition: width 400ms linear 0s;+ -webkit-transition: width 400ms linear 0s;+ -ms-transition: width 400ms linear 0s;+ transition: width 400ms linear 0s;+ }+ figure {+ width: 100%;+ height: 100%;+ }+ figure > * {+ position: absolute;+ }+ figure > img, figure > video {+ width: 100%; height: 100%;+ }+</style>++<script>+ var Dz = {+ remoteWindows: [],+ idx: -1,+ step: 0,+ slides: null,+ progressBar : null,+ params: {+ autoplay: "1"+ }+ };++ Dz.init = function() {+ document.body.className = "loaded";+ this.slides = $$("body > section");+ this.progressBar = $("#progress-bar");+ this.setupParams();+ this.onhashchange();+ this.setupTouchEvents();+ this.onresize();+ }+ + Dz.setupParams = function() {+ var p = window.location.search.substr(1).split('&');+ p.forEach(function(e, i, a) {+ var keyVal = e.split('=');+ Dz.params[keyVal[0]] = decodeURIComponent(keyVal[1]);+ });+ // Specific params handling+ if (!+this.params.autoplay)+ $$.forEach($$("video"), function(v){ v.controls = true });+ }++ Dz.onkeydown = function(aEvent) {+ // Don't intercept keyboard shortcuts+ if (aEvent.altKey+ || aEvent.ctrlKey+ || aEvent.metaKey+ || aEvent.shiftKey) {+ return;+ }+ if ( aEvent.keyCode == 37 // left arrow+ || aEvent.keyCode == 38 // up arrow+ || aEvent.keyCode == 33 // page up+ ) {+ aEvent.preventDefault();+ this.back();+ }+ if ( aEvent.keyCode == 39 // right arrow+ || aEvent.keyCode == 40 // down arrow+ || aEvent.keyCode == 34 // page down+ ) {+ aEvent.preventDefault();+ this.forward();+ }+ if (aEvent.keyCode == 35) { // end+ aEvent.preventDefault();+ this.goEnd();+ }+ if (aEvent.keyCode == 36) { // home+ aEvent.preventDefault();+ this.goStart();+ }+ if (aEvent.keyCode == 32) { // space+ aEvent.preventDefault();+ this.toggleContent();+ }+ if (aEvent.keyCode == 70) { // f+ aEvent.preventDefault();+ this.goFullscreen();+ }+ }++ /* Touch Events */++ Dz.setupTouchEvents = function() {+ var orgX, newX;+ var tracking = false;++ var db = document.body;+ db.addEventListener("touchstart", start.bind(this), false);+ db.addEventListener("touchmove", move.bind(this), false);++ function start(aEvent) {+ aEvent.preventDefault();+ tracking = true;+ orgX = aEvent.changedTouches[0].pageX;+ }++ function move(aEvent) {+ if (!tracking) return;+ newX = aEvent.changedTouches[0].pageX;+ if (orgX - newX > 100) {+ tracking = false;+ this.forward();+ } else {+ if (orgX - newX < -100) {+ tracking = false;+ this.back();+ }+ }+ }+ }++ /* Adapt the size of the slides to the window */++ Dz.onresize = function() {+ var db = document.body;+ var sx = db.clientWidth / window.innerWidth;+ var sy = db.clientHeight / window.innerHeight;+ var transform = "scale(" + (1/Math.max(sx, sy)) + ")";++ db.style.MozTransform = transform;+ db.style.WebkitTransform = transform;+ db.style.OTransform = transform;+ db.style.msTransform = transform;+ db.style.transform = transform;+ }+++ Dz.getDetails = function(aIdx) {+ var s = $("section:nth-of-type(" + aIdx + ")");+ var d = s.$("details");+ return d ? d.innerHTML : "";+ }++ Dz.onmessage = function(aEvent) {+ var argv = aEvent.data.split(" "), argc = argv.length;+ argv.forEach(function(e, i, a) { a[i] = decodeURIComponent(e) });+ var win = aEvent.source;+ if (argv[0] === "REGISTER" && argc === 1) {+ this.remoteWindows.push(win);+ this.postMsg(win, "REGISTERED", document.title, this.slides.length);+ this.postMsg(win, "CURSOR", this.idx + "." + this.step);+ return;+ }+ if (argv[0] === "BACK" && argc === 1)+ this.back();+ if (argv[0] === "FORWARD" && argc === 1)+ this.forward();+ if (argv[0] === "START" && argc === 1)+ this.goStart();+ if (argv[0] === "END" && argc === 1)+ this.goEnd();+ if (argv[0] === "TOGGLE_CONTENT" && argc === 1)+ this.toggleContent();+ if (argv[0] === "SET_CURSOR" && argc === 2)+ window.location.hash = "#" + argv[1];+ if (argv[0] === "GET_CURSOR" && argc === 1)+ this.postMsg(win, "CURSOR", this.idx + "." + this.step);+ if (argv[0] === "GET_NOTES" && argc === 1)+ this.postMsg(win, "NOTES", this.getDetails(this.idx));+ }++ Dz.toggleContent = function() {+ // If a Video is present in this new slide, play it.+ // If a Video is present in the previous slide, stop it.+ var s = $("section[aria-selected]");+ if (s) {+ var video = s.$("video");+ if (video) {+ if (video.ended || video.paused) {+ video.play();+ } else {+ video.pause();+ }+ }+ }+ }++ Dz.setCursor = function(aIdx, aStep) {+ // If the user change the slide number in the URL bar, jump+ // to this slide.+ aStep = (aStep != 0 && typeof aStep !== "undefined") ? "." + aStep : ".0";+ window.location.hash = "#" + aIdx + aStep;+ }++ Dz.onhashchange = function() {+ var cursor = window.location.hash.split("#"),+ newidx = 1,+ newstep = 0;+ if (cursor.length == 2) {+ newidx = ~~cursor[1].split(".")[0];+ newstep = ~~cursor[1].split(".")[1];+ if (newstep > Dz.slides[newidx - 1].$$('.incremental > *').length) {+ newstep = 0;+ newidx++;+ }+ }+ this.setProgress(newidx, newstep);+ if (newidx != this.idx) {+ this.setSlide(newidx);+ }+ if (newstep != this.step) {+ this.setIncremental(newstep);+ }+ for (var i = 0; i < this.remoteWindows.length; i++) {+ this.postMsg(this.remoteWindows[i], "CURSOR", this.idx + "." + this.step);+ }+ }++ Dz.back = function() {+ if (this.idx == 1 && this.step == 0) {+ return;+ }+ if (this.step == 0) {+ this.setCursor(this.idx - 1,+ this.slides[this.idx - 2].$$('.incremental > *').length);+ } else {+ this.setCursor(this.idx, this.step - 1);+ }+ }++ Dz.forward = function() {+ if (this.idx >= this.slides.length &&+ this.step >= this.slides[this.idx - 1].$$('.incremental > *').length) {+ return;+ }+ if (this.step >= this.slides[this.idx - 1].$$('.incremental > *').length) {+ this.setCursor(this.idx + 1, 0);+ } else {+ this.setCursor(this.idx, this.step + 1);+ }+ }++ Dz.goStart = function() {+ this.setCursor(1, 0);+ }++ Dz.goEnd = function() {+ var lastIdx = this.slides.length;+ var lastStep = this.slides[lastIdx - 1].$$('.incremental > *').length;+ this.setCursor(lastIdx, lastStep);+ }++ Dz.setSlide = function(aIdx) {+ this.idx = aIdx;+ var old = $("section[aria-selected]");+ var next = $("section:nth-of-type("+ this.idx +")");+ if (old) {+ old.removeAttribute("aria-selected");+ var video = old.$("video");+ if (video) {+ video.pause();+ }+ }+ if (next) {+ next.setAttribute("aria-selected", "true");+ var video = next.$("video");+ if (video && !!+this.params.autoplay) {+ video.play();+ }+ } else {+ // That should not happen+ this.idx = -1;+ // console.warn("Slide doesn't exist.");+ }+ }++ Dz.setIncremental = function(aStep) {+ this.step = aStep;+ var old = this.slides[this.idx - 1].$('.incremental > *[aria-selected]');+ if (old) {+ old.removeAttribute('aria-selected');+ }+ var incrementals = $$('.incremental');+ if (this.step <= 0) {+ $$.forEach(incrementals, function(aNode) {+ aNode.removeAttribute('active');+ });+ return;+ }+ var next = this.slides[this.idx - 1].$$('.incremental > *')[this.step - 1];+ if (next) {+ next.setAttribute('aria-selected', true);+ next.parentNode.setAttribute('active', true);+ var found = false;+ $$.forEach(incrementals, function(aNode) {+ if (aNode != next.parentNode)+ if (found)+ aNode.removeAttribute('active');+ else+ aNode.setAttribute('active', true);+ else+ found = true;+ });+ } else {+ setCursor(this.idx, 0);+ }+ return next;+ }++ Dz.goFullscreen = function() {+ var html = $('html'),+ requestFullscreen = html.requestFullscreen || html.requestFullScreen || html.mozRequestFullScreen || html.webkitRequestFullScreen;+ if (requestFullscreen) {+ requestFullscreen.apply(html);+ }+ }+ + Dz.setProgress = function(aIdx, aStep) {+ var slide = $("section:nth-of-type("+ aIdx +")");+ if (!slide)+ return;+ var steps = slide.$$('.incremental > *').length + 1,+ slideSize = 100 / (this.slides.length - 1),+ stepSize = slideSize / steps;+ this.progressBar.style.width = ((aIdx - 1) * slideSize + aStep * stepSize) + '%';+ }+ + Dz.postMsg = function(aWin, aMsg) { // [arg0, [arg1...]]+ aMsg = [aMsg];+ for (var i = 2; i < arguments.length; i++)+ aMsg.push(encodeURIComponent(arguments[i]));+ aWin.postMessage(aMsg.join(" "), "*");+ }+ + function init() {+ Dz.init();+ window.onkeydown = Dz.onkeydown.bind(Dz);+ window.onresize = Dz.onresize.bind(Dz);+ window.onhashchange = Dz.onhashchange.bind(Dz);+ window.onmessage = Dz.onmessage.bind(Dz);+ }++ window.onload = init;+</script>+++<script> // Helpers+ if (!Function.prototype.bind) {+ Function.prototype.bind = function (oThis) {++ // closest thing possible to the ECMAScript 5 internal IsCallable+ // function + if (typeof this !== "function")+ throw new TypeError(+ "Function.prototype.bind - what is trying to be fBound is not callable"+ );++ var aArgs = Array.prototype.slice.call(arguments, 1),+ fToBind = this,+ fNOP = function () {},+ fBound = function () {+ return fToBind.apply( this instanceof fNOP ? this : oThis || window,+ aArgs.concat(Array.prototype.slice.call(arguments)));+ };++ fNOP.prototype = this.prototype;+ fBound.prototype = new fNOP();++ return fBound;+ };+ }++ var $ = (HTMLElement.prototype.$ = function(aQuery) {+ return this.querySelector(aQuery);+ }).bind(document);++ var $$ = (HTMLElement.prototype.$$ = function(aQuery) {+ return this.querySelectorAll(aQuery);+ }).bind(document);++ $$.forEach = function(nodeList, fun) {+ Array.prototype.forEach.call(nodeList, fun);+ }++</script>+<!-- vim: set fdm=marker: }}} -->
binary file changed (absent → 8619 bytes)
@@ -0,0 +1,314 @@+-- This is a sample custom writer for pandoc. It produces output+-- that is very similar to that of pandoc's HTML writer.+-- There is one new feature: code blocks marked with class 'dot'+-- are piped through graphviz and images are included in the HTML+-- output using 'data:' URLs.+--+-- Invoke with: pandoc -t sample.lua+--+-- Note: you need not have lua installed on your system to use this+-- custom writer. However, if you do have lua installed, you can+-- use it to test changes to the script. 'lua sample.lua' will+-- produce informative error messages if your code contains+-- syntax errors.++-- Character escaping+local function escape(s, in_attribute)+ return s:gsub("[<>&\"']",+ function(x)+ if x == '<' then+ return '<'+ elseif x == '>' then+ return '>'+ elseif x == '&' then+ return '&'+ elseif x == '"' then+ return '"'+ elseif x == "'" then+ return '''+ else+ return x+ end+ end)+end++-- Helper function to convert an attributes table into+-- a string that can be put into HTML tags.+local function attributes(attr)+ local attr_table = {}+ for x,y in pairs(attr) do+ if y and y ~= "" then+ table.insert(attr_table, ' ' .. x .. '="' .. escape(y,true) .. '"')+ end+ end+ return table.concat(attr_table)+end++-- Run cmd on a temporary file containing inp and return result.+local function pipe(cmd, inp)+ local tmp = os.tmpname()+ local tmph = io.open(tmp, "w")+ tmph:write(inp)+ tmph:close()+ local outh = io.popen(cmd .. " " .. tmp,"r")+ local result = outh:read("*all")+ outh:close()+ os.remove(tmp)+ return result+end++-- Table to store footnotes, so they can be included at the end.+local notes = {}++-- Blocksep is used to separate block elements.+function Blocksep()+ return "\n\n"+end++-- This function is called once for the whole document. Parameters:+-- body is a string, metadata is a table, variables is a table.+-- This gives you a fragment. You could use the metadata table to+-- fill variables in a custom lua template. Or, pass `--template=...`+-- to pandoc, and pandoc will add do the template processing as+-- usual.+function Doc(body, metadata, variables)+ local buffer = {}+ local function add(s)+ table.insert(buffer, s)+ end+ add(body)+ if #notes > 0 then+ add('<ol class="footnotes">')+ for _,note in pairs(notes) do+ add(note)+ end+ add('</ol>')+ end+ return table.concat(buffer,'\n')+end++-- The functions that follow render corresponding pandoc elements.+-- s is always a string, attr is always a table of attributes, and+-- items is always an array of strings (the items in a list).+-- Comments indicate the types of other variables.++function Str(s)+ return escape(s)+end++function Space()+ return " "+end++function LineBreak()+ return "<br/>"+end++function Emph(s)+ return "<em>" .. s .. "</em>"+end++function Strong(s)+ return "<strong>" .. s .. "</strong>"+end++function Subscript(s)+ return "<sub>" .. s .. "</sub>"+end++function Superscript(s)+ return "<sup>" .. s .. "</sup>"+end++function SmallCaps(s)+ return '<span style="font-variant: small-caps;">' .. s .. '</span>'+end++function Strikeout(s)+ return '<del>' .. s .. '</del>'+end++function Link(s, src, tit)+ return "<a href='" .. escape(src,true) .. "' title='" ..+ escape(tit,true) .. "'>" .. s .. "</a>"+end++function Image(s, src, tit)+ return "<img src='" .. escape(src,true) .. "' title='" ..+ escape(tit,true) .. "'/>"+end++function Code(s, attr)+ return "<code" .. attributes(attr) .. ">" .. escape(s) .. "</code>"+end++function InlineMath(s)+ return "\\(" .. escape(s) .. "\\)"+end++function DisplayMath(s)+ return "\\[" .. escape(s) .. "\\]"+end++function Note(s)+ local num = #notes + 1+ -- insert the back reference right before the final closing tag.+ s = string.gsub(s,+ '(.*)</', '%1 <a href="#fnref' .. num .. '">↩</a></')+ -- add a list item with the note to the note table.+ table.insert(notes, '<li id="fn' .. num .. '">' .. s .. '</li>')+ -- return the footnote reference, linked to the note.+ return '<a id="fnref' .. num .. '" href="#fn' .. num ..+ '"><sup>' .. num .. '</sup></a>'+end++function Span(s, attr)+ return "<span" .. attributes(attr) .. ">" .. s .. "</span>"+end++function Cite(s, cs)+ local ids = {}+ for _,cit in ipairs(cs) do+ table.insert(ids, cit.citationId)+ end+ return "<span class=\"cite\" data-citation-ids=\"" .. table.concat(ids, ",") ..+ "\">" .. s .. "</span>"+end++function Plain(s)+ return s+end++function Para(s)+ return "<p>" .. s .. "</p>"+end++-- lev is an integer, the header level.+function Header(lev, s, attr)+ return "<h" .. lev .. attributes(attr) .. ">" .. s .. "</h" .. lev .. ">"+end++function BlockQuote(s)+ return "<blockquote>\n" .. s .. "\n</blockquote>"+end++function HorizontalRule()+ return "<hr/>"+end++function CodeBlock(s, attr)+ -- If code block has class 'dot', pipe the contents through dot+ -- and base64, and include the base64-encoded png as a data: URL.+ if attr.class and string.match(' ' .. attr.class .. ' ',' dot ') then+ local png = pipe("base64", pipe("dot -Tpng", s))+ return '<img src="data:image/png;base64,' .. png .. '"/>'+ -- otherwise treat as code (one could pipe through a highlighter)+ else+ return "<pre><code" .. attributes(attr) .. ">" .. escape(s) ..+ "</code></pre>"+ end+end++function BulletList(items)+ local buffer = {}+ for _, item in pairs(items) do+ table.insert(buffer, "<li>" .. item .. "</li>")+ end+ return "<ul>\n" .. table.concat(buffer, "\n") .. "\n</ul>"+end++function OrderedList(items)+ local buffer = {}+ for _, item in pairs(items) do+ table.insert(buffer, "<li>" .. item .. "</li>")+ end+ return "<ol>\n" .. table.concat(buffer, "\n") .. "\n</ol>"+end++-- Revisit association list STackValue instance.+function DefinitionList(items)+ local buffer = {}+ for _,item in pairs(items) do+ for k, v in pairs(item) do+ table.insert(buffer,"<dt>" .. k .. "</dt>\n<dd>" ..+ table.concat(v,"</dd>\n<dd>") .. "</dd>")+ end+ end+ return "<dl>\n" .. table.concat(buffer, "\n") .. "\n</dl>"+end++-- Convert pandoc alignment to something HTML can use.+-- align is AlignLeft, AlignRight, AlignCenter, or AlignDefault.+function html_align(align)+ if align == 'AlignLeft' then+ return 'left'+ elseif align == 'AlignRight' then+ return 'right'+ elseif align == 'AlignCenter' then+ return 'center'+ else+ return 'left'+ end+end++-- Caption is a string, aligns is an array of strings,+-- widths is an array of floats, headers is an array of+-- strings, rows is an array of arrays of strings.+function Table(caption, aligns, widths, headers, rows)+ local buffer = {}+ local function add(s)+ table.insert(buffer, s)+ end+ add("<table>")+ if caption ~= "" then+ add("<caption>" .. caption .. "</caption>")+ end+ if widths and widths[1] ~= 0 then+ for _, w in pairs(widths) do+ add('<col width="' .. string.format("%d%%", w * 100) .. '" />')+ end+ end+ local header_row = {}+ local empty_header = true+ for i, h in pairs(headers) do+ local align = html_align(aligns[i])+ table.insert(header_row,'<th align="' .. align .. '">' .. h .. '</th>')+ empty_header = empty_header and h == ""+ end+ if empty_header then+ head = ""+ else+ add('<tr class="header">')+ for _,h in pairs(header_row) do+ add(h)+ end+ add('</tr>')+ end+ local class = "even"+ for _, row in pairs(rows) do+ class = (class == "even" and "odd") or "even"+ add('<tr class="' .. class .. '">')+ for i,c in pairs(row) do+ add('<td align="' .. html_align(aligns[i]) .. '">' .. c .. '</td>')+ end+ add('</tr>')+ end+ add('</table')+ return table.concat(buffer,'\n')+end++function Div(s, attr)+ return "<div" .. attributes(attr) .. ">\n" .. s .. "</div>"+end++-- The following code will produce runtime warnings when you haven't defined+-- all of the functions you need for the custom writer, so it's useful+-- to include when you're working on a writer.+local meta = {}+meta.__index =+ function(_, key)+ io.stderr:write(string.format("WARNING: Undefined function '%s'\n",key))+ return function() return "" end+ end+setmetatable(_G, meta)+
@@ -0,0 +1,26 @@+$if(titleblock)$+$title$+$for(author)$+:author: $author$+$endfor$+$if(date)$+:date: $date$+$endif$+$if(toc)$+:toc:+$endif$++$endif$+$for(header-includes)$+$header-includes$++$endfor$+$for(include-before)$+$include-before$++$endfor$+$body$+$for(include-after)$++$include-after$+$endfor$
@@ -0,0 +1,177 @@+\documentclass[$if(fontsize)$$fontsize$,$endif$$if(handout)$handout,$endif$$if(beamer)$ignorenonframetext,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$}+$if(theme)$+\usetheme{$theme$}+$endif$+$if(colortheme)$+\usecolortheme{$colortheme$}+$endif$+$if(fonttheme)$+\usefonttheme{$fonttheme$}+$endif$+\setbeamertemplate{caption}[numbered]+\setbeamertemplate{caption label separator}{:}+\setbeamercolor{caption name}{fg=normal text.fg}+\usepackage{amssymb,amsmath}+\usepackage{ifxetex,ifluatex}+\usepackage{fixltx2e} % provides \textsubscript+\usepackage{lmodern}+\ifxetex+ \usepackage{fontspec,xltxtra,xunicode}+ \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}+ \newcommand{\euro}{€}+\else+ \ifluatex+ \usepackage{fontspec}+ \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}+ \newcommand{\euro}{€}+ \else+ \usepackage[T1]{fontenc}+ \usepackage[utf8]{inputenc}+ $if(euro)$+ \usepackage{eurosym}+ $endif$+ \fi+\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(natbib)$+\usepackage{natbib}+\bibliographystyle{plainnat}+$endif$+$if(biblatex)$+\usepackage{biblatex}+$if(biblio-files)$+\bibliography{$biblio-files$}+$endif$+$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}+\usepackage{caption}+% These lines are needed to make table captions work with longtable:+\makeatletter+\def\fnum@table{\tablename~\thetable}+\makeatother+$endif$+$if(url)$+\usepackage{url}+$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>\textheight0.8\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$++% Comment these out if you don't want a slide with just the+% part/section/subsection/subsubsection title:+\AtBeginPart{+ \let\insertpartnumber\relax+ \let\partname\relax+ \frame{\partpage}+}+\AtBeginSection{+ \let\insertsectionnumber\relax+ \let\sectionname\relax+ \frame{\sectionpage}+}+\AtBeginSubsection{+ \let\insertsubsectionnumber\relax+ \let\subsectionname\relax+ \frame{\subsectionpage}+}++$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)$+$else$+\setcounter{secnumdepth}{0}+$endif$+$if(verbatim-in-note)$+\VerbatimFootnotes % allows verbatim text in footnotes+$endif$+$if(lang)$+\usepackage[$lang$]{babel}+$endif$+$for(header-includes)$+$header-includes$+$endfor$++$if(title)$+\title{$title$}+$endif$+$if(subtitle)$+\subtitle{$subtitle$}+$endif$+$if(author)$+\author{$for(author)$$author$$sep$ \and $endfor$}+$endif$+\date{$date$}++\begin{document}+$if(title)$+\frame{\titlepage}+$endif$++$for(include-before)$+$include-before$++$endfor$+$if(toc)$+\begin{frame}+\tableofcontents[hideallsubsections]+\end{frame}++$endif$+$body$++$if(natbib)$+$if(biblio-files)$+$if(biblio-title)$+$if(book-class)$+\renewcommand\bibname{$biblio-title$}+$else$+\renewcommand\refname{$biblio-title$}+$endif$+$endif$+\begin{frame}[allowframebreaks]{$biblio-title$}+\bibliography{$biblio-files$}+\end{frame}++$endif$+$endif$+$if(biblatex)$+\begin{frame}[allowframebreaks]{$biblio-title$}+\printbibliography[heading=none]+\end{frame}++$endif$+$for(include-after)$+$include-after$++$endfor$+\end{document}
@@ -0,0 +1,87 @@+\startmode[*mkii]+ \enableregime[utf-8] + \setupcolors[state=start]+\stopmode+$if(mainlang)$+\mainlanguage[$mainlang$]+$endif$++% Enable hyperlinks+\setupinteraction[state=start, color=middleblue]++\setuppapersize [$if(papersize)$$papersize$$else$letter$endif$][$if(papersize)$$papersize$$else$letter$endif$]+\setuplayout [width=middle, backspace=1.5in, cutspace=1.5in,+ height=middle, topspace=0.75in, bottomspace=0.75in]++\setuppagenumbering[location={footer,center}]++\setupbodyfont[11pt]++\setupwhitespace[medium]++\setuphead[chapter] [style=\tfd]+\setuphead[section] [style=\tfc]+\setuphead[subsection] [style=\tfb]+\setuphead[subsubsection][style=\bf]++$if(number-sections)$+$else$+\setuphead[chapter, section, subsection, subsubsection][number=no]+$endif$++\definedescription+ [description]+ [headstyle=bold, style=normal, location=hanging, width=broad, margin=1cm]++\setupitemize[autointro] % prevent orphan list intro+\setupitemize[indentnext=no]++\setupfloat[figure][default={here,nonumber}]+\setupfloat[table][default={here,nonumber}]++\setupthinrules[width=15em] % width of horizontal rules++\setupdelimitedtext+ [blockquote]+ [before={\blank[medium]},+ after={\blank[medium]},+ indentnext=no,+ ]++$if(toc)$+\setupcombinedlist[content][list={$placelist$}]++$endif$+$for(header-includes)$+$header-includes$+$endfor$++\starttext+$if(title)$+\startalignment[center]+ \blank[2*big]+ {\tfd $title$}+$if(author)$+ \blank[3*medium]+ {\tfa $for(author)$$author$$sep$\crlf $endfor$}+$endif$+$if(date)$+ \blank[2*medium]+ {\tfa $date$}+$endif$+ \blank[3*medium]+\stopalignment+$endif$+$for(include-before)$+$include-before$+$endfor$+$if(toc)$+\placecontent+$endif$++$body$++$for(include-after)$+$include-after$+$endfor$+\stoptext
@@ -0,0 +1,32 @@+<?xml version="1.0" encoding="utf-8" ?>+$if(mathml)$+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook EBNF Module V1.1CR1//EN"+ "http://www.oasis-open.org/docbook/xml/mathml/1.1CR1/dbmathml.dtd">+$else$+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">+$endif$+<article>+ <articleinfo>+ <title>$title$</title>+$if(author)$+ <authorgroup>+$for(author)$+ <author>+ $author$+ </author>+$endfor$+ </authorgroup>+$endif$+$if(date)$+ <date>$date$</date>+$endif$+ </articleinfo>+$for(include-before)$+$include-before$+$endfor$+$body$+$for(include-after)$+$include-after$+$endfor$+</article>
@@ -0,0 +1,13 @@+$for(include-before)$+$include-before$++$endfor$+$if(toc)$+__TOC__++$endif$+$body$+$for(include-after)$++$include-after$+$endfor$
@@ -0,0 +1,123 @@+<!DOCTYPE html>+<head>+<meta charset="utf-8">+$for(author-meta)$+ <meta name="author" content="$author-meta$" />+$endfor$+$if(date-meta)$+ <meta name="dcterms.date" content="$date-meta$" />+$endif$+ <title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>+ <style type="text/css">code{white-space: pre;}</style>+$if(highlighting-css)$+ <style type="text/css">+$highlighting-css$+ </style>+$endif$+$if(css)$+$for(css)$+ <link rel="stylesheet" href="$css$" $if(html5)$$else$type="text/css" $endif$/>+$endfor$+$else$+<style>+ html { background-color: black; }+ body { background-color: white; border-radius: 12px}+ /* A section is a slide. It's size is 800x600, and this will never change */+ section {+ font-family: Arial, serif;+ font-size: 20pt;+ }+ address, blockquote, dl, fieldset, form, h1, h2, h3, h4, h5, h6, hr, ol, p, pre, table, ul, dl { padding: 10px 20px 10px 20px; }+ h1, h2, h3 {+ text-align: center;+ margin: 10pt 10pt 20pt 10pt;+ }+ ul, ol {+ margin: 10px 10px 10px 50px;+ }+ section.titleslide h1 { margin-top: 200px; }+ h1.title { margin-top: 150px; }+ h1 { font-size: 180%; }+ h2 { font-size: 120%; }+ h3 { font-size: 100%; }+ q { quotes: "“" "”" "‘" "’"; }+ blockquote { font-style: italic }+ /* Figures are displayed full-page, with the caption on+ top of the image/video */+ figure {+ background-color: black;+ }+ figcaption {+ margin: 70px;+ }+ footer {+ position: absolute;+ bottom: 0;+ width: 100%;+ padding: 40px;+ text-align: right;+ background-color: #F3F4F8;+ border-top: 1px solid #CCC;+ }++ /* Transition effect */+ /* Feel free to change the transition effect for original+ animations. See here:+ https://developer.mozilla.org/en/CSS/CSS_transitions+ How to use CSS3 Transitions: */+ section {+ -moz-transition: left 400ms linear 0s;+ -webkit-transition: left 400ms linear 0s;+ -ms-transition: left 400ms linear 0s;+ transition: left 400ms linear 0s;+ }++ /* Before */+ section { left: -150%; }+ /* Now */+ section[aria-selected] { left: 0; }+ /* After */+ section[aria-selected] ~ section { left: +150%; }++ /* Incremental elements */++ /* By default, visible */+ .incremental > * { opacity: 1; }++ /* The current item */+ .incremental > *[aria-selected] { color: red; opacity: 1; }++ /* The items to-be-selected */+ .incremental > *[aria-selected] ~ * { opacity: 0.2; }+</style>+$endif$+$if(math)$+ $math$+$endif$+$for(header-includes)$+ $header-includes$+$endfor$+</head>+<body>+$if(title)$+<section class="title">+ <h1 class="title">$title$</h1>+$if(subtitle)$+ <h1 class="subtitle">$subtitle$</h1>+$endif$+$for(author)$+ <h2 class="author">$author$</h2>+$endfor$+ <h3 class="date">$date$</h3>+</section>+$endif$+$for(include-before)$+$include-before$+$endfor$+$body$+$for(include-after)$+$include-after$+$endfor$+$dzslides-core$+</body>+</html>
@@ -0,0 +1,50 @@+<?xml version="1.0" encoding="UTF-8"?>+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">+<html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ xml:lang="$lang$"$endif$>+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+ <title>$pagetitle$</title>+$if(highlighting-css)$+ <style type="text/css">+$highlighting-css$+ </style>+$endif$+$for(css)$+ <link rel="stylesheet" type="text/css" href="$css$" />+$endfor$+</head>+<body>+$if(titlepage)$+$for(title)$+$if(title.text)$+ <h1 class="$title.type$">$title.text$</h1>+$else$+ <h1 class="title">$title$</h1>+$endif$+$endfor$+$if(subtitle)$+ <h1 class="subtitle">$subtitle$</h1>+$endif$+$for(author)$+ <h2 class="author">$author$</h2>+$endfor$+$for(creator)$+ <h2 class="$creator.type$">$creator.text$</h2>+$endfor$+$if(publisher)$+ <p class="publisher">$publisher$</p>+$endif$+$if(date)$+ <p class="date">$date$</p>+$endif$+$if(rights)$+ <p class="rights">$rights$</p>+$endif$+$else$+$body$+$endif$+</body>+</html>+
@@ -0,0 +1,56 @@+<?xml version="1.0" encoding="UTF-8"?>+<!DOCTYPE html>+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"$if(lang)$ xml:lang="$lang$"$endif$>+<head>+ <meta charset="utf-8" />+ <meta name="generator" content="pandoc" />+ <title>$pagetitle$</title>+$if(quotes)$+ <style type="text/css">+ q { quotes: "“" "”" "‘" "’"; }+ </style>+$endif$+$if(highlighting-css)$+ <style type="text/css">+$highlighting-css$+ </style>+$endif$+$for(css)$+ <link rel="stylesheet" type="text/css" href="$css$" />+$endfor$+</head>+<body>+$if(titlepage)$+<section epub:type="titlepage">+$for(title)$+$if(title.type)$+ <h1 class="$title.type$">$title.text$</h1>+$else$+ <h1 class="title">$title$</h1>+$endif$+$endfor$+$if(subtitle)$+ <h1 class="subtitle">$subtitle$</h1>+$endif$+$for(author)$+ <h2 class="author">$author$</h2>+$endfor$+$for(creator)$+ <h2 class="$creator.type$">$creator.text$</h2>+$endfor$+$if(publisher)$+ <p class="publisher">$publisher$</p>+$endif$+$if(date)$+ <p class="date">$date$</p>+$endif$+$if(rights)$+ <p class="rights">$rights$</p>+$endif$+</section>+$else$+$body$+$endif$+</body>+</html>+
@@ -0,0 +1,1 @@+$body$
@@ -0,0 +1,61 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$>+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+$for(author-meta)$+ <meta name="author" content="$author-meta$" />+$endfor$+$if(date-meta)$+ <meta name="date" content="$date-meta$" />+$endif$+ <title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>+ <style type="text/css">code{white-space: pre;}</style>+$if(quotes)$+ <style type="text/css">q { quotes: "“" "”" "‘" "’"; }</style>+$endif$+$if(highlighting-css)$+ <style type="text/css">+$highlighting-css$+ </style>+$endif$+$for(css)$+ <link rel="stylesheet" href="$css$" $if(html5)$$else$type="text/css" $endif$/>+$endfor$+$if(math)$+ $math$+$endif$+$for(header-includes)$+ $header-includes$+$endfor$+</head>+<body>+$for(include-before)$+$include-before$+$endfor$+$if(title)$+<div id="$idprefix$header">+<h1 class="title">$title$</h1>+$if(subtitle)$+<h1 class="subtitle">$subtitle$</h1>+$endif$+$for(author)$+<h2 class="author">$author$</h2>+$endfor$+$if(date)$+<h3 class="date">$date$</h3>+$endif$+</div>+$endif$+$if(toc)$+<div id="$idprefix$TOC">+$toc$+</div>+$endif$+$body$+$for(include-after)$+$include-after$+$endfor$+</body>+</html>
@@ -0,0 +1,64 @@+<!DOCTYPE html>+<html$if(lang)$ lang="$lang$"$endif$>+<head>+ <meta charset="utf-8">+ <meta name="generator" content="pandoc">+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">+$for(author-meta)$+ <meta name="author" content="$author-meta$">+$endfor$+$if(date-meta)$+ <meta name="dcterms.date" content="$date-meta$">+$endif$+ <title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>+ <style type="text/css">code{white-space: pre;}</style>+ <!--[if lt IE 9]>+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>+ <![endif]-->+$if(quotes)$+ <style type="text/css">q { quotes: "“" "”" "‘" "’"; }</style>+$endif$+$if(highlighting-css)$+ <style type="text/css">+$highlighting-css$+ </style>+$endif$+$for(css)$+ <link rel="stylesheet" href="$css$">+$endfor$+$if(math)$+ $math$+$endif$+$for(header-includes)$+ $header-includes$+$endfor$+</head>+<body>+$for(include-before)$+$include-before$+$endfor$+$if(title)$+<header>+<h1 class="title">$title$</h1>+$if(subtitle)$+<h1 class="subtitle">$subtitle$</h1>+$endif$+$for(author)$+<h2 class="author">$author$</h2>+$endfor$+$if(date)$+<h3 class="date">$date$</h3>+$endif$+</header>+$endif$+$if(toc)$+<nav id="$idprefix$TOC">+$toc$+</nav>+$endif$+$body$+$for(include-after)$+$include-after$+$endfor$+</body>+</html>
@@ -0,0 +1,43 @@+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>+<?aid style="50" type="snippet" readerVersion="6.0" featureSet="513" product="8.0(370)" ?>+<?aid SnippetType="InCopyInterchange"?>+<Document DOMVersion="8.0" Self="pandoc_doc">+ <RootCharacterStyleGroup Self="pandoc_character_styles">+ <CharacterStyle Self="$$ID/NormalCharacterStyle" Name="Default" />+ $charStyles$ + </RootCharacterStyleGroup>+ <RootParagraphStyleGroup Self="pandoc_paragraph_styles">+ <ParagraphStyle Self="$$ID/NormalParagraphStyle" Name="$$ID/NormalParagraphStyle"+ SpaceBefore="6" SpaceAfter="6"> <!-- paragraph spacing -->+ <Properties>+ <TabList type="list">+ <ListItem type="record">+ <Alignment type="enumeration">LeftAlign</Alignment>+ <AlignmentCharacter type="string">.</AlignmentCharacter>+ <Leader type="string"></Leader>+ <Position type="unit">10</Position> <!-- first tab stop -->+ </ListItem>+ </TabList>+ </Properties>+ </ParagraphStyle>+ $parStyles$ + </RootParagraphStyleGroup>+ <RootTableStyleGroup Self="pandoc_table_styles">+ <TableStyle Self="TableStyle/Table" Name="Table" />+ </RootTableStyleGroup>+ <RootCellStyleGroup Self="pandoc_cell_styles">+ <CellStyle Self="CellStyle/Cell" AppliedParagraphStyle="ParagraphStyle/$$ID/[No paragraph style]" Name="Cell" />+ </RootCellStyleGroup>+ <Story Self="pandoc_story"+ TrackChanges="false"+ StoryTitle="$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$"+ AppliedTOCStyle="n"+ AppliedNamedGrid="n" >+ <StoryPreference OpticalMarginAlignment="true" OpticalMarginSize="12" />++<!-- body needs to be non-indented, otherwise code blocks are indented too far -->+$body$++ </Story>+ $hyperlinks$+</Document>
@@ -0,0 +1,196 @@+\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$lang$,$endif$$if(papersize)$$papersize$,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$}+$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}+\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts+}{}+$if(geometry)$+\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}+$endif$+$if(lang)$+\ifxetex+ \usepackage{polyglossia}+ \setmainlanguage{$mainlang$}+\else+ \usepackage[shorthands=off,$lang$]{babel}+\fi+$endif$+$if(natbib)$+\usepackage{natbib}+\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$}+$endif$+$if(biblatex)$+\usepackage{biblatex}+$if(biblio-files)$+\bibliography{$biblio-files$}+$endif$+$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+$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(title)$+\title{$title$$if(subtitle)$\\\vspace{0.5em}{\large $subtitle$}$endif$}+$endif$+$if(author)$+\author{$for(author)$$author$$sep$ \and $endfor$}+$endif$+\date{$date$}+$for(header-includes)$+$header-includes$+$endfor$++\begin{document}+$if(title)$+\maketitle+$endif$+$if(abstract)$+\begin{abstract}+$abstract$+\end{abstract}+$endif$++$for(include-before)$+$include-before$++$endfor$+$if(toc)$+{+\hypersetup{linkcolor=black}+\setcounter{tocdepth}{$toc-depth$}+\tableofcontents+}+$endif$+$if(lot)$+\listoftables+$endif$+$if(lof)$+\listoffigures+$endif$+$body$++$if(natbib)$+$if(biblio-files)$+$if(biblio-title)$+$if(book-class)$+\renewcommand\bibname{$biblio-title$}+$else$+\renewcommand\refname{$biblio-title$}+$endif$+$endif$+\bibliography{$biblio-files$}++$endif$+$endif$+$if(biblatex)$+\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$++$endif$+$for(include-after)$+$include-after$++$endfor$+\end{document}
@@ -0,0 +1,18 @@+$if(has-tables)$+.\"t+$endif$+.TH "$title$" "$section$" "$date$" "$footer$" "$header$"+$for(header-includes)$+$header-includes$+$endfor$+$for(include-before)$+$include-before$+$endfor$+$body$+$for(include-after)$+$include-after$+$endfor$+$if(author)$+.SH AUTHORS+$for(author)$$author$$sep$; $endfor$.+$endif$
@@ -0,0 +1,21 @@+$if(titleblock)$+$titleblock$++$endif$+$for(header-includes)$+$header-includes$++$endfor$+$for(include-before)$+$include-before$++$endfor$+$if(toc)$+$toc$++$endif$+$body$+$for(include-after)$++$include-after$+$endfor$
@@ -0,0 +1,13 @@+$for(include-before)$+$include-before$++$endfor$+$if(toc)$+__TOC__++$endif$+$body$+$for(include-after)$++$include-after$+$endfor$
@@ -0,0 +1,30 @@+<?xml version="1.0" encoding="utf-8" ?>+<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" office:version="1.2">+ <office:font-face-decls>+ <style:font-face style:name="Courier New" style:font-family-generic="modern" style:font-pitch="fixed" svg:font-family="'Courier New'" />+ </office:font-face-decls>+ $automatic-styles$+$for(header-includes)$+ $header-includes$+$endfor$+<office:body>+<office:text>+$if(title)$+<text:h text:style-name="Title">$title$</text:h>+$endif$+$for(author)$+<text:p text:style-name="Author">$author$</text:p>+$endfor$+$if(date)$+<text:p text:style-name="Date">$date$</text:p>+$endif$+$for(include-before)$+$include-before$+$endfor$+$body$+$for(include-after)$+$include-after$+$endfor$+</office:text>+</office:body>+</office:document-content>
@@ -0,0 +1,11 @@+<?xml version="1.0" encoding="UTF-8"?>+<opml version="2.0">+ <head>+ <title>$title$</title>+ <dateModified>$date$</dateModified>+ <ownerName>$for(author)$$author$$sep$; $endfor$</ownerName>+ </head>+ <body>+$body$+ </body>+</opml>
@@ -0,0 +1,24 @@+$if(title)$+#+TITLE: $title$++$endif$+$if(author)$+#+AUTHOR: $for(author)$$author$$sep$; $endfor$+$endif$+$if(date)$+#+DATE: $date$++$endif$+$for(header-includes)$+$header-includes$++$endfor$+$for(include-before)$+$include-before$++$endfor$+$body$+$for(include-after)$++$include-after$+$endfor$
@@ -0,0 +1,21 @@+$if(titleblock)$+$titleblock$++$endif$+$for(header-includes)$+$header-includes$++$endfor$+$for(include-before)$+$include-before$++$endfor$+$if(toc)$+$toc$++$endif$+$body$+$for(include-after)$++$include-after$+$endfor$
@@ -0,0 +1,108 @@+<!DOCTYPE html>+<html$if(lang)$ lang="$lang$"$endif$>+<head>+ <meta charset="utf-8">+ <meta name="generator" content="pandoc">+$for(author-meta)$+ <meta name="author" content="$author-meta$" />+$endfor$+$if(date-meta)$+ <meta name="dcterms.date" content="$date-meta$" />+$endif$+ <title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>+ <meta name="apple-mobile-web-app-capable" content="yes" />+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">+ <link rel="stylesheet" href="$revealjs-url$/css/reveal.min.css"/>+ <style type="text/css">code{white-space: pre;}</style>+$if(highlighting-css)$+ <style type="text/css">+$highlighting-css$+ </style>+$endif$+$if(css)$+$for(css)$+ <link rel="stylesheet" href="$css$"/>+$endfor$+$else$+ <link rel="stylesheet" href="$revealjs-url$/css/theme/simple.css" id="theme">+$endif$+ <!-- If the query includes 'print-pdf', include the PDF print sheet -->+ <script>+ if( window.location.search.match( /print-pdf/gi ) ) {+ var link = document.createElement( 'link' );+ link.rel = 'stylesheet';+ link.type = 'text/css';+ link.href = '$revealjs-url$/css/print/pdf.css';+ document.getElementsByTagName( 'head' )[0].appendChild( link );+ }+ </script>+ <!--[if lt IE 9]>+ <script src="$revealjs-url$/lib/js/html5shiv.js"></script>+ <![endif]-->+$if(math)$+ $math$+$endif$+$for(header-includes)$+ $header-includes$+$endfor$+</head>+<body>+$for(include-before)$+$include-before$+$endfor$+ <div class="reveal">+ <div class="slides">++$if(title)$+<section>+ <h1 class="title">$title$</h1>+$if(subtitle)$+ <h1 class="subtitle">$subtitle$</h1>+$endif$+$for(author)$+ <h2 class="author">$author$</h2>+$endfor$+ <h3 class="date">$date$</h3>+</section>+$endif$+$if(toc)$+<section id="$idprefix$TOC">+$toc$+</section>+$endif$++$body$+ </div>+ </div>+++ <script src="$revealjs-url$/lib/js/head.min.js"></script>+ <script src="$revealjs-url$/js/reveal.min.js"></script>++ <script>++ // Full list of configuration options available here:+ // https://github.com/hakimel/reveal.js#configuration+ Reveal.initialize({+ controls: true,+ progress: true,+ history: true,+ center: true,+ theme: $if(theme)$'$theme$'$else$Reveal.getQueryHash().theme$endif$, // available themes are in /css/theme+ transition: $if(transition)$'$transition$'$else$Reveal.getQueryHash().transition || 'default'$endif$, // default/cube/page/concave/zoom/linear/fade/none++ // Optional libraries used to extend on reveal.js+ dependencies: [+ { src: '$revealjs-url$/lib/js/classList.js', condition: function() { return !document.body.classList; } },+ { src: '$revealjs-url$/plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },+ { src: '$revealjs-url$/plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },+// { src: '$revealjs-url$/plugin/search/search.js', async: true, condition: function() { return !!document.body.classList; }, }+// { src: '$revealjs-url$/plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }+]});+ </script>+ $for(include-after)$+ $include-after$+ $endfor$+ </body>+</html>
@@ -0,0 +1,42 @@+$if(title)$+$title$++$endif$+$for(author)$+:Author: $author$+$endfor$+$if(date)$+:Date: $date$+$endif$+$if(author)$++$else$+$if(date)$++$endif$+$endif$+$if(math)$+.. role:: math(raw)+ :format: html latex+..++$endif$+$for(include-before)$+$include-before$++$endfor$+$if(toc)$+.. contents::+ :depth: $toc-depth$+..++$endif$+$for(header-includes)$+$header-includes$++$endfor$+$body$+$for(include-after)$++$include-after$+$endfor$
@@ -0,0 +1,30 @@+{\rtf1\ansi\deff0{\fonttbl{\f0 \fswiss Helvetica;}{\f1 Courier;}}+{\colortbl;\red255\green0\blue0;\red0\green0\blue255;}+\widowctrl\hyphauto+$for(header-includes)$+$header-includes$+$endfor$++$if(title)$+{\pard \qc \f0 \sa180 \li0 \fi0 \b \fs36 $title$\par}+$endif$+$for(author)$+{\pard \qc \f0 \sa180 \li0 \fi0 $author$\par}+$endfor$+$if(date)$+{\pard \qc \f0 \sa180 \li0 \fi0 $date$\par}+$endif$+$if(spacer)$+{\pard \ql \f0 \sa180 \li0 \fi0 \par}+$endif$+$if(toc)$+$toc$+$endif$+$for(include-before)$+$include-before$+$endfor$+$body$+$for(include-after)$+$include-after$+$endfor$+}
@@ -0,0 +1,70 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html xmlns="http://www.w3.org/1999/xhtml">+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+$for(author-meta)$+ <meta name="author" content="$author-meta$" />+$endfor$+$if(date-meta)$+ <meta name="date" content="$date-meta$" />+$endif$+ <title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>+ <style type="text/css">code{white-space: pre;}</style>+ <!-- configuration parameters -->+ <meta name="defaultView" content="slideshow" />+ <meta name="controlVis" content="hidden" />+$if(highlighting-css)$+ <style type="text/css">+$highlighting-css$+ </style>+$endif$+$for(css)$+ <link rel="stylesheet" href="$css$" type="text/css" />+$endfor$+ <!-- style sheet links -->+ <link rel="stylesheet" href="$s5-url$/slides.css" type="text/css" media="projection" id="slideProj" />+ <link rel="stylesheet" href="$s5-url$/outline.css" type="text/css" media="screen" id="outlineStyle" />+ <link rel="stylesheet" href="$s5-url$/print.css" type="text/css" media="print" id="slidePrint" />+ <link rel="stylesheet" href="$s5-url$/opera.css" type="text/css" media="projection" id="operaFix" />+ <!-- S5 JS -->+ <script src="$s5-url$/slides.js" type="text/javascript"></script>+$if(math)$+ $math$+$endif$+$for(header-includes)$+ $header-includes$+$endfor$+</head>+<body>+$for(include-before)$+$include-before$+$endfor$+<div class="layout">+<div id="controls"></div>+<div id="currentSlide"></div>+<div id="header"></div>+<div id="footer">+ <h1>$date$</h1>+ <h2>$title$</h2>+</div>+</div>+<div class="presentation">+$if(title)$+<div class="titleslide slide">+ <h1>$title$</h1>+$if(subtitle)$+ <h1 class="subtitle">$subtitle$</h1>+$endif$+ <h2>$for(author)$$author$$sep$<br/>$endfor$</h2>+ <h3>$date$</h3>+</div>+$endif$+$body$+$for(include-after)$+$include-after$+$endfor$+</div>+</body>+</html>
@@ -0,0 +1,79 @@+<?xml version="1.0" encoding="utf-8"?>+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">+<html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$>+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+$for(author-meta)$+ <meta name="author" content="$author-meta$" />+$endfor$+$if(date-meta)$+ <meta name="date" content="$date-meta$" />+$endif$+ <title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>+ <style type="text/css">code{white-space: pre;}</style>+$if(highlighting-css)$+ <style type="text/css">+$highlighting-css$+ </style>+$endif$+ <link rel="stylesheet" type="text/css" media="screen, projection, print"+ href="$slideous-url$/slideous.css" />+$for(css)$+ <link rel="stylesheet" type="text/css" media="screen, projection, print"+ href="$css$" />+$endfor$+$if(math)$+ $math$+$endif$+$for(header-includes)$+ $header-includes$+$endfor$+ <script src="$slideous-url$/slideous.js"+ charset="utf-8" type="text/javascript"></script>+$if(duration)$+ <meta name="duration" content="$duration$" />+$endif$+</head>+<body>+$for(include-before)$+$include-before$+$endfor$+<div id="statusbar">+<span style="float:right;">+<span style="margin-right:4em;font-weight:bold;"><span id="slideidx"></span> of {$$slidecount}</span>+<button id="homebutton" title="first slide">1</button>+<button id="prevslidebutton" title="previous slide">«</button>+<button id="previtembutton" title="previous item">‹</button>+<button id="nextitembutton" title="next item">›</button>+<button id="nextslidebutton" title="next slide">»</button>+<button id="endbutton" title="last slide">{$$slidecount}</button>+<button id="incfontbutton" title="content">A+</button>+<button id="decfontbutton" title="first slide">A-</button>+<select id="tocbox" size="1"><option></option></select>+</span>+<span id="eos">½</span>+<span title="{$$location}, {$$date}">{$$title}, {$$author}</span>+</div>+$if(title)$+<div class="slide titlepage">+ <h1 class="title">$title$</h1>+$if(subtitle)$+ <h1 class="subtitle">$subtitle$</h1>+$endif$+ <p class="author">+$for(author)$$author$$sep$<br/>$endfor$+ </p>+$if(date)$+ <p class="date">$date$</p>+$endif$+</div>+$endif$+$body$+$for(include-after)$+$include-after$+$endfor$+</body>+</html>
@@ -0,0 +1,63 @@+<?xml version="1.0" encoding="utf-8"?>+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">+<html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$>+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+$for(author-meta)$+ <meta name="author" content="$author-meta$" />+$endfor$+$if(date-meta)$+ <meta name="date" content="$date-meta$" />+$endif$+ <title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>+ <style type="text/css">code{white-space: pre;}</style>+$if(highlighting-css)$+ <style type="text/css">+$highlighting-css$+ </style>+$endif$+ <link rel="stylesheet" type="text/css" media="screen, projection, print"+ href="$slidy-url$/styles/slidy.css" />+$for(css)$+ <link rel="stylesheet" type="text/css" media="screen, projection, print"+ href="$css$" />+$endfor$+$if(math)$+ $math$+$endif$+$for(header-includes)$+ $header-includes$+$endfor$+ <script src="$slidy-url$/scripts/slidy.js"+ charset="utf-8" type="text/javascript"></script>+$if(duration)$+ <meta name="duration" content="$duration$" />+$endif$+</head>+<body>+$for(include-before)$+$include-before$+$endfor$+$if(title)$+<div class="slide titlepage">+ <h1 class="title">$title$</h1>+$if(subtitle)$+ <h1 class="subtitle">$subtitle$</h1>+$endif$+ <p class="author">+$for(author)$$author$$sep$<br/>$endfor$+ </p>+$if(date)$+ <p class="date">$date$</p>+$endif$+</div>+$endif$+$body$+$for(include-after)$+$include-after$+$endfor$+</body>+</html>
@@ -0,0 +1,64 @@+\input texinfo+@documentencoding UTF-8+$for(header-includes)$+$header-includes$+$endfor$++$if(strikeout)$+@macro textstrikeout{text}+~~\text\~~+@end macro++$endif$+$if(subscript)$+@macro textsubscript{text}+@iftex+@textsubscript{\text\}+@end iftex+@ifnottex+_@{\text\@}+@end ifnottex+@end macro++$endif$+$if(superscript)$+@macro textsuperscript{text}+@iftex+@textsuperscript{\text\}+@end iftex+@ifnottex+^@{\text\@}+@end ifnottex+@end macro++$endif$+@ifnottex+@paragraphindent 0+@end ifnottex+$if(titlepage)$+@titlepage+@title $title$+$for(author)$+@author $author$+$endfor$+$if(date)$+$date$+$endif$+@end titlepage++$endif$+$for(include-before)$+$include-before$++$endfor$+$if(toc)$+@contents++$endif$+$body$+$for(include-after)$++$include-after$+$endfor$++@bye
@@ -0,0 +1,9 @@+$for(include-before)$+$include-before$++$endfor$+$body$+$for(include-after)$++$include-after$+$endfor$
@@ -0,0 +1,136 @@+<!DOCTYPE html>+<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"$if(lang)$ lang="$lang$"$endif$> <![endif]-->+<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"$if(lang)$ lang="$lang$"$endif$> <![endif]-->+<!--[if IE 8]> <html class="no-js lt-ie9"$if(lang)$ lang="$lang$"$endif$> <![endif]-->+<!--[if gt IE 8]><!--> <html class="no-js"$if(lang)$ lang="$lang$"$endif$> <!--<![endif]-->+<head>+ <meta charset="utf-8">+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">+ <meta name="generator" content="scholpandoc">+ <meta name="viewport" content="width=device-width">+ +$for(author-meta)$+ <meta name="author" content="$author-meta$">+$endfor$+$if(date-meta)$+ <meta name="dcterms.date" content="$date-meta$">+$endif$+ <title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>+ <style type="text/css">code{white-space: pre;}</style>+$if(polyfill-js)$+$for(polyfill-js)$+ <script src="$polyfill-js$"></script>+$endfor$+$else$+ <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.7.1/modernizr.min.js"></script>+ <script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.js"></script>+$endif$+$if(quotes)$+ <style type="text/css">q { quotes: "“" "”" "‘" "’"; }</style>+$endif$+$if(highlighting-css)$+ <style type="text/css">+$highlighting-css$+ </style>+$endif$+$for(css)$+ <link rel="stylesheet" href="$css$">+$endfor$+$for(html-header-includes)$+ $html-header-includes$+$endfor$+$for(header-includes)$+ $header-includes$+$endfor$+</head>+<body>+<div class="scholmd-container">+<div class="scholmd-main">+$for(include-before)$+$include-before$+$endfor$+$if(math-macros)$+<div class="math scholmd-math-definitions" style="visibility: hidden; height: 0px; width 0px;">\[+$math-macros$+\]</div>+$endif$+<div class="scholmd-content">+$if(title)$+<header>+$if(subtitle)$+<hgroup class="scholmd-title-group">+<h1 class="scholmd-title">$title$</h1>+<h1 class="scholmd-subtitle">$subtitle$</h1>+</hgroup>+$else$+<h1 class="scholmd-title">$title$</h1>+$endif$+$for(author)$+<div class="scholmd-author">+$if(author.name)$+<div class="scholmd-author-name">$author.name$</div>+$if(author.affiliation)$+<div class="scholmd-author-affiliation">$author.affiliation$</div>+$endif$+$else$+$author$+$endif$+</div>+$endfor$+$if(date)$+<div class="scholmd-date">$date$</div>+$endif$+</header>+$endif$+$if(abstract)$+<div class="scholmd-abstract">+$if(abstract-title)$+<h2 class="scholmd-abstract-title">$abstract-title$</h2>+$endif$+$abstract$+</div>+$endif$+$if(toc)$+<nav id="$idprefix$TOC">+$toc$+</nav>+$endif$+$body$+</div>+</div>+<script type="text/x-mathjax-config">+MathJax.Hub.Config({+ tex2jax: {+ processClass: "math"+ },+ TeX: {+ TagSide: "left",+ TagIndent: "1.2em",+ equationNumbers: {+ autoNumber: "AMS"+ },+ Macros: {+ ensuremath: ["#1",1],+ textsf: ["\\mathsf{\\text{#1}}",1],+ texttt: ["\\mathtt{\\text{#1}}",1]+ }+ },+ "HTML-CSS": { + scale: 100,+ availableFonts: ["TeX"], + preferredFont: "TeX",+ webFont: "TeX",+ imageFont: "TeX",+ EqnChunk: 1000+ }+});+</script>+$for(include-after)$+$include-after$+$endfor$+$if(math)$+$math$+$endif$+</div>+</body>+</html>
@@ -0,0 +1,307 @@+% Some classes load the `subfigure` package which clashes with+% our internal use of `subfig` for subfloats. We are most likely+% not going to need the canned subfigure functionality anyways,+% so we'll trick LaTeX into thinking it already loaded `subfigure`+\makeatletter+\newcommand{\dontusepackage}[2][]{%+ \@namedef{ver@#2.sty}{9999/12/31}%+ \@namedef{opt@#2.sty}{#1}}+\makeatother+\dontusepackage{subfigure}+$for(latex-before-documentclass-includes)$+$latex-before-documentclass-includes$+$endfor$+++%% ===== Begin LaTeX file ===========================+%%+\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$lang$,$endif$$if(papersize)$$papersize$,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$}++$for(latex-before-packages-includes)$+$latex-before-packages-includes$+$endfor$+$if(fontfamily)$+\usepackage{$fontfamily$}+$else$+\usepackage{lmodern}+$endif$+$if(linestretch)$+\usepackage{setspace}+\setstretch{$linestretch$}+$endif$+\usepackage{amssymb,amsmath}+\usepackage{ifxetex,ifluatex}+\usepackage[usenames,dvipsnames]{color}+\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}+\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts+}{}+$if(geometry)$+\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}+$endif$+$if(lang)$+\ifxetex+ \usepackage{polyglossia}+ \setmainlanguage{$mainlang$}+\else+ \usepackage[shorthands=off,$lang$]{babel}+\fi+$endif$+$if(natbib)$+\usepackage[$for(natbib-options)$$natbib-options$$sep$,$endfor$]{natbib}+\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$}+$endif$+$if(biblatex)$+\usepackage[$for(biblatex-options)$$biblatex-options$$sep$,$endfor$]{biblatex}+$if(biblio-files)$+\bibliography{$biblio-files$}+$endif$+$endif$+$if(listings)$+\usepackage{listings}+% Define slightly more reasonable Listings defaults+\lstset{+ basicstyle=\ttfamily\small,+ breaklines=true,+ prebreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\hookleftarrow}},+ frame=lines,+ showtabs=false,+ showspaces=false,+ showstringspaces=false,+ keywordstyle=\color[gray]{0.4}\bfseries,+ commentstyle=\color[gray]{0.65}\itshape,+ numbers=left,+ captionpos=b,+}+$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+$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$+$if(floats)$+\usepackage{caption}+\usepackage{float}+% Override extremely conservative LaTeX float placement rules+% (might need to be removed for "manuscript" styles)+\renewcommand{\topfraction}{0.85} % max fraction of floats at top+\renewcommand{\bottomfraction}{0.75} % max fraction of floats at bottom+\setcounter{topnumber}{2}+\setcounter{bottomnumber}{2}+\setcounter{totalnumber}{4}+\setcounter{dbltopnumber}{2} % for 2-column pages+\renewcommand{\dbltopfraction}{0.85} % fit big float above 2-col. text+\renewcommand{\textfraction}{0.10} % allow minimal text w. figs+\renewcommand{\floatpagefraction}{0.85} % require fuller float pages+\renewcommand{\dblfloatpagefraction}{0.85} % require fuller float pages+% Encourage floats to be placed in the vacinity of where it is defined+% (in some manuscript styles where figures are collected at the end, the 'h'+% option might need to be removed by a separate '\floatplacement' call in the+% 'header-includes' metadata field)+\floatplacement{figure}{htbp}+\floatplacement{scholmdAlgorithm}{htbp}+\floatplacement{table}{htbp}+$endif$+$if(subfigures)$+\usepackage{subfig}+\captionsetup[subfloat]{margin=1em}+$endif$+$if(algorithms)$+\usepackage{algorithm} % <- from the `algorithms` package+% Rename the `algorithm` float environment so that it doesn't+% conflict with the one provided by `algorithm2e`, which is+% also called `algorithm`. The following environments are renamed:+% algorithm -> scholmdAlgorithm+% algorithm* -> scholmdAlgorithm*+% listofalgorithms -> scholmdListofalgorithms+\let\scholmdAlgorithm\algorithm+\let\endscholmdAlgorithm\endalgorithm+\let\algorithm\relax \let\endalgorithm\relax+\let\scholmdListofalgorithms\listofalgorithms+\let\listofalgorithms\relax+{+ \catcode`\*=11\relax+ \global\let\scholmdAlgorithm*\algorithm*+ \global\let\endscholmdAlgorithm*\endalgorithm*+ \global\let\algorithm*\relax + \global\let\endalgorithm*\relax+}+$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$black$endif$,+ urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$,+ linkcolor=$if(linkcolor)$$linkcolor$$else$black$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$+$if(indentparagraphs)$+$else$+\setlength{\parindent}{0pt}+\setlength{\parskip}{6pt plus 2pt minus 1pt}+$endif$+\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$++$for(latex-after-packages-includes)$+$latex-after-packages-includes$+$endfor$+$if(math-macros)$++% Math definitons+$math-macros$+% End of math definitions++$endif$++$if(title)$+\title{$title$$if(subtitle)$\\\vspace{0.5em}{\large $subtitle$}$endif$}+$endif$+$if(author)$+\author{$for(author)$$author$$sep$ \and $endfor$}+$endif$+\date{$date$}++$for(header-includes)$+$header-includes$++$endfor$+$for(latex-header-includes)$+$latex-header-includes$+$endfor$++\begin{document}+$if(title)$+\maketitle+$endif$+$if(abstract)$+\begin{abstract}+$abstract$+\end{abstract}+$endif$++$for(include-before)$+$include-before$++$endfor$+$if(toc)$+{+\hypersetup{linkcolor=black}+\setcounter{tocdepth}{$toc-depth$}+\tableofcontents+}+$endif$+$if(lot)$+\listoftables+$endif$+$if(lof)$+\listoffigures+$endif$+$body$++$if(natbib)$+$if(biblio-files)$+$if(biblio-title)$+$if(book-class)$+\renewcommand\bibname{$biblio-title$}+$else$+\renewcommand\refname{$biblio-title$}+$endif$+$endif$+\bibliography{$biblio-files$}++$endif$+$endif$+$if(biblatex)$+\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$++$endif$+$for(include-after)$+$include-after$++$endfor$+$for(latex-after-body-includes)$+$latex-after-body-includes$+$endfor$++\end{document}++$for(latex-after-document-includes)$+$latex-after-document-includes$+$endfor$
@@ -0,0 +1,86 @@+$if(quotes)$+<style type="text/css">q { quotes: "“" "”" "‘" "’"; }</style>+$endif$+$for(include-before)$+$include-before$+$endfor$+$if(math-macros)$+<div class="math scholmd-math-definitions" style="visibility: hidden; height: 0px; width 0px;">\[+$math-macros$+\]</div>+$endif$+$if(title)$+<header>+$if(subtitle)$+<hgroup class="scholmd-title-group">+<h1 class="scholmd-title">$title$</h1>+<h1 class="scholmd-subtitle">$subtitle$</h1>+</hgroup>+$else$+<h1 class="scholmd-title">$title$</h1>+$endif$+$for(author)$+<div class="scholmd-author">+$if(author.name)$+<div class="scholmd-author-name">$author.name$</div>+$if(author.affiliation)$+<div class="scholmd-author-affiliation">$author.affiliation$</div>+$endif$+$else$+$author$+$endif$+</div>+$endfor$+$if(date)$+<div class="scholmd-date">$date$</div>+$endif$+</header>+$endif$+$if(abstract)$+<div class="scholmd-abstract">+$if(abstract-title)$+<h2 class="scholmd-abstract-title">$abstract-title$</h2>+$endif$+$abstract$+</div>+$endif$+$if(toc)$+<nav id="$idprefix$TOC">+$toc$+</nav>+$endif$+$body$++<script type="text/x-mathjax-config">+MathJax.Hub.Config({+ tex2jax: {+ processClass: "math"+ },+ TeX: {+ TagSide: "left",+ TagIndent: "1.2em",+ equationNumbers: {+ autoNumber: "AMS"+ },+ Macros: {+ ensuremath: ["#1",1],+ textsf: ["\\mathsf{\\text{#1}}",1],+ texttt: ["\\mathtt{\\text{#1}}",1]+ }+ },+ "HTML-CSS": { + scale: 100,+ availableFonts: ["TeX"], + preferredFont: "TeX",+ webFont: "TeX",+ imageFont: "TeX",+ EqnChunk: 1000+ }+});+</script>+$for(include-after)$+$include-after$+$endfor$+$if(math)$+$math$+$endif$
@@ -0,0 +1,340 @@+Name: scholdoc+Version: 0.1.3+Cabal-Version: >= 1.10+Build-Type: Custom+License: GPL+License-File: COPYING+Copyright: (c) 2014 Tim T.Y. Lin, (c) 2006-2014 John MacFarlane+Author: Tim T.Y. Lin <timtylin@gmail.com>+Maintainer: Tim T.Y. Lin <timtylin@gmail.com>+Bug-Reports: https://github.com/timtylin/scholdoc/issues+Stability: alpha+Homepage: http://scholarlymarkdown.com+Category: Text+Tested-With: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.2+Synopsis: Converts ScholarlyMarkdown documents to HTML5/LaTeX/Docx format+Description: Scholdoc is a command-line utility that converts+ ScholarlyMarkdown documents into the HTML5, LaTeX, and Docx+ (OOML) formats. It is intended to facilitate academic writing+ in a cross-platform, semantic-aware, plaintext format that can+ be quickly used in modern publishing pipelines.+ .+ Scholdoc is implemented as (rather crude) fork of @pandoc@,+ and the command-line executable mostly retains the same user+ interface (including the custom template and filter system).+ It essentially understands a new input format+ @markdown_scholarly@ (implemented in the markdown reader a+ superset of @markdown_pandoc@ features), and limits itself to+ HTML5, LaTeX, and Docx output.+ .+ Unfortunately, currently Scholdoc occupies the @Pandoc@+ namespace. This is done to avoid problems when merging in+ fixes and changes from the core Pandoc project, and to+ potentially allow enhancements from Scholdoc to be contributed+ back to Pandoc. It is thus not recommended to use the library+ directly, as Scholdoc is not backwards-compatible with Pandoc,+ to avoid confusion.+ .+ For descriptions of the original @pandoc@ package, please+ visit <http://hackage.haskell.org/package/pandoc>++Data-Files:+ -- templates+ data/templates/default.html+ data/templates/default.html5+ data/templates/default.docbook+ data/templates/default.beamer+ data/templates/default.opendocument+ data/templates/default.icml+ data/templates/default.opml+ data/templates/default.latex+ data/templates/default.context+ data/templates/default.texinfo+ data/templates/default.man+ data/templates/default.markdown+ data/templates/default.rst+ data/templates/default.plain+ data/templates/default.mediawiki+ data/templates/default.dokuwiki+ data/templates/default.rtf+ data/templates/default.s5+ data/templates/default.slidy+ data/templates/default.slideous+ data/templates/default.revealjs+ data/templates/default.dzslides+ data/templates/default.asciidoc+ data/templates/default.haddock+ data/templates/default.textile+ data/templates/default.org+ data/templates/default.epub+ data/templates/default.epub3+ data/templates/scholmdTemplate.html5,+ data/templates/scholmdTemplate_bodyOnly.html5,+ data/templates/scholmdTemplate.latex,+ -- data for docx writer+ data/reference.docx+ -- data for LaTeXMathML writer+ data/LaTeXMathML.js+ data/MathMLinHTML.js+ -- data for dzslides writer+ data/dzslides/template.html+ -- sample lua custom writer+ data/sample.lua+ -- documentation+ README.md, README-pandoc, COPYRIGHT+Extra-Source-Files:+ -- documentation+ INSTALL.md, BUGS, CONTRIBUTING.md, CHANGELOG.md+ CHANGELOG-pandoc, Makefile+ -- tryscholdoc+ tryscholdoc/index.html+ -- tests+ tests/bodybg.gif+ tests/*.native+ tests/insert+ tests/lalune.jpg+ tests/movie.jpg+ tests/markdown-reader-more.txt+ tests/markdown-citations.txt+ tests/s5-basic.html+ tests/s5-fancy.html+ tests/s5-fragment.html+ tests/s5-inserts.html+ tests/tables.html+ tests/tables.latex+ tests/tables.man+ tests/tables.plain+ tests/tables.markdown+ tests/tables.haddock+ tests/tables.txt+ tests/testsuite.txt+ tests/writer.latex+ tests/writer.html+ tests/writer.man+ tests/writer.markdown+ tests/writer.plain+ tests/writer.haddock+ tests/lhs-test.markdown+ tests/lhs-test.markdown+lhs+ tests/lhs-test.latex+ tests/lhs-test.latex+lhs+ tests/lhs-test.html+ tests/lhs-test.html+lhs+ tests/pipe-tables.txt+ tests/scholdoc.txt+ tests/scholdoc.native+ tests/scholdoc.latex+ tests/scholdoc.html++Source-repository head+ type: git+ location: git://github.com/timtylin/scholdoc.git++Flag embed_data_files+ Description: Embed data files in binary for relocatable executable.+ Default: False++Flag tryscholdoc+ Description: Build tryscholdoc cgi executable.+ Default: False++Flag https+ Description: Enable support for downloading of resources over https.+ Default: True++Flag make-pandoc-man-pages+ Description: Included to prevent errors, but currently useless for Scholdoc+ Default: False++Flag network-uri+ Description: Get Network.URI from the network-uri package+ Default: True++Library+ Build-Depends: base >= 4.2 && <5,+ syb >= 0.1 && < 0.5,+ containers >= 0.1 && < 0.6,+ unordered-containers >= 0.2 && < 0.3,+ parsec >= 3.1 && < 3.2,+ mtl >= 1.1 && < 2.3,+ filepath >= 1.1 && < 1.4,+ process >= 1 && < 1.3,+ directory >= 1 && < 1.3,+ bytestring >= 0.9 && < 0.11,+ text >= 0.11 && < 1.3,+ zip-archive >= 0.2.3.4 && < 0.3,+ old-locale >= 1 && < 1.1,+ time >= 1.2 && < 1.5,+ HTTP >= 4000.0.5 && < 4000.3,+ scholdoc-texmath >= 0.1 && < 0.2,+ xml >= 1.3.12 && < 1.4,+ random >= 1 && < 1.2,+ extensible-exceptions >= 0.1 && < 0.2,+ scholdoc-types >= 0.1.3 && < 0.1.4,+ aeson >= 0.7 && < 0.9,+ tagsoup >= 0.13.1 && < 0.14,+ base64-bytestring >= 0.1 && < 1.1,+ zlib >= 0.5 && < 0.6,+ highlighting-kate >= 0.5.8.5 && < 0.6,+ data-default >= 0.4 && < 0.6,+ temporary >= 1.1 && < 1.3,+ blaze-html >= 0.5 && < 0.8,+ blaze-markup >= 0.5.1 && < 0.7,+ yaml >= 0.8.8.2 && < 0.9,+ scientific >= 0.2 && < 0.4,+ vector >= 0.10 && < 0.11,+ hslua >= 0.3 && < 0.4,+ binary >= 0.5 && < 0.8,+ SHA >= 1.6 && < 1.7,+ old-time,+ JuicyPixels >= 3.1.6.1 && < 3.2+ if flag(network-uri)+ Build-Depends: network-uri >= 2.6 && < 2.7, network >= 2.6+ else+ Build-Depends: network >= 2 && < 2.6+ if flag(https)+ Build-Depends: http-client >= 0.3.2 && < 0.5,+ http-client-tls >= 0.2 && < 0.3,+ http-types >= 0.8 && < 0.9+ cpp-options: -DHTTP_CLIENT+ if flag(embed_data_files)+ cpp-options: -DEMBED_DATA_FILES+ -- Build-Tools: hsb2hs -- not yet recognized by cabal+ other-modules: Text.Pandoc.Data+ if os(windows)+ Cpp-options: -D_WINDOWS+ Ghc-Options: -rtsopts -Wall -fno-warn-unused-do-bind+ Ghc-Prof-Options: -auto-all -caf-all -rtsopts+ Default-Language: Haskell98+ Other-Extensions: PatternGuards, OverloadedStrings,+ ScopedTypeVariables, GeneralizedNewtypeDeriving,+ RelaxedPolyRec, DeriveDataTypeable, TypeSynonymInstances,+ FlexibleInstances+ Hs-Source-Dirs: src++ Exposed-Modules: Text.Pandoc,+ Text.Pandoc.Scholarly,+ Text.Pandoc.Options,+ Text.Pandoc.Pretty,+ Text.Pandoc.Shared,+ Text.Pandoc.MediaBag,+ Text.Pandoc.Readers.HTML,+ Text.Pandoc.Readers.LaTeX,+ Text.Pandoc.Readers.Markdown,+ Text.Pandoc.Readers.TeXMath,+ Text.Pandoc.Readers.Native,+ Text.Pandoc.Writers.Native,+ Text.Pandoc.Writers.HTML,+ Text.Pandoc.Writers.LaTeX,+ Text.Pandoc.Writers.Man,+ Text.Pandoc.Writers.Markdown,+ Text.Pandoc.Writers.Haddock,+ Text.Pandoc.Writers.Custom,+ Text.Pandoc.Writers.Docx,+ Text.Pandoc.PDF,+ Text.Pandoc.UTF8,+ Text.Pandoc.Templates,+ Text.Pandoc.XML,+ Text.Pandoc.SelfContained,+ Text.Pandoc.Process+ Other-Modules: Text.Pandoc.Writers.Shared,+ Text.Pandoc.Asciify,+ Text.Pandoc.MIME,+ Text.Pandoc.Parsing,+ Text.Pandoc.UUID,+ Text.Pandoc.ImageSize,+ Text.Pandoc.Slides,+ Text.Pandoc.Highlighting,+ Text.Pandoc.Compat.Monoid,+ Text.Pandoc.Compat.Except,+ Text.Pandoc.Compat.TagSoupEntity,+ Text.Pandoc.Compat.Directory,+ Paths_scholdoc++ Buildable: True++Executable scholdoc+ Build-Depends: scholdoc,+ scholdoc-types >= 0.1.3 && < 0.1.4,+ base >= 4.2 && <5,+ directory >= 1 && < 1.3,+ filepath >= 1.1 && < 1.4,+ text >= 0.11 && < 1.3,+ bytestring >= 0.9 && < 0.11,+ extensible-exceptions >= 0.1 && < 0.2,+ highlighting-kate >= 0.5.8.5 && < 0.6,+ aeson >= 0.7.0.5 && < 0.9,+ yaml >= 0.8.8.2 && < 0.9,+ containers >= 0.1 && < 0.6+ if flag(network-uri)+ Build-Depends: network-uri >= 2.6 && < 2.7+ else+ Build-Depends: network >= 2 && < 2.6+ Ghc-Options: -rtsopts -with-rtsopts=-K16m -Wall -fno-warn-unused-do-bind+ Ghc-Prof-Options: -auto-all -caf-all -rtsopts -with-rtsopts=-K16m+ if os(windows)+ Cpp-options: -D_WINDOWS+ Default-Language: Haskell98+ Other-Extensions: PatternGuards, OverloadedStrings,+ ScopedTypeVariables, GeneralizedNewtypeDeriving,+ RelaxedPolyRec, DeriveDataTypeable, TypeSynonymInstances,+ FlexibleInstances+ Hs-Source-Dirs: .+ Main-Is: scholdoc.hs+ Buildable: True++Executable tryscholdoc+ Main-Is: tryscholdoc.hs+ Hs-Source-Dirs: tryscholdoc+ default-language: Haskell2010+ if flag(tryscholdoc)+ Build-Depends: base, aeson, scholdoc, highlighting-kate,+ text, wai-extra, wai >= 0.3, http-types+ Buildable: True+ else+ Buildable: False++Test-Suite test-scholdoc+ Type: exitcode-stdio-1.0+ Main-Is: test-scholdoc.hs+ Hs-Source-Dirs: tests+ Build-Depends: base >= 4.2 && < 5,+ syb >= 0.1 && < 0.5,+ scholdoc,+ scholdoc-types >= 0.1.3 && < 0.1.4,+ bytestring >= 0.9 && < 0.11,+ directory >= 1 && < 1.3,+ filepath >= 1.1 && < 1.4,+ process >= 1 && < 1.3,+ Diff >= 0.2 && < 0.4,+ test-framework >= 0.3 && < 0.9,+ test-framework-hunit >= 0.2 && < 0.4,+ test-framework-quickcheck2 >= 0.2.9 && < 0.4,+ QuickCheck >= 2.4 && < 2.8,+ HUnit >= 1.2 && < 1.3,+ containers >= 0.1 && < 0.6,+ executable-path >= 0.0 && < 0.1+ Other-Modules: Tests.Old+ Tests.Helpers+ Tests.Arbitrary+ Tests.Shared+ Tests.Walk+ Tests.Readers.LaTeX+ Tests.Readers.Markdown+ Tests.Writers.Native+ Tests.Writers.HTML+ Tests.Writers.Markdown+ Tests.Writers.Plain+ Tests.Writers.LaTeX+ Ghc-Options: -rtsopts -Wall -fno-warn-unused-do-bind+ Default-Language: Haskell98++benchmark benchmark-scholdoc+ Type: exitcode-stdio-1.0+ Main-Is: benchmark-scholdoc.hs+ Hs-Source-Dirs: benchmark+ Build-Depends: scholdoc,+ base >= 4.2 && < 5,+ criterion >= 0.5 && < 0.9+ Ghc-Options: -rtsopts -Wall -fno-warn-unused-do-bind+ Default-Language: Haskell98
@@ -0,0 +1,1432 @@+{-# LANGUAGE CPP, TupleSections #-}+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>+Copyright (C) 2014 Tim T.Y. Lin <timtylin@gmail.com>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Main+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley@edu>+ Stability : alpha+ Portability : portable++Parses command-line options and calls the appropriate readers and+writers.+-}+module Main where+import Text.Pandoc+import Text.Pandoc.Builder (setMeta)+import Text.Pandoc.PDF (makePDF)+import Text.Pandoc.Walk (walk)+import Text.Pandoc.Readers.LaTeX (handleIncludes)+import Text.Pandoc.Shared ( tabFilter, readDataFileUTF8, readDataFile,+ safeRead, headerShift, normalize, err, warn,+ openURL )+import Text.Pandoc.MediaBag ( mediaDirectory, extractMediaBag, MediaBag )+import Text.Pandoc.XML ( toEntities )+import Text.Pandoc.SelfContained ( makeSelfContained )+import Text.Pandoc.Process (pipeProcess)+import Text.Highlighting.Kate ( languages, Style, tango, pygments,+ espresso, zenburn, kate, haddock, monochrome )+import System.Environment ( getArgs, getProgName )+import System.Exit ( exitWith, ExitCode (..) )+import System.FilePath+import System.Console.GetOpt+import Data.Char ( toLower )+import Data.List ( intercalate, isPrefixOf, isSuffixOf, sort, (\\) )+import Data.Maybe ( isNothing )+import System.Directory ( getAppUserDataDirectory, findExecutable,+ doesFileExist, Permissions(..), getPermissions )+import System.IO ( stdout, stderr )+import System.IO.Error ( isDoesNotExistError )+import qualified Control.Exception as E+import Control.Exception.Extensible ( throwIO )+import qualified Text.Pandoc.UTF8 as UTF8+import Control.Monad (when, unless, (>=>))+import Data.Maybe (isJust, fromMaybe)+import Data.Foldable (foldrM)+import Network.URI (parseURI, isURI, URI(..))+import qualified Data.ByteString.Lazy as B+import qualified Data.ByteString as BS+import Data.Aeson (eitherDecode', encode)+import qualified Data.Map as M+import Data.Yaml (decode)+import qualified Data.Yaml as Yaml+import qualified Data.Text as T+import Control.Applicative ((<$>), (<|>))+-- import Text.Pandoc.Readers.Txt2Tags (getT2TMeta)+import Data.Monoid++type Transform = Pandoc -> Pandoc++copyrightMessage :: String+copyrightMessage = intercalate "\n" [+ "",+ "Copyright (C) 2014 Tim T.Y. Lin",+ "This work is a fork of Pandoc:",+ " Copyright (C) 2006-2014 John MacFarlane",+ " Web: http://johnmacfarlane.net/pandoc",+ "This is free software; see the source for copying conditions.",+ "There is no warranty, not even for merchantability or fitness",+ "for a particular purpose." ]++compileInfo :: String+compileInfo =+ "\nCompiled with scholdoc-texmath " +++ VERSION_scholdoc_texmath ++ ", highlighting-kate " ++ VERSION_highlighting_kate +++ ".\nSyntax highlighting is supported for the following languages:\n " +++ wrapWords 4 78+ [map toLower l | l <- languages, l /= "Alert" && l /= "Alert_indent"]++-- | Converts a list of strings into a single string with the items printed as+-- comma separated words in lines with a maximum line length.+wrapWords :: Int -> Int -> [String] -> String+wrapWords indent c = wrap' (c - indent) (c - indent)+ where+ wrap' _ _ [] = ""+ wrap' cols remaining (x:xs)+ | remaining == cols =+ x ++ wrap' cols (remaining - length x) xs+ | (length x + 1) > remaining =+ ",\n" ++ replicate indent ' ' ++ x +++ wrap' cols (cols - length x) xs+ | otherwise =+ ", " ++ x +++ wrap' cols (remaining - length x - 2) xs++isTextFormat :: String -> Bool+isTextFormat s = takeWhile (`notElem` "+-") s `notElem` binaries+ where binaries = ["odt","docx","epub","epub3"]++externalFilter :: FilePath -> [String] -> Pandoc -> IO Pandoc+externalFilter f args' d = do+ mbexe <- if '/' `elem` f+ -- don't check PATH if filter name has a path+ then return Nothing+ -- we catch isDoesNotExistError because this will+ -- be triggered if PATH not set:+ else E.catch (findExecutable f)+ (\e -> if isDoesNotExistError e+ then return Nothing+ else throwIO e)+ (f', args'') <- case mbexe of+ Just x -> return (x, args')+ Nothing -> do+ exists <- doesFileExist f+ if exists+ then do+ isExecutable <- executable `fmap`+ getPermissions f+ return $+ case map toLower $ takeExtension f of+ _ | isExecutable -> (f, args')+ ".py" -> ("python", f:args')+ ".hs" -> ("runhaskell", f:args')+ ".pl" -> ("perl", f:args')+ ".rb" -> ("ruby", f:args')+ ".php" -> ("php", f:args')+ _ -> (f, args')+ else err 85 $ "Filter " ++ f ++ " not found"+ (exitcode, outbs, errbs) <- E.handle filterException $+ pipeProcess Nothing f' args'' $ encode d+ when (not $ B.null errbs) $ B.hPutStr stderr errbs+ case exitcode of+ ExitSuccess -> return $ either error id $ eitherDecode' outbs+ ExitFailure _ -> err 83 $ "Error running filter " ++ f+ where filterException :: E.SomeException -> IO a+ filterException e = err 83 $ "Error running filter " ++ f ++ "\n" +++ show e++-- | Data structure for command line options.+data Opt = Opt+ { optTabStop :: Int -- ^ Number of spaces per tab+ , optPreserveTabs :: Bool -- ^ Preserve tabs instead of converting to spaces+ , optStandalone :: Bool -- ^ Include header, footer+ , optReader :: String -- ^ Reader format+ , optWriter :: String -- ^ Writer format+ , optParseRaw :: Bool -- ^ Parse unconvertable HTML and TeX+ , optTableOfContents :: Bool -- ^ Include table of contents+ , optTransforms :: [Transform] -- ^ Doc transforms to apply+ , optTemplate :: Maybe FilePath -- ^ Custom template+ , optVariables :: [(String,String)] -- ^ Template variables to set+ , optMetadata :: M.Map String MetaValue -- ^ Metadata fields to set+ , optOutputFile :: String -- ^ Name of output file+ , optNumberSections :: Bool -- ^ Number sections in LaTeX+ , optNumberOffset :: [Int] -- ^ Starting number for sections+ , optSectionDivs :: Bool -- ^ Put sections in div tags in HTML+ , optIncremental :: Bool -- ^ Use incremental lists in Slidy/Slideous/S5+ , optSelfContained :: Bool -- ^ Make HTML accessible offline+ , optSmart :: Bool -- ^ Use smart typography+ , optOldDashes :: Bool -- ^ Parse dashes like pandoc <=1.8.2.1+ , optHtml5 :: Bool -- ^ Produce HTML5 in HTML+ , optHtmlQTags :: Bool -- ^ Use <q> tags in HTML+ , optHighlight :: Bool -- ^ Highlight source code+ , optHighlightStyle :: Style -- ^ Style to use for highlighted code+ , optChapters :: Bool -- ^ Use chapter for top-level sects+ , optHTMLMathMethod :: HTMLMathMethod -- ^ Method to print HTML math+ , optUseMathJaxCDN :: Bool -- ^ Use MathJax from CDN in standalone+ , optReferenceODT :: Maybe FilePath -- ^ Path of reference.odt+ , optReferenceDocx :: Maybe FilePath -- ^ Path of reference.docx+ , optEpubStylesheet :: Maybe String -- ^ EPUB stylesheet+ , optEpubMetadata :: String -- ^ EPUB metadata+ , optEpubFonts :: [FilePath] -- ^ EPUB fonts to embed+ , optEpubChapterLevel :: Int -- ^ Header level at which to split chapters+ , optTOCDepth :: Int -- ^ Number of levels to include in TOC+ , optDumpArgs :: Bool -- ^ Output command-line arguments+ , optIgnoreArgs :: Bool -- ^ Ignore command-line arguments+ , optReferenceLinks :: Bool -- ^ Use reference links in writing markdown, rst+ , optWrapText :: Bool -- ^ Wrap text+ , optColumns :: Int -- ^ Line length in characters+ , optFilters :: [FilePath] -- ^ Filters to apply+ , optEmailObfuscation :: ObfuscationMethod+ , optIdentifierPrefix :: String+ , optIndentedCodeClasses :: [String] -- ^ Default classes for indented code blocks+ , optDataDir :: Maybe FilePath+ , optCiteMethod :: CiteMethod -- ^ Method to output cites+ , optListings :: Bool -- ^ Use listings package for code blocks+ , optLaTeXEngine :: String -- ^ Program to use for latex -> pdf+ , optSlideLevel :: Maybe Int -- ^ Header level that creates slides+ , optSetextHeaders :: Bool -- ^ Use atx headers for markdown level 1-2+ , optAscii :: Bool -- ^ Use ascii characters only in html+ , optTeXLigatures :: Bool -- ^ Use TeX ligatures for quotes/dashes+ , optDefaultImageExtension :: String -- ^ Default image extension+ , optExtractMedia :: Maybe FilePath -- ^ Path to extract embedded media+ , optTrace :: Bool -- ^ Print debug information+ , optTrackChanges :: TrackChanges -- ^ Accept or reject MS Word track-changes.+ , optKaTeXStylesheet :: Maybe String -- ^ Path to stylesheet for KaTeX+ , optKaTeXJS :: Maybe String -- ^ Path to js file for KaTeX+ }++-- | Defaults for command-line options.+defaultOpts :: Opt+defaultOpts = Opt+ { optTabStop = 4+ , optPreserveTabs = False+ , optStandalone = False+ , optReader = "" -- null for default reader+ , optWriter = "" -- null for default writer+ , optParseRaw = False+ , optTableOfContents = False+ , optTransforms = []+ , optTemplate = Nothing+ , optVariables = []+ , optMetadata = M.empty+ , optOutputFile = "-" -- "-" means stdout+ , optNumberSections = False+ , optNumberOffset = [0,0,0,0,0,0]+ , optSectionDivs = False+ , optIncremental = False+ , optSelfContained = False+ , optSmart = False+ , optOldDashes = False+ , optHtml5 = False+ , optHtmlQTags = False+ , optHighlight = True+ , optHighlightStyle = pygments+ , optChapters = False+ , optHTMLMathMethod = PlainMath+ , optUseMathJaxCDN = True+ , optReferenceODT = Nothing+ , optReferenceDocx = Nothing+ , optEpubStylesheet = Nothing+ , optEpubMetadata = ""+ , optEpubFonts = []+ , optEpubChapterLevel = 1+ , optTOCDepth = 3+ , optDumpArgs = False+ , optIgnoreArgs = False+ , optReferenceLinks = False+ , optWrapText = True+ , optColumns = 72+ , optFilters = []+ , optEmailObfuscation = JavascriptObfuscation+ , optIdentifierPrefix = ""+ , optIndentedCodeClasses = []+ , optDataDir = Nothing+ , optCiteMethod = Citeproc+ , optListings = False+ , optLaTeXEngine = "pdflatex"+ , optSlideLevel = Nothing+ , optSetextHeaders = True+ , optAscii = False+ , optTeXLigatures = True+ , optDefaultImageExtension = ""+ , optExtractMedia = Nothing+ , optTrace = False+ , optTrackChanges = AcceptChanges+ , optKaTeXStylesheet = Nothing+ , optKaTeXJS = Nothing+ }++-- | A list of functions, each transforming the options data structure+-- in response to a command-line option.+options :: [OptDescr (Opt -> IO Opt)]+options =+ [ Option "fr" ["from","read"]+ (ReqArg+ (\arg opt -> return opt { optReader = arg })+ "FORMAT")+ ""++ , Option "tw" ["to","write"]+ (ReqArg+ (\arg opt -> return opt { optWriter = arg })+ "FORMAT")+ ""++ , Option "o" ["output"]+ (ReqArg+ (\arg opt -> return opt { optOutputFile = arg })+ "FILENAME")+ "" -- "Name of output file"++ , Option "" ["data-dir"]+ (ReqArg+ (\arg opt -> return opt { optDataDir = Just arg })+ "DIRECTORY") -- "Directory containing pandoc data files."+ ""++ , Option "" ["strict"]+ (NoArg+ (\opt -> do+ err 59 $ "The --strict option has been removed.\n" +++ "Use `markdown_strict' input or output format instead."+ return opt ))+ "" -- "Disable markdown syntax extensions"++ , Option "R" ["parse-raw"]+ (NoArg+ (\opt -> return opt { optParseRaw = True }))+ "" -- "Parse untranslatable HTML codes and LaTeX environments as raw"++ , Option "" ["no-parse-raw"]+ (NoArg+ (\opt -> return opt { optParseRaw = False }))+ "" -- "Disable parsing of untranslatable HTML codes and LaTeX environments as raw"++ , Option "S" ["smart"]+ (NoArg+ (\opt -> return opt { optSmart = True }))+ "" -- "Use smart quotes, dashes, and ellipses"++ , Option "" ["no-smart"]+ (NoArg+ (\opt -> return opt { optSmart = False }))+ "" -- "Disable smart quotes, dashes, and ellipses"++ , Option "" ["old-dashes"]+ (NoArg+ (\opt -> return opt { optSmart = True+ , optOldDashes = True }))+ "" -- "Use smart quotes, dashes, and ellipses"++ , Option "" ["base-header-level"]+ (ReqArg+ (\arg opt ->+ case safeRead arg of+ Just t | t > 0 -> do+ let oldTransforms = optTransforms opt+ let shift = t - 1+ return opt{ optTransforms =+ headerShift shift : oldTransforms }+ _ -> err 19+ "base-header-level must be a number > 0")+ "NUMBER")+ "" -- "Headers base level"++ , Option "" ["indented-code-classes"]+ (ReqArg+ (\arg opt -> return opt { optIndentedCodeClasses = words $+ map (\c -> if c == ',' then ' ' else c) arg })+ "STRING")+ "" -- "Classes (whitespace- or comma-separated) to use for indented code-blocks"++ , Option "F" ["filter"]+ (ReqArg+ (\arg opt -> return opt { optFilters = arg : optFilters opt })+ "PROGRAM")+ "" -- "External JSON filter"++ , Option "" ["normalize"]+ (NoArg+ (\opt -> return opt { optTransforms =+ normalize : optTransforms opt } ))+ "" -- "Normalize the Pandoc AST"++ , Option "p" ["preserve-tabs"]+ (NoArg+ (\opt -> return opt { optPreserveTabs = True }))+ "" -- "Preserve tabs instead of converting to spaces"++ , Option "" ["tab-stop"]+ (ReqArg+ (\arg opt ->+ case safeRead arg of+ Just t | t > 0 -> return opt { optTabStop = t }+ _ -> err 31+ "tab-stop must be a number greater than 0")+ "NUMBER")+ "" -- "Tab stop (default 4)"++ , Option "" ["track-changes"]+ (ReqArg+ (\arg opt -> do+ action <- case arg of+ "accept" -> return AcceptChanges+ "reject" -> return RejectChanges+ "all" -> return AllChanges+ _ -> err 6+ ("Unknown option for track-changes: " ++ arg)+ return opt { optTrackChanges = action })+ "accept|reject|all")+ "" -- "Accepting or reject MS Word track-changes.""++ , Option "" ["extract-media"]+ (ReqArg+ (\arg opt -> do+ return opt { optExtractMedia = Just arg })+ "PATH")+ "" -- "Directory to which to extract embedded media"++ , Option "s" ["standalone"]+ (NoArg+ (\opt -> return opt { optStandalone = True }))+ "" -- "Include needed header and footer on output"++ , Option "" ["no-standalone"]+ (NoArg+ (\opt -> return opt { optStandalone = False }))+ "" -- "Exclude needed header and footer on output"++ , Option "" ["template"]+ (ReqArg+ (\arg opt -> do+ return opt{ optTemplate = Just arg,+ optStandalone = True })+ "FILENAME")+ "" -- "Use custom template"++ , Option "M" ["metadata"]+ (ReqArg+ (\arg opt -> do+ let (key,val) = case break (`elem` ":=") arg of+ (k,_:v) -> (k, readMetaValue v)+ (k,_) -> (k, MetaBool True)+ return opt{ optMetadata = addMetadata key val+ $ optMetadata opt })+ "KEY[:VALUE]")+ ""++ , Option "V" ["variable"]+ (ReqArg+ (\arg opt -> do+ let (key,val) = case break (`elem` ":=") arg of+ (k,_:v) -> (k,v)+ (k,_) -> (k,"true")+ return opt{ optVariables = (key,val) : optVariables opt })+ "KEY[:VALUE]")+ ""++ , Option "D" ["print-default-template"]+ (ReqArg+ (\arg _ -> do+ templ <- getDefaultTemplate Nothing arg+ case templ of+ Right t -> UTF8.hPutStr stdout t+ Left e -> error $ show e+ exitWith ExitSuccess)+ "FORMAT")+ "" -- "Print default template for FORMAT"++ , Option "" ["print-default-data-file"]+ (ReqArg+ (\arg _ -> do+ readDataFile Nothing arg >>= BS.hPutStr stdout+ exitWith ExitSuccess)+ "FILE")+ "" -- "Print default data file"++ , Option "" ["no-wrap"]+ (NoArg+ (\opt -> return opt { optWrapText = False }))+ "" -- "Do not wrap text in output"++ , Option "" ["columns"]+ (ReqArg+ (\arg opt ->+ case safeRead arg of+ Just t | t > 0 -> return opt { optColumns = t }+ _ -> err 33 $+ "columns must be a number greater than 0")+ "NUMBER")+ "" -- "Length of line in characters"++ , Option "" ["toc", "table-of-contents"]+ (NoArg+ (\opt -> return opt { optTableOfContents = True }))+ "" -- "Include table of contents"++ , Option "" ["toc-depth"]+ (ReqArg+ (\arg opt -> do+ case safeRead arg of+ Just t | t >= 1 && t <= 6 ->+ return opt { optTOCDepth = t }+ _ -> err 57 $+ "TOC level must be a number between 1 and 6")+ "NUMBER")+ "" -- "Number of levels to include in TOC"++ , Option "" ["no-highlight"]+ (NoArg+ (\opt -> return opt { optHighlight = False }))+ "" -- "Don't highlight source code"++ , Option "" ["highlight-style"]+ (ReqArg+ (\arg opt -> do+ newStyle <- case map toLower arg of+ "pygments" -> return pygments+ "tango" -> return tango+ "espresso" -> return espresso+ "zenburn" -> return zenburn+ "kate" -> return kate+ "monochrome" -> return monochrome+ "haddock" -> return haddock+ _ -> err 39 $+ "Unknown style :" ++ arg+ return opt{ optHighlightStyle = newStyle })+ "STYLE")+ "" -- "Style for highlighted code"++ , Option "H" ["include-in-header"]+ (ReqArg+ (\arg opt -> do+ text <- UTF8.readFile arg+ -- add new ones to end, so they're included in order specified+ let newvars = optVariables opt ++ [("header-includes",text)]+ return opt { optVariables = newvars,+ optStandalone = True })+ "FILENAME")+ "" -- "File to include at end of header (implies -s)"++ , Option "B" ["include-before-body"]+ (ReqArg+ (\arg opt -> do+ text <- UTF8.readFile arg+ -- add new ones to end, so they're included in order specified+ let newvars = optVariables opt ++ [("include-before",text)]+ return opt { optVariables = newvars,+ optStandalone = True })+ "FILENAME")+ "" -- "File to include before document body"++ , Option "A" ["include-after-body"]+ (ReqArg+ (\arg opt -> do+ text <- UTF8.readFile arg+ -- add new ones to end, so they're included in order specified+ let newvars = optVariables opt ++ [("include-after",text)]+ return opt { optVariables = newvars,+ optStandalone = True })+ "FILENAME")+ "" -- "File to include after document body"++ , Option "" ["self-contained"]+ (NoArg+ (\opt -> return opt { optSelfContained = True,+ optStandalone = True }))+ "" -- "Make slide shows include all the needed js and css"++ , Option "" ["offline"]+ (NoArg+ (\opt -> do warn $ "--offline is deprecated. Use --self-contained instead."+ return opt { optSelfContained = True,+ optStandalone = True }))+ "" -- "Make slide shows include all the needed js and css"+ -- deprecated synonym for --self-contained++ , Option "5" ["html5"]+ (NoArg+ (\opt -> do+ warn $ "--html5 is deprecated. "+ ++ "Use the html5 output format instead."+ return opt { optHtml5 = True }))+ "" -- "Produce HTML5 in HTML output"++ , Option "" ["html-q-tags"]+ (NoArg+ (\opt -> do+ return opt { optHtmlQTags = True }))+ "" -- "Use <q> tags for quotes in HTML"++ , Option "" ["ascii"]+ (NoArg+ (\opt -> return opt { optAscii = True }))+ "" -- "Use ascii characters only in HTML output"++ , Option "" ["reference-links"]+ (NoArg+ (\opt -> return opt { optReferenceLinks = True } ))+ "" -- "Use reference links in parsing HTML"++ , Option "" ["atx-headers"]+ (NoArg+ (\opt -> return opt { optSetextHeaders = False } ))+ "" -- "Use atx-style headers for markdown"++ , Option "" ["chapters"]+ (NoArg+ (\opt -> return opt { optChapters = True }))+ "" -- "Use chapter for top-level sections in LaTeX, DocBook"++ , Option "N" ["number-sections"]+ (NoArg+ (\opt -> return opt { optNumberSections = True }))+ "" -- "Number sections in LaTeX"++ , Option "" ["number-offset"]+ (ReqArg+ (\arg opt ->+ case safeRead ('[':arg ++ "]") of+ Just ns -> return opt { optNumberOffset = ns,+ optNumberSections = True }+ _ -> err 57 "could not parse number-offset")+ "NUMBERS")+ "" -- "Starting number for sections, subsections, etc."++ , Option "" ["no-tex-ligatures"]+ (NoArg+ (\opt -> return opt { optTeXLigatures = False }))+ "" -- "Don't use tex ligatures for quotes, dashes"++ , Option "" ["listings"]+ (NoArg+ (\opt -> return opt { optListings = True }))+ "" -- "Use listings package for LaTeX code blocks"++ , Option "i" ["incremental"]+ (NoArg+ (\opt -> return opt { optIncremental = True }))+ "" -- "Make list items display incrementally in Slidy/Slideous/S5"++ , Option "" ["slide-level"]+ (ReqArg+ (\arg opt -> do+ case safeRead arg of+ Just t | t >= 1 && t <= 6 ->+ return opt { optSlideLevel = Just t }+ _ -> err 39 $+ "slide level must be a number between 1 and 6")+ "NUMBER")+ "" -- "Force header level for slides"++ , Option "" ["section-divs"]+ (NoArg+ (\opt -> return opt { optSectionDivs = True }))+ "" -- "Put sections in div tags in HTML"++ , Option "" ["default-image-extension"]+ (ReqArg+ (\arg opt -> return opt { optDefaultImageExtension = arg })+ "extension")+ "" -- "Default extension for extensionless images"++ , Option "" ["email-obfuscation"]+ (ReqArg+ (\arg opt -> do+ method <- case arg of+ "references" -> return ReferenceObfuscation+ "javascript" -> return JavascriptObfuscation+ "none" -> return NoObfuscation+ _ -> err 6+ ("Unknown obfuscation method: " ++ arg)+ return opt { optEmailObfuscation = method })+ "none|javascript|references")+ "" -- "Method for obfuscating email in HTML"++ , Option "" ["id-prefix"]+ (ReqArg+ (\arg opt -> return opt { optIdentifierPrefix = arg })+ "STRING")+ "" -- "Prefix to add to automatically generated HTML identifiers"++ , Option "T" ["title-prefix"]+ (ReqArg+ (\arg opt -> do+ let newvars = ("title-prefix", arg) : optVariables opt+ return opt { optVariables = newvars,+ optStandalone = True })+ "STRING")+ "" -- "String to prefix to HTML window title"++ , Option "c" ["css"]+ (ReqArg+ (\arg opt -> do+ -- add new link to end, so it is included in proper order+ let newvars = optVariables opt ++ [("css",arg)]+ return opt { optVariables = newvars,+ optStandalone = True })+ "URL")+ "" -- "Link to CSS style sheet"++ , Option "" ["reference-odt"]+ (ReqArg+ (\arg opt -> do+ return opt { optReferenceODT = Just arg })+ "FILENAME")+ "" -- "Path of custom reference.odt"++ , Option "" ["reference-docx"]+ (ReqArg+ (\arg opt -> do+ return opt { optReferenceDocx = Just arg })+ "FILENAME")+ "" -- "Path of custom reference.docx"++ , Option "" ["epub-stylesheet"]+ (ReqArg+ (\arg opt -> do+ text <- UTF8.readFile arg+ return opt { optEpubStylesheet = Just text })+ "FILENAME")+ "" -- "Path of epub.css"++ , Option "" ["epub-cover-image"]+ (ReqArg+ (\arg opt ->+ return opt { optVariables =+ ("epub-cover-image", arg) : optVariables opt })+ "FILENAME")+ "" -- "Path of epub cover image"++ , Option "" ["epub-metadata"]+ (ReqArg+ (\arg opt -> do+ text <- UTF8.readFile arg+ return opt { optEpubMetadata = text })+ "FILENAME")+ "" -- "Path of epub metadata file"++ , Option "" ["epub-embed-font"]+ (ReqArg+ (\arg opt -> do+ return opt{ optEpubFonts = arg : optEpubFonts opt })+ "FILE")+ "" -- "Directory of fonts to embed"++ , Option "" ["epub-chapter-level"]+ (ReqArg+ (\arg opt -> do+ case safeRead arg of+ Just t | t >= 1 && t <= 6 ->+ return opt { optEpubChapterLevel = t }+ _ -> err 59 $+ "chapter level must be a number between 1 and 6")+ "NUMBER")+ "" -- "Header level at which to split chapters in EPUB"++ , Option "" ["latex-engine"]+ (ReqArg+ (\arg opt -> do+ let b = takeBaseName arg+ if b `elem` ["pdflatex", "lualatex", "xelatex"]+ then return opt { optLaTeXEngine = arg }+ else err 45 "latex-engine must be pdflatex, lualatex, or xelatex.")+ "PROGRAM")+ "" -- "Name of latex program to use in generating PDF"++ , Option "" ["bibliography"]+ (ReqArg+ (\arg opt -> return opt{ optMetadata = addMetadata+ "bibliography" (readMetaValue arg)+ $ optMetadata opt+ , optVariables =+ ("biblio-files", dropExtension arg) :+ optVariables opt+ })+ "FILE")+ ""++ , Option "" ["csl"]+ (ReqArg+ (\arg opt ->+ return opt{ optMetadata = addMetadata "csl"+ (readMetaValue arg)+ $ optMetadata opt })+ "FILE")+ ""++ , Option "" ["citation-abbreviations"]+ (ReqArg+ (\arg opt ->+ return opt{ optMetadata = addMetadata+ "citation-abbreviations"+ (readMetaValue arg)+ $ optMetadata opt })+ "FILE")+ ""++ , Option "" ["natbib"]+ (NoArg+ (\opt -> return opt { optCiteMethod = Natbib }))+ "" -- "Use natbib cite commands in LaTeX output"++ , Option "" ["biblatex"]+ (NoArg+ (\opt -> return opt { optCiteMethod = Biblatex }))+ "" -- "Use biblatex cite commands in LaTeX output"++ , Option "" ["citeproc"]+ (NoArg+ (\opt -> return opt { optFilters =+ "scholdoc-citeproc" : optFilters opt }))+ "" -- add pandoc-citeproc to list of filters++ , Option "m" ["latexmathml", "asciimathml"]+ (OptArg+ (\arg opt ->+ return opt { optHTMLMathMethod = LaTeXMathML arg })+ "URL")+ "" -- "Use LaTeXMathML script in html output"++ , Option "" ["mathml"]+ (OptArg+ (\arg opt ->+ return opt { optHTMLMathMethod = MathML arg })+ "URL")+ "" -- "Use mathml for HTML math"++ , Option "" ["mimetex"]+ (OptArg+ (\arg opt -> do+ let url' = case arg of+ Just u -> u ++ "?"+ Nothing -> "/cgi-bin/mimetex.cgi?"+ return opt { optHTMLMathMethod = WebTeX url' })+ "URL")+ "" -- "Use mimetex for HTML math"++ , Option "" ["webtex"]+ (OptArg+ (\arg opt -> do+ let url' = case arg of+ Just u -> u+ Nothing -> "http://chart.apis.google.com/chart?cht=tx&chl="+ return opt { optHTMLMathMethod = WebTeX url' })+ "URL")+ "" -- "Use web service for HTML math"++ , Option "" ["jsmath"]+ (OptArg+ (\arg opt -> return opt { optHTMLMathMethod = JsMath arg})+ "URL")+ "" -- "Use jsMath for HTML math"++ , Option "" ["mathjax"]+ (OptArg+ (\arg opt -> do+ let url' = case arg of+ Just u -> u+ Nothing -> ""+ return opt { optHTMLMathMethod = MathJax url'})+ "URL")+ "" -- "Use MathJax for HTML math"+ , Option "" ["katex"]+ (OptArg+ (\arg opt ->+ return opt+ { optKaTeXJS =+ arg <|> Just "http://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.1.0/katex.min.js"})+ "URL")+ "" -- Use KaTeX for HTML Math++ , Option "" ["katex-stylesheet"]+ (ReqArg+ (\arg opt ->+ return opt { optKaTeXStylesheet = Just arg })+ "URL")+ "" -- Set the KaTeX Stylesheet location++ , Option "" ["no-mathjax-cdn"]+ (NoArg+ (\opt -> return opt { optUseMathJaxCDN = False }))+ "" -- suppress inclusion of MathJax script from CDN+ -- useful for offline or preventing conflict with buildscripts+ -- explicit declaration of any math method overrides this++ , Option "" ["gladtex"]+ (NoArg+ (\opt -> return opt { optHTMLMathMethod = GladTeX }))+ "" -- "Use gladtex for HTML math"++ , Option "" ["trace"]+ (NoArg+ (\opt -> return opt { optTrace = True }))+ "" -- "Turn on diagnostic tracing in readers."++ , Option "" ["dump-args"]+ (NoArg+ (\opt -> return opt { optDumpArgs = True }))+ "" -- "Print output filename and arguments to stdout."++ , Option "" ["ignore-args"]+ (NoArg+ (\opt -> return opt { optIgnoreArgs = True }))+ "" -- "Ignore command-line arguments."++ , Option "" ["emulate-pandoc"]+ (NoArg+ (\opt -> return opt))+ "" -- "Make defaults same as Pandoc (picked up in rawArgs)"++ , Option "v" ["version"]+ (NoArg+ (\_ -> do+ prg <- getProgName+ defaultDatadir <- getAppUserDataDirectory "pandoc"+ UTF8.hPutStrLn stdout (prg +++ pandocVersion ++ "-alpha, incorporating Pandoc 1.13.1" +++ compileInfo ++ "\nDefault user data directory: " +++ defaultDatadir ++ copyrightMessage)+ exitWith ExitSuccess ))+ "" -- "Print version"++ , Option "h" ["help"]+ (NoArg+ (\_ -> do+ prg <- getProgName+ UTF8.hPutStr stdout (usageMessage prg options)+ exitWith ExitSuccess ))+ "" -- "Show help"++ ]+++addMetadata :: String -> MetaValue -> M.Map String MetaValue+ -> M.Map String MetaValue+addMetadata k v m = case M.lookup k m of+ Nothing -> M.insert k v m+ Just (MetaList xs) -> M.insert k+ (MetaList (xs ++ [v])) m+ Just x -> M.insert k (MetaList [v, x]) m++readMetaValue :: String -> MetaValue+readMetaValue s = case decode (UTF8.fromString s) of+ Just (Yaml.String t) -> MetaString $ T.unpack t+ Just (Yaml.Bool b) -> MetaBool b+ _ -> MetaString s++-- Returns usage message+usageMessage :: String -> [OptDescr (Opt -> IO Opt)] -> String+usageMessage programName = usageInfo+ (programName ++ " [OPTIONS] [FILES]" +++ "\nInput formats: " ++ (wrapWords 16 78 $ readers'names) +++ '\n' : replicate 16 ' ' +++ "[* markdown_scholarly only supports the following output formats:" +++ '\n' : replicate 19 ' ' +++ "html5, latex, dzslides, revealjs, beamer]" +++ "\nOutput formats: " ++ (wrapWords 16 78 $ writers'names) +++ '\n' : replicate 16 ' ' +++ "[* for pdf output, use latex or beamer and -o FILENAME.pdf]\nOptions:")+ where+ writers'names = sort $ "pdf*" : map fst writers+ readers'names = sort $ "markdown_scholarly*" :+ ((map fst readers) \\ ["markdown_scholarly"])++-- Determine default reader based on source file extensions+defaultReaderName :: String -> [FilePath] -> String+defaultReaderName fallback [] = fallback+defaultReaderName fallback (x:xs) =+ case takeExtension (map toLower x) of+ ".lhs" -> "markdown+lhs"+ ".native" -> "native"+ ".json" -> "json"+ _ -> defaultReaderName fallback xs++-- Returns True if extension of first source is .lhs+lhsExtension :: [FilePath] -> Bool+lhsExtension (x:_) = takeExtension x == ".lhs"+lhsExtension _ = False++-- Determine default writer based on output file extension+defaultWriterName :: FilePath -> String+defaultWriterName "-" = "html" -- no output file+defaultWriterName x =+ case takeExtension (map toLower x) of+ "" -> "markdown" -- empty extension+ ".tex" -> "latex"+ ".latex" -> "latex"+ ".ltx" -> "latex"+ ".native" -> "native"+ ".json" -> "json"+ ".txt" -> "markdown"+ ".text" -> "markdown"+ ".md" -> "markdown"+ ".markdown" -> "markdown"+ ".lhs" -> "markdown+lhs"+ ".docx" -> "docx"+ ['.',y] | y `elem` ['1'..'9'] -> "man"+ _ -> "html"++-- Transformations of a Pandoc document post-parsing:++extractMedia :: MediaBag -> FilePath -> Pandoc -> IO Pandoc+extractMedia media dir d =+ case [fp | (fp, _, _) <- mediaDirectory media] of+ [] -> return d+ fps -> do+ extractMediaBag True dir media+ return $ walk (adjustImagePath dir fps) d++adjustImagePath :: FilePath -> [FilePath] -> Inline -> Inline+adjustImagePath dir paths (Image attr lab (src, tit))+ | src `elem` paths = Image attr lab (dir ++ "/" ++ src, tit)+adjustImagePath _ _ x = x++adjustMetadata :: M.Map String MetaValue -> Pandoc -> IO Pandoc+adjustMetadata metadata d = return $ M.foldWithKey setMeta d metadata++applyTransforms :: [Transform] -> Pandoc -> IO Pandoc+applyTransforms transforms d = return $ foldr ($) d transforms++applyFilters :: [FilePath] -> [String] -> Pandoc -> IO Pandoc+applyFilters filters args d =+ foldrM ($) d $ map (flip externalFilter args) filters++main :: IO ()+main = do++ rawArgs <- map UTF8.decodeArg <$> getArgs+ prg <- getProgName+ let compatMode = (prg == "hsmarkdown")+ let scholarlyPandoc = (prg == "scholdoc" || prg == "scholpandoc")++ let (actions, args, errors) = if compatMode+ then ([], rawArgs, [])+ else getOpt Permute options rawArgs++ unless (null errors) $+ err 2 $ concat $ errors +++ ["Try " ++ prg ++ " --help for more information."]++ let preventScholarly = "--emulate-pandoc" `elem` rawArgs++ let defaultOpts' = if compatMode+ then defaultOpts { optReader = "markdown_strict"+ , optWriter = "html"+ , optEmailObfuscation =+ ReferenceObfuscation }+ else if scholarlyPandoc && not preventScholarly+ then defaultOpts { optReader = "markdown_scholarly"+ , optSmart = True+ , optParseRaw = True+ , optStandalone = True+ , optHTMLMathMethod = MathJax ""+ }+ else defaultOpts++ -- thread option data structure through all supplied option actions+ opts <- foldl (>>=) (return defaultOpts') actions++ let Opt { optTabStop = tabStop+ , optPreserveTabs = preserveTabs+ , optStandalone = standalone+ , optReader = readerName+ , optWriter = writerName+ , optParseRaw = parseRaw+ , optVariables = variables+ , optMetadata = metadata+ , optTableOfContents = toc+ , optTransforms = transforms+ , optTemplate = templatePath+ , optOutputFile = outputFile+ , optNumberSections = numberSections+ , optNumberOffset = numberFrom+ , optSectionDivs = sectionDivs+ , optIncremental = incremental+ , optSelfContained = selfContained+ , optSmart = smart+ , optOldDashes = oldDashes+ , optHtml5 = html5+ , optHtmlQTags = htmlQTags+ , optHighlight = highlight+ , optHighlightStyle = highlightStyle+ , optChapters = chapters+ , optHTMLMathMethod = mathMethod'+ , optUseMathJaxCDN = useMathJaxCDN+ , optReferenceODT = referenceODT+ , optReferenceDocx = referenceDocx+ , optEpubStylesheet = epubStylesheet+ , optEpubMetadata = epubMetadata+ , optEpubFonts = epubFonts+ , optEpubChapterLevel = epubChapterLevel+ , optTOCDepth = epubTOCDepth+ , optDumpArgs = dumpArgs+ , optIgnoreArgs = ignoreArgs+ , optReferenceLinks = referenceLinks+ , optWrapText = wrap+ , optColumns = columns+ , optFilters = filters+ , optEmailObfuscation = obfuscationMethod+ , optIdentifierPrefix = idPrefix+ , optIndentedCodeClasses = codeBlockClasses+ , optDataDir = mbDataDir+ , optCiteMethod = citeMethod+ , optListings = listings+ , optLaTeXEngine = latexEngine+ , optSlideLevel = slideLevel+ , optSetextHeaders = setextHeaders+ , optAscii = ascii+ , optTeXLigatures = texLigatures+ , optDefaultImageExtension = defaultImageExtension+ , optExtractMedia = mbExtractMedia+ , optTrace = trace+ , optTrackChanges = trackChanges+ , optKaTeXStylesheet = katexStylesheet+ , optKaTeXJS = katexJS+ } = opts++ when dumpArgs $+ do UTF8.hPutStrLn stdout outputFile+ mapM_ (\arg -> UTF8.hPutStrLn stdout arg) args+ exitWith ExitSuccess++ let csscdn = "http://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.1.0/katex.min.css"+ let mathMethod =+ case (katexJS, katexStylesheet) of+ (Nothing, _) -> mathMethod'+ (Just js, ss) -> KaTeX js (fromMaybe csscdn ss)+++ -- --bibliography implies -F scholdoc-citeproc for backwards compatibility:+ let needsCiteproc = isJust (M.lookup "bibliography" metadata) &&+ optCiteMethod opts `notElem` [Natbib, Biblatex] &&+ "scholdoc-citeproc" `notElem` map takeBaseName filters+ let filters' = if needsCiteproc then "scholdoc-citeproc" : filters+ else filters++ let sources = if ignoreArgs then [] else args++ datadir <- case mbDataDir of+ Nothing -> E.catch+ (Just <$> getAppUserDataDirectory "scholdoc")+ (\e -> let _ = (e :: E.SomeException)+ in return Nothing)+ Just _ -> return mbDataDir++ -- assign reader and writer based on options and filenames+ let readerName' = case map toLower readerName of+ [] -> defaultReaderName+ (if any isURI sources+ then "html"+ else "markdown") sources+ "html4" -> "html"+ x -> x++ let scholarlyMode = if readerName' == "markdown_scholarly"+ then True+ else False++ -- postepending "_bodyonly" to a writer enables a special "body-only" template+ let (writerNameTrim, bodyOnly) = case T.stripSuffix (T.pack "_bodyonly")+ (T.pack $ map toLower writerName) of+ Just w -> (T.unpack w, True)+ Nothing -> (writerName, False)++ let writerName' = case map toLower writerNameTrim of+ -- ScholMD defaults to html5+ [] -> case defaultWriterName outputFile of+ "html" -> if scholarlyMode+ then "html5"+ else "html"+ x -> x+ "epub2" -> "epub"+ "html4" -> "html"+ -- ScholMD only implemented for html5+ "html" -> if scholarlyMode then "html5" else "html"+ x -> x++ let pdfOutput = map toLower (takeExtension outputFile) == ".pdf"++ let laTeXOutput = "latex" `isPrefixOf` writerName' ||+ "beamer" `isPrefixOf` writerName'++ writer <- if ".lua" `isSuffixOf` writerName'+ -- note: use non-lowercased version writerName+ then return $ IOStringWriter $ writeCustom writerName+ else case getWriter writerName' of+ Left e -> err 9 $+ if writerName' == "pdf"+ then e +++ "\nTo create a pdf with pandoc, use " +++ "the latex or beamer writer and specify\n" +++ "an output file with .pdf extension " +++ "(pandoc -t latex -o filename.pdf)."+ else e+ Right w -> return w++ reader <- case getReader readerName' of+ Right r -> return r+ Left e -> err 7 e++ let standalone' = standalone || not (isTextFormat writerName') || pdfOutput++ -- Begin Scholarly Markdown specific settings+ when scholarlyMode $ do+ unless (writerName' `elem` ["html5","dzslides","revealjs","s5","slidy","slideous","latex","beamer","native","json","docx"])+ $ err 101 "Scholarly Markdown currently only renders to html5, latex/pdf, or native/json"+ case mathMethod of+ MathJax _ -> return ()+ PlainMath -> return ()+ _ -> warn "Scholarly Markdown relies on MathJax for HTML output, switching to MathJax..."+ >> return ()++ let (templatePath', standalone'') = if scholarlyMode && isNothing templatePath+ then if standalone' && not bodyOnly+ then case writerName' of+ "html5" -> (Just "scholmdTemplate.html5", True)+ "latex" -> (Just "scholmdTemplate.latex", True)+ _ -> (Nothing, True)+ else if bodyOnly+ then case writerName' of+ -- needed to conform to scholmd schema, and also+ -- for math definitions and MathJax settings+ "html5" -> (Just "scholmdTemplate_bodyOnly.html5", True)+ _ -> (Nothing, standalone')+ else (Nothing, standalone')+ else (templatePath, standalone')++ let scholdocMathJaxCDN = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full"++ let checkMathJaxCDN (MathJax "") = if useMathJaxCDN+ then MathJax scholdocMathJaxCDN+ else MathJax ""+ checkMathJaxCDN (MathJax a) = MathJax a+ checkMathJaxCDN PlainMath = PlainMath+ checkMathJaxCDN _ = checkMathJaxCDN (MathJax "") -- force using MathJax++ let mathMethod'' = if not scholarlyMode+ then mathMethod+ else checkMathJaxCDN mathMethod++ -- ScholMD always assume h1=Chapter, h2=Section, etc...+ let chapters' = if scholarlyMode && writerName' == "latex"+ then True+ else chapters++ -- ScholMD always assume, if not specified, that the default+ -- image file extension is PDF+ let defaultImageExtension' = if scholarlyMode && null defaultImageExtension+ then "pdf"+ else defaultImageExtension++ -- End Scholarly Markdown specific settings++ templ <- case templatePath' of+ _ | not standalone'' -> return ""+ Nothing -> do+ deftemp <- getDefaultTemplate datadir writerName'+ case deftemp of+ Left e -> throwIO e+ Right t -> return t+ Just tp -> do+ -- strip off extensions+ let format = takeWhile (`notElem` "+-") writerName'+ let tp' = case takeExtension tp of+ "" -> tp <.> format+ _ -> tp+ E.catch (UTF8.readFile tp')+ (\e -> if isDoesNotExistError e+ then E.catch+ (readDataFileUTF8 datadir+ ("templates" </> tp'))+ (\e' -> let _ = (e' :: E.SomeException)+ in throwIO e')+ else throwIO e)++ variables' <- case mathMethod'' of+ LaTeXMathML Nothing -> do+ s <- readDataFileUTF8 datadir "LaTeXMathML.js"+ return $ ("mathml-script", s) : variables+ MathML Nothing -> do+ s <- readDataFileUTF8 datadir "MathMLinHTML.js"+ return $ ("mathml-script", s) : variables+ _ -> return variables++ variables'' <- if "dzslides" `isPrefixOf` writerName'+ then do+ dztempl <- readDataFileUTF8 datadir+ ("dzslides" </> "template.html")+ let dzline = "<!-- {{{{ dzslides core"+ let dzcore = unlines+ $ dropWhile (not . (dzline `isPrefixOf`))+ $ lines dztempl+ return $ ("dzslides-core", dzcore) : variables'+ else return variables'++ let sourceURL = case sources of+ [] -> Nothing+ (x:_) -> case parseURI x of+ Just u+ | uriScheme u `elem` ["http:","https:"] ->+ Just $ show u{ uriQuery = "",+ uriFragment = "" }+ _ -> Nothing++ let readerOpts = def{ readerSmart = smart || (texLigatures &&+ (laTeXOutput || "context" `isPrefixOf` writerName'))+ , readerStandalone = standalone''+ , readerParseRaw = parseRaw+ , readerColumns = columns+ , readerTabStop = tabStop+ , readerOldDashes = oldDashes+ , readerIndentedCodeClasses = codeBlockClasses+ , readerApplyMacros = not laTeXOutput+ , readerDefaultImageExtension = defaultImageExtension'+ , readerTrace = trace+ , readerTrackChanges = trackChanges+ }++ when (not (isTextFormat writerName') && outputFile == "-") $+ err 5 $ "Cannot write " ++ writerName' ++ " output to stdout.\n" +++ "Specify an output file using the -o option."++ let readSources [] = mapM readSource ["-"]+ readSources srcs = mapM readSource srcs+ readSource "-" = UTF8.getContents+ readSource src = case parseURI src of+ Just u | uriScheme u `elem` ["http:","https:"] ->+ readURI src+ _ -> UTF8.readFile src+ readURI src = do+ res <- openURL src+ case res of+ Left e -> throwIO e+ Right (bs,_) -> return $ UTF8.toString bs++ let readFiles [] = error "Cannot read archive from stdin"+ readFiles (x:_) = B.readFile x++ let convertTabs = tabFilter (if preserveTabs || readerName' == "t2t"+ then 0+ else tabStop)++ let handleIncludes' = if readerName' == "latex" ||+ readerName' == "latex+lhs"+ then handleIncludes+ else return++ (doc, media) <-+ case reader of+ StringReader r-> (, mempty) <$>+ ( readSources >=>+ handleIncludes' . convertTabs . intercalate "\n" >=>+ r readerOpts ) sources+ ByteStringReader r -> readFiles sources >>= r readerOpts++ let writerOptions = def { writerStandalone = standalone'',+ writerTemplate = templ,+ writerVariables = variables'',+ writerTabStop = tabStop,+ writerTableOfContents = toc,+ writerHTMLMathMethod = mathMethod'',+ writerIncremental = incremental,+ writerCiteMethod = citeMethod,+ writerIgnoreNotes = False,+ writerNumberSections = numberSections,+ writerNumberOffset = numberFrom,+ writerSectionDivs = sectionDivs,+ writerReferenceLinks = referenceLinks,+ writerWrapText = wrap,+ writerColumns = columns,+ writerEmailObfuscation = obfuscationMethod,+ writerIdentifierPrefix = idPrefix,+ writerSourceURL = sourceURL,+ writerUserDataDir = datadir,+ writerHtml5 = html5,+ writerHtmlQTags = htmlQTags,+ writerChapters = chapters',+ writerListings = listings,+ writerBeamer = False,+ writerSlideLevel = slideLevel,+ writerHighlight = highlight,+ writerHighlightStyle = highlightStyle,+ writerSetextHeaders = setextHeaders,+ writerTeXLigatures = texLigatures,+ writerEpubMetadata = epubMetadata,+ writerEpubStylesheet = epubStylesheet,+ writerEpubFonts = epubFonts,+ writerEpubChapterLevel = epubChapterLevel,+ writerTOCDepth = epubTOCDepth,+ writerReferenceODT = referenceODT,+ writerReferenceDocx = referenceDocx,+ writerScholarly = scholarlyMode,+ writerMediaBag = media+ }+++ doc' <- (maybe return (extractMedia media) mbExtractMedia >=>+ adjustMetadata metadata >=>+ applyTransforms transforms >=>+ applyFilters filters' [writerName']) doc++ let writeBinary :: B.ByteString -> IO ()+ writeBinary = B.writeFile (UTF8.encodePath outputFile)++ let writerFn :: FilePath -> String -> IO ()+ writerFn "-" = UTF8.putStr+ writerFn f = UTF8.writeFile f++ case writer of+ IOStringWriter f -> f writerOptions doc' >>= writerFn outputFile+ IOByteStringWriter f -> f writerOptions doc' >>= writeBinary+ PureStringWriter f+ | pdfOutput -> do+ -- make sure writer is latex or beamer+ unless laTeXOutput $+ err 47 $ "cannot produce pdf output with " ++ writerName' +++ " writer"++ -- check for latex program+ mbLatex <- findExecutable latexEngine+ when (mbLatex == Nothing) $+ err 41 $ latexEngine ++ " not found. " +++ latexEngine ++ " is needed for pdf output."++ res <- makePDF latexEngine f writerOptions doc'+ case res of+ Right pdf -> writeBinary pdf+ Left err' -> do+ B.hPutStr stderr $ err'+ B.hPut stderr $ B.pack [10]+ err 43 "Error producing PDF from TeX source"+ | otherwise -> selfcontain (f writerOptions doc' +++ ['\n' | not standalone''])+ >>= writerFn outputFile . handleEntities+ where htmlFormat = writerName' `elem`+ ["html","html+lhs","html5","html5+lhs",+ "s5","slidy","slideous","dzslides","revealjs"]+ selfcontain = if selfContained && htmlFormat+ then makeSelfContained writerOptions+ else return+ handleEntities = if htmlFormat && ascii+ then toEntities+ else id
@@ -0,0 +1,273 @@+{-# LANGUAGE ScopedTypeVariables, FlexibleInstances #-}+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>+Copyright (C) 2014 Tim T.Y. Lin <timtylin@gmail.com>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++This helper module exports the main writers, readers, and data+structure definitions from the Pandoc libraries.++A typical application will chain together a reader and a writer+to convert strings from one format to another. For example, the+following simple program will act as a filter converting markdown+fragments to reStructuredText, using reference-style links instead of+inline links:++> module Main where+> import Text.Pandoc+>+> markdownToRST :: String -> String+> markdownToRST =+> (writeRST def {writerReferenceLinks = True}) . readMarkdown def+>+> main = getContents >>= putStrLn . markdownToRST++Note: all of the readers assume that the input text has @'\n'@+line endings. So if you get your input text from a web form,+you should remove @'\r'@ characters using @filter (/='\r')@.++-}++module Text.Pandoc+ (+ -- * Definitions+ module Text.Pandoc.Definition+ -- * Generics+ , module Text.Pandoc.Generic+ -- * Options+ , module Text.Pandoc.Options+ -- * Lists of readers and writers+ , readers+ , writers+ -- * Readers: converting /to/ Pandoc format+ , Reader (..)+ , mkStringReader+ , readMarkdown+ , readLaTeX+ , readHtml+ , readNative+ , readJSON+ -- * Writers: converting /from/ Pandoc format+ , Writer (..)+ , writeNative+ , writeJSON+ , writeMarkdown+ , writePlain+ , writeLaTeX+ , writeHtml+ , writeHtmlString+ , writeMan+ , writeDocx+ , writeHaddock+ , writeCustom+ -- * Rendering templates and default templates+ , module Text.Pandoc.Templates+ -- * Version+ , pandocVersion+ -- * Miscellaneous+ , getReader+ , getWriter+ , ToJsonFilter(..)+ ) where++import Text.Pandoc.Definition+import Text.Pandoc.Generic+import Text.Pandoc.JSON+import Text.Pandoc.Readers.Markdown+import Text.Pandoc.Readers.LaTeX+import Text.Pandoc.Readers.HTML+import Text.Pandoc.Readers.Native+import Text.Pandoc.Writers.Native+import Text.Pandoc.Writers.Markdown+import Text.Pandoc.Writers.LaTeX+import Text.Pandoc.Writers.HTML+import Text.Pandoc.Writers.Docx+import Text.Pandoc.Writers.Man+import Text.Pandoc.Writers.Haddock+import Text.Pandoc.Writers.Custom+import Text.Pandoc.Templates+import Text.Pandoc.Options+import Text.Pandoc.Shared (safeRead, warn)+import Text.Pandoc.MediaBag (MediaBag)+import Data.Aeson+import qualified Data.ByteString.Lazy as BL+import Data.List (intercalate)+import Data.Version (showVersion)+import Data.Set (Set)+import qualified Data.Set as Set+import Text.Parsec+import Text.Parsec.Error+import qualified Text.Pandoc.UTF8 as UTF8+import Paths_scholdoc (version)++-- | Version number of pandoc library.+pandocVersion :: String+pandocVersion = showVersion version++parseFormatSpec :: String+ -> Either ParseError (String, Set Extension -> Set Extension)+parseFormatSpec = parse formatSpec ""+ where formatSpec = do+ name <- formatName+ extMods <- many extMod+ return (name, foldl (.) id extMods)+ formatName = many1 $ noneOf "-+"+ extMod = do+ polarity <- oneOf "-+"+ name <- many $ noneOf "-+"+ ext <- case safeRead ("Ext_" ++ name) of+ Just n -> return n+ Nothing+ | name == "lhs" -> return Ext_literate_haskell+ | otherwise -> fail $ "Unknown extension: " ++ name+ return $ case polarity of+ '-' -> Set.delete ext+ _ -> Set.insert ext++-- auxiliary function for readers:+markdown :: ReaderOptions -> String -> IO Pandoc+markdown o s = do+ let (doc, warnings) = readMarkdownWithWarnings o s+ mapM_ warn warnings+ return doc++data Reader = StringReader (ReaderOptions -> String -> IO Pandoc)+ | ByteStringReader (ReaderOptions -> BL.ByteString -> IO (Pandoc, MediaBag))++mkStringReader :: (ReaderOptions -> String -> Pandoc) -> Reader+mkStringReader r = StringReader (\o s -> return $ r o s)++-- | Association list of formats and readers.+readers :: [(String, Reader)]+readers = [ ("native" , StringReader $ \_ s -> return $ readNative s)+ ,("json" , mkStringReader readJSON )+ ,("markdown" , StringReader markdown)+ ,("markdown_strict" , StringReader markdown)+ ,("markdown_phpextra" , StringReader markdown)+ ,("markdown_github" , StringReader markdown)+ ,("markdown_mmd", StringReader markdown)+ ,("markdown_scholarly", StringReader markdown)+ ]++data Writer = PureStringWriter (WriterOptions -> Pandoc -> String)+ | IOStringWriter (WriterOptions -> Pandoc -> IO String)+ | IOByteStringWriter (WriterOptions -> Pandoc -> IO BL.ByteString)++-- | Association list of formats and writers.+writers :: [ ( String, Writer ) ]+writers = [+ ("native" , PureStringWriter writeNative)+ ,("json" , PureStringWriter writeJSON)+ ,("docx" , IOByteStringWriter writeDocx)+ ,("html" , PureStringWriter writeHtmlString)+ ,("html5" , PureStringWriter $ \o ->+ writeHtmlString o{ writerHtml5 = True })+ -- ,("icml" , PureStringWriter writeICML)+ ,("s5" , PureStringWriter $ \o ->+ writeHtmlString o{ writerSlideVariant = S5Slides+ , writerTableOfContents = False })+ ,("slidy" , PureStringWriter $ \o ->+ writeHtmlString o{ writerSlideVariant = SlidySlides })+ ,("slideous" , PureStringWriter $ \o ->+ writeHtmlString o{ writerSlideVariant = SlideousSlides })+ ,("dzslides" , PureStringWriter $ \o ->+ writeHtmlString o{ writerSlideVariant = DZSlides+ , writerHtml5 = True })+ ,("revealjs" , PureStringWriter $ \o ->+ writeHtmlString o{ writerSlideVariant = RevealJsSlides+ , writerHtml5 = True })+ ,("latex" , PureStringWriter writeLaTeX)+ ,("beamer" , PureStringWriter $ \o ->+ writeLaTeX o{ writerBeamer = True })+ ,("man" , PureStringWriter writeMan)+ ,("markdown" , PureStringWriter writeMarkdown)+ ,("markdown_strict" , PureStringWriter writeMarkdown)+ ,("markdown_phpextra" , PureStringWriter writeMarkdown)+ ,("markdown_github" , PureStringWriter writeMarkdown)+ ,("markdown_mmd" , PureStringWriter writeMarkdown)+ ,("markdown_scholarly" , PureStringWriter writeMarkdown)+ ,("plain" , PureStringWriter writePlain)+ ,("haddock" , PureStringWriter writeHaddock)+ ]++getDefaultExtensions :: String -> Set Extension+getDefaultExtensions "markdown_strict" = strictExtensions+getDefaultExtensions "markdown_phpextra" = phpMarkdownExtraExtensions+getDefaultExtensions "markdown_mmd" = multimarkdownExtensions+getDefaultExtensions "markdown_github" = githubMarkdownExtensions+getDefaultExtensions "markdown_scholarly" = scholarlyMarkdownExtensions+getDefaultExtensions "markdown" = pandocExtensions+getDefaultExtensions "plain" = pandocExtensions+getDefaultExtensions "html" = Set.fromList [Ext_auto_identifiers,+ Ext_native_divs,+ Ext_native_spans]+getDefaultExtensions "html5" = getDefaultExtensions "html"+getDefaultExtensions _ = Set.fromList [Ext_auto_identifiers]++-- | Retrieve reader based on formatSpec (format+extensions).+getReader :: String -> Either String Reader+getReader s =+ case parseFormatSpec s of+ Left e -> Left $ intercalate "\n" $ [m | Message m <- errorMessages e]+ Right (readerName, setExts) ->+ case lookup readerName readers of+ Nothing -> Left $ "Unknown reader: " ++ readerName+ Just (StringReader r) -> Right $ StringReader $ \o ->+ r o{ readerExtensions = setExts $+ getDefaultExtensions readerName }+ Just (ByteStringReader r) -> Right $ ByteStringReader $ \o ->+ r o{ readerExtensions = setExts $+ getDefaultExtensions readerName }++-- | Retrieve writer based on formatSpec (format+extensions).+getWriter :: String -> Either String Writer+getWriter s+ = case parseFormatSpec s of+ Left e -> Left $ intercalate "\n" $ [m | Message m <- errorMessages e]+ Right (writerName, setExts) ->+ case lookup writerName writers of+ Nothing -> Left $ "Unknown writer: " ++ writerName+ Just (PureStringWriter r) -> Right $ PureStringWriter $+ \o -> r o{ writerExtensions = setExts $+ getDefaultExtensions writerName }+ Just (IOStringWriter r) -> Right $ IOStringWriter $+ \o -> r o{ writerExtensions = setExts $+ getDefaultExtensions writerName }+ Just (IOByteStringWriter r) -> Right $ IOByteStringWriter $+ \o -> r o{ writerExtensions = setExts $+ getDefaultExtensions writerName }++{-# DEPRECATED toJsonFilter "Use 'toJSONFilter' from 'Text.Pandoc.JSON' instead" #-}+-- | Deprecated. Use @toJSONFilter@ from @Text.Pandoc.JSON@ instead.+class ToJSONFilter a => ToJsonFilter a+ where toJsonFilter :: a -> IO ()+ toJsonFilter = toJSONFilter++readJSON :: ReaderOptions -> String -> Pandoc+readJSON _ = either error id . eitherDecode' . UTF8.fromStringLazy++writeJSON :: WriterOptions -> Pandoc -> String+writeJSON _ = UTF8.toStringLazy . encode
@@ -0,0 +1,422 @@+{-+Copyright (C) 2013-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Asciify+ Copyright : Copyright (C) 2013-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Function to convert accented latin letters to their unaccented+ascii equivalents (used in constructing HTML identifiers).+-}+module Text.Pandoc.Asciify (toAsciiChar)+where+import qualified Data.Map as M+import Data.Char (isAscii)++toAsciiChar :: Char -> Maybe Char+toAsciiChar c | isAscii c = Just c+ | otherwise = M.lookup c asciiMap++asciiMap :: M.Map Char Char+asciiMap = M.fromList+ [('\192','A')+ ,('\193','A')+ ,('\194','A')+ ,('\195','A')+ ,('\196','A')+ ,('\197','A')+ ,('\199','C')+ ,('\200','E')+ ,('\201','E')+ ,('\202','E')+ ,('\203','E')+ ,('\204','I')+ ,('\205','I')+ ,('\206','I')+ ,('\207','I')+ ,('\209','N')+ ,('\210','O')+ ,('\211','O')+ ,('\212','O')+ ,('\213','O')+ ,('\214','O')+ ,('\217','U')+ ,('\218','U')+ ,('\219','U')+ ,('\220','U')+ ,('\221','Y')+ ,('\224','a')+ ,('\225','a')+ ,('\226','a')+ ,('\227','a')+ ,('\228','a')+ ,('\229','a')+ ,('\231','c')+ ,('\232','e')+ ,('\233','e')+ ,('\234','e')+ ,('\235','e')+ ,('\236','i')+ ,('\237','i')+ ,('\238','i')+ ,('\239','i')+ ,('\241','n')+ ,('\242','o')+ ,('\243','o')+ ,('\244','o')+ ,('\245','o')+ ,('\246','o')+ ,('\249','u')+ ,('\250','u')+ ,('\251','u')+ ,('\252','u')+ ,('\253','y')+ ,('\255','y')+ ,('\256','A')+ ,('\257','a')+ ,('\258','A')+ ,('\259','a')+ ,('\260','A')+ ,('\261','a')+ ,('\262','C')+ ,('\263','c')+ ,('\264','C')+ ,('\265','c')+ ,('\266','C')+ ,('\267','c')+ ,('\268','C')+ ,('\269','c')+ ,('\270','D')+ ,('\271','d')+ ,('\274','E')+ ,('\275','e')+ ,('\276','E')+ ,('\277','e')+ ,('\278','E')+ ,('\279','e')+ ,('\280','E')+ ,('\281','e')+ ,('\282','E')+ ,('\283','e')+ ,('\284','G')+ ,('\285','g')+ ,('\286','G')+ ,('\287','g')+ ,('\288','G')+ ,('\289','g')+ ,('\290','G')+ ,('\291','g')+ ,('\292','H')+ ,('\293','h')+ ,('\296','I')+ ,('\297','i')+ ,('\298','I')+ ,('\299','i')+ ,('\300','I')+ ,('\301','i')+ ,('\302','I')+ ,('\303','i')+ ,('\304','I')+ ,('\308','J')+ ,('\309','j')+ ,('\310','K')+ ,('\311','k')+ ,('\313','L')+ ,('\314','l')+ ,('\315','L')+ ,('\316','l')+ ,('\317','L')+ ,('\318','l')+ ,('\323','N')+ ,('\324','n')+ ,('\325','N')+ ,('\326','n')+ ,('\327','N')+ ,('\328','n')+ ,('\332','O')+ ,('\333','o')+ ,('\334','O')+ ,('\335','o')+ ,('\336','O')+ ,('\337','o')+ ,('\340','R')+ ,('\341','r')+ ,('\342','R')+ ,('\343','r')+ ,('\344','R')+ ,('\345','r')+ ,('\346','S')+ ,('\347','s')+ ,('\348','S')+ ,('\349','s')+ ,('\350','S')+ ,('\351','s')+ ,('\352','S')+ ,('\353','s')+ ,('\354','T')+ ,('\355','t')+ ,('\356','T')+ ,('\357','t')+ ,('\360','U')+ ,('\361','u')+ ,('\362','U')+ ,('\363','u')+ ,('\364','U')+ ,('\365','u')+ ,('\366','U')+ ,('\367','u')+ ,('\368','U')+ ,('\369','u')+ ,('\370','U')+ ,('\371','u')+ ,('\372','W')+ ,('\373','w')+ ,('\374','Y')+ ,('\375','y')+ ,('\376','Y')+ ,('\377','Z')+ ,('\378','z')+ ,('\379','Z')+ ,('\380','z')+ ,('\381','Z')+ ,('\382','z')+ ,('\416','O')+ ,('\417','o')+ ,('\431','U')+ ,('\432','u')+ ,('\461','A')+ ,('\462','a')+ ,('\463','I')+ ,('\464','i')+ ,('\465','O')+ ,('\466','o')+ ,('\467','U')+ ,('\468','u')+ ,('\486','G')+ ,('\487','g')+ ,('\488','K')+ ,('\489','k')+ ,('\490','O')+ ,('\491','o')+ ,('\496','j')+ ,('\500','G')+ ,('\501','g')+ ,('\504','N')+ ,('\505','n')+ ,('\512','A')+ ,('\513','a')+ ,('\514','A')+ ,('\515','a')+ ,('\516','E')+ ,('\517','e')+ ,('\518','E')+ ,('\519','e')+ ,('\520','I')+ ,('\521','i')+ ,('\522','I')+ ,('\523','i')+ ,('\524','O')+ ,('\525','o')+ ,('\526','O')+ ,('\527','o')+ ,('\528','R')+ ,('\529','r')+ ,('\530','R')+ ,('\531','r')+ ,('\532','U')+ ,('\533','u')+ ,('\534','U')+ ,('\535','u')+ ,('\536','S')+ ,('\537','s')+ ,('\538','T')+ ,('\539','t')+ ,('\542','H')+ ,('\543','h')+ ,('\550','A')+ ,('\551','a')+ ,('\552','E')+ ,('\553','e')+ ,('\558','O')+ ,('\559','o')+ ,('\562','Y')+ ,('\563','y')+ ,('\894',';')+ ,('\7680','A')+ ,('\7681','a')+ ,('\7682','B')+ ,('\7683','b')+ ,('\7684','B')+ ,('\7685','b')+ ,('\7686','B')+ ,('\7687','b')+ ,('\7690','D')+ ,('\7691','d')+ ,('\7692','D')+ ,('\7693','d')+ ,('\7694','D')+ ,('\7695','d')+ ,('\7696','D')+ ,('\7697','d')+ ,('\7698','D')+ ,('\7699','d')+ ,('\7704','E')+ ,('\7705','e')+ ,('\7706','E')+ ,('\7707','e')+ ,('\7710','F')+ ,('\7711','f')+ ,('\7712','G')+ ,('\7713','g')+ ,('\7714','H')+ ,('\7715','h')+ ,('\7716','H')+ ,('\7717','h')+ ,('\7718','H')+ ,('\7719','h')+ ,('\7720','H')+ ,('\7721','h')+ ,('\7722','H')+ ,('\7723','h')+ ,('\7724','I')+ ,('\7725','i')+ ,('\7728','K')+ ,('\7729','k')+ ,('\7730','K')+ ,('\7731','k')+ ,('\7732','K')+ ,('\7733','k')+ ,('\7734','L')+ ,('\7735','l')+ ,('\7738','L')+ ,('\7739','l')+ ,('\7740','L')+ ,('\7741','l')+ ,('\7742','M')+ ,('\7743','m')+ ,('\7744','M')+ ,('\7745','m')+ ,('\7746','M')+ ,('\7747','m')+ ,('\7748','N')+ ,('\7749','n')+ ,('\7750','N')+ ,('\7751','n')+ ,('\7752','N')+ ,('\7753','n')+ ,('\7754','N')+ ,('\7755','n')+ ,('\7764','P')+ ,('\7765','p')+ ,('\7766','P')+ ,('\7767','p')+ ,('\7768','R')+ ,('\7769','r')+ ,('\7770','R')+ ,('\7771','r')+ ,('\7774','R')+ ,('\7775','r')+ ,('\7776','S')+ ,('\7777','s')+ ,('\7778','S')+ ,('\7779','s')+ ,('\7786','T')+ ,('\7787','t')+ ,('\7788','T')+ ,('\7789','t')+ ,('\7790','T')+ ,('\7791','t')+ ,('\7792','T')+ ,('\7793','t')+ ,('\7794','U')+ ,('\7795','u')+ ,('\7796','U')+ ,('\7797','u')+ ,('\7798','U')+ ,('\7799','u')+ ,('\7804','V')+ ,('\7805','v')+ ,('\7806','V')+ ,('\7807','v')+ ,('\7808','W')+ ,('\7809','w')+ ,('\7810','W')+ ,('\7811','w')+ ,('\7812','W')+ ,('\7813','w')+ ,('\7814','W')+ ,('\7815','w')+ ,('\7816','W')+ ,('\7817','w')+ ,('\7818','X')+ ,('\7819','x')+ ,('\7820','X')+ ,('\7821','x')+ ,('\7822','Y')+ ,('\7823','y')+ ,('\7824','Z')+ ,('\7825','z')+ ,('\7826','Z')+ ,('\7827','z')+ ,('\7828','Z')+ ,('\7829','z')+ ,('\7830','h')+ ,('\7831','t')+ ,('\7832','w')+ ,('\7833','y')+ ,('\7840','A')+ ,('\7841','a')+ ,('\7842','A')+ ,('\7843','a')+ ,('\7864','E')+ ,('\7865','e')+ ,('\7866','E')+ ,('\7867','e')+ ,('\7868','E')+ ,('\7869','e')+ ,('\7880','I')+ ,('\7881','i')+ ,('\7882','I')+ ,('\7883','i')+ ,('\7884','O')+ ,('\7885','o')+ ,('\7886','O')+ ,('\7887','o')+ ,('\7908','U')+ ,('\7909','u')+ ,('\7910','U')+ ,('\7911','u')+ ,('\7922','Y')+ ,('\7923','y')+ ,('\7924','Y')+ ,('\7925','y')+ ,('\7926','Y')+ ,('\7927','y')+ ,('\7928','Y')+ ,('\7929','y')+ ,('\8175','`')+ ,('\8490','K')+ ,('\8800','=')+ ,('\8814','<')+ ,('\8815','>')+ ]
@@ -0,0 +1,21 @@+{-# LANGUAGE CPP #-}+module Text.Pandoc.Compat.Directory ( getModificationTime )+ where++#if MIN_VERSION_directory(1,2,0)+import System.Directory+++#else+import qualified System.Directory as S+import Data.Time.Clock (UTCTime)+import Data.Time.Clock.POSIX+import System.Time++getModificationTime :: FilePath -> IO UTCTime+getModificationTime fp = convert `fmap` S.getModificationTime fp+ where+ convert (TOD x _) = posixSecondsToUTCTime (realToFrac x)++#endif+
@@ -0,0 +1,37 @@+{-# LANGUAGE CPP #-}+module Text.Pandoc.Compat.Except ( ExceptT+ , Except+ , Error(..)+ , runExceptT+ , runExcept+ , MonadError+ , throwError+ , catchError )+ where++#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except++class Error a where+ noMsg :: a+ strMsg :: String -> a++ noMsg = strMsg ""+ strMsg _ = noMsg++#else+import Control.Monad.Error+import Control.Monad.Identity (Identity, runIdentity)++type ExceptT = ErrorT++type Except s a = ErrorT s Identity a++runExceptT :: ExceptT e m a -> m (Either e a)+runExceptT = runErrorT++runExcept :: ExceptT e Identity a -> Either e a+runExcept = runIdentity . runExceptT+#endif++
@@ -0,0 +1,20 @@+{-# LANGUAGE CPP #-}+module Text.Pandoc.Compat.Monoid ( Monoid(..)+ , (<>)+ ) where++#if MIN_VERSION_base(4,5,0)+import Data.Monoid ((<>), Monoid(..))+#else+import Data.Monoid (mappend, Monoid(..))+#endif++#if MIN_VERSION_base(4,5,0)+#else+infixr 6 <>++-- | An infix synonym for 'mappend'.+(<>) :: Monoid m => m -> m -> m+(<>) = mappend+{-# INLINE (<>) #-}+#endif
@@ -0,0 +1,15 @@+{-# LANGUAGE CPP #-}+module Text.Pandoc.Compat.TagSoupEntity (lookupEntity+ ) where++import qualified Text.HTML.TagSoup.Entity as TE++lookupEntity :: String -> Maybe Char+#if MIN_VERSION_tagsoup(0,13,0)+lookupEntity = str2chr . TE.lookupEntity+ where str2chr :: Maybe String -> Maybe Char+ str2chr (Just [c]) = Just c+ str2chr _ = Nothing+#else+lookupEntity = TE.lookupEntity+#endif
@@ -0,0 +1,7 @@+{-# LANGUAGE OverloadedStrings #-}+-- to be processed using hsb2hs+module Text.Pandoc.Data (dataFiles) where+import qualified Data.ByteString as B++dataFiles :: [(FilePath, B.ByteString)]+dataFiles = %blobs "data"
@@ -0,0 +1,154 @@+{-+Copyright (C) 2008-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Highlighting+ Copyright : Copyright (C) 2008-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Exports functions for syntax highlighting.+-}++module Text.Pandoc.Highlighting ( languages+ , languagesByExtension+ , highlight+ , formatLaTeXInline+ , formatLaTeXBlock+ , styleToLaTeX+ , formatHtmlInline+ , formatHtmlBlock+ , styleToCss+ , pygments+ , espresso+ , zenburn+ , tango+ , kate+ , monochrome+ , haddock+ , Style+ , fromListingsLanguage+ , toListingsLanguage+ ) where+import Text.Pandoc.Definition+import Text.Pandoc.Shared (safeRead)+import Text.Highlighting.Kate+import Data.List (find)+import Data.Maybe (fromMaybe)+import Data.Char (toLower)+import qualified Data.Map as M+import Control.Applicative ((<|>))++lcLanguages :: [String]+lcLanguages = map (map toLower) languages++highlight :: (FormatOptions -> [SourceLine] -> a) -- ^ Formatter+ -> Attr -- ^ Attributes of the CodeBlock+ -> String -- ^ Raw contents of the CodeBlock+ -> Maybe a -- ^ Maybe the formatted result+highlight formatter (_, classes, keyvals) rawCode =+ let firstNum = case safeRead (fromMaybe "1" $ lookup "startFrom" keyvals) of+ Just n -> n+ Nothing -> 1+ fmtOpts = defaultFormatOpts{+ startNumber = firstNum,+ numberLines = any (`elem`+ ["number","numberLines", "number-lines"]) classes }+ lcclasses = map (map toLower) classes+ in case find (`elem` lcLanguages) lcclasses of+ Nothing+ | numberLines fmtOpts -> Just+ $ formatter fmtOpts{ codeClasses = [],+ containerClasses = classes }+ $ map (\ln -> [(NormalTok, ln)]) $ lines rawCode+ | otherwise -> Nothing+ Just language -> Just+ $ formatter fmtOpts{ codeClasses = [language],+ containerClasses = classes }+ $ highlightAs language rawCode++-- Functions for correlating latex listings package's language names+-- with highlighting-kate language names:++langToListingsMap :: M.Map String String+langToListingsMap = M.fromList langsList++listingsToLangMap :: M.Map String String+listingsToLangMap = M.fromList $ map switch langsList+ where switch (a,b) = (b,a)++langsList :: [(String, String)]+langsList = [("ada","Ada")+ ,("java","Java")+ ,("prolog","Prolog")+ ,("python","Python")+ ,("gnuassembler","Assembler")+ ,("commonlisp","Lisp")+ ,("r","R")+ ,("awk","Awk")+ ,("bash","bash")+ ,("makefile","make")+ ,("c","C")+ ,("matlab","Matlab")+ ,("ruby","Ruby")+ ,("cpp","C++")+ ,("ocaml","Caml")+ ,("modula2","Modula-2")+ ,("sql","SQL")+ ,("eiffel","Eiffel")+ ,("tcl","tcl")+ ,("erlang","erlang")+ ,("verilog","Verilog")+ ,("fortran","Fortran")+ ,("vhdl","VHDL")+ ,("pascal","Pascal")+ ,("perl","Perl")+ ,("xml","XML")+ ,("haskell","Haskell")+ ,("php","PHP")+ ,("xslt","XSLT")+ ,("html","HTML")+ ]++listingsLangs :: [String]+listingsLangs = ["Ada","Java","Prolog","Algol","JVMIS","Promela",+ "Ant","ksh","Python","Assembler","Lisp","R","Awk",+ "Logo","Reduce","bash","make","Rexx","Basic",+ "Mathematica","RSL","C","Matlab","Ruby","C++",+ "Mercury","S","Caml","MetaPost","SAS","Clean",+ "Miranda","Scilab","Cobol","Mizar","sh","Comal",+ "ML","SHELXL","csh","Modula-2","Simula","Delphi",+ "MuPAD","SQL","Eiffel","NASTRAN","tcl","Elan",+ "Oberon-2","TeX","erlang","OCL","VBScript","Euphoria",+ "Octave","Verilog","Fortran","Oz","VHDL","GCL",+ "Pascal","VRML","Gnuplot","Perl","XML","Haskell",+ "PHP","XSLT","HTML","PL/I"]++-- Determine listings language name from highlighting-kate language name.+toListingsLanguage :: String -> Maybe String+toListingsLanguage lang = (if lang `elem` listingsLangs+ then Just lang+ else Nothing) <|>+ M.lookup (map toLower lang) langToListingsMap++-- Determine highlighting-kate language name from listings language name.+fromListingsLanguage :: String -> Maybe String+fromListingsLanguage lang = M.lookup lang listingsToLangMap
@@ -0,0 +1,399 @@+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}+{-+ Copyright (C) 2011-2014 John MacFarlane <jgm@berkeley.edu>++ This program is free software; you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation; either version 2 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful, but WITHOUT+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for+ more details.++ You should have received a copy of the GNU General Public License along+ with this program; if not, write to the Free Software Foundation, Inc., 59+ Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+Module : Text.Pandoc.ImageSize+Copyright : Copyright (C) 2011-2014 John MacFarlane+License : GNU GPL, version 2 or above++Maintainer : John MacFarlane <jgm@berkeley.edu>+Stability : alpha+Portability : portable++Functions for determining the size of a PNG, JPEG, or GIF image.+-}+module Text.Pandoc.ImageSize ( ImageType(..), imageType, imageSize,+ sizeInPixels, sizeInPoints ) where+import Data.ByteString (ByteString, unpack)+import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Lazy as BL+import Control.Applicative+import Control.Monad+import Data.Bits+import Data.Binary+import Data.Binary.Get+import Text.Pandoc.Shared (safeRead)+import qualified Data.Map as M++-- quick and dirty functions to get image sizes+-- algorithms borrowed from wwwis.pl++data ImageType = Png | Gif | Jpeg | Pdf | Eps deriving Show++data ImageSize = ImageSize{+ pxX :: Integer+ , pxY :: Integer+ , dpiX :: Integer+ , dpiY :: Integer+ } deriving (Read, Show, Eq)+++imageType :: ByteString -> Maybe ImageType+imageType img = case B.take 4 img of+ "\x89\x50\x4e\x47" -> return Png+ "\x47\x49\x46\x38" -> return Gif+ "\xff\xd8\xff\xe0" -> return Jpeg -- JFIF+ "\xff\xd8\xff\xe1" -> return Jpeg -- Exif+ "%PDF" -> return Pdf+ "%!PS"+ | (B.take 4 $ B.drop 1 $ B.dropWhile (/=' ') img) == "EPSF"+ -> return Eps+ _ -> fail "Unknown image type"++imageSize :: ByteString -> Maybe ImageSize+imageSize img = do+ t <- imageType img+ case t of+ Png -> pngSize img+ Gif -> gifSize img+ Jpeg -> jpegSize img+ Eps -> epsSize img+ Pdf -> Nothing -- TODO++defaultSize :: (Integer, Integer)+defaultSize = (72, 72)++sizeInPixels :: ImageSize -> (Integer, Integer)+sizeInPixels s = (pxX s, pxY s)++sizeInPoints :: ImageSize -> (Integer, Integer)+sizeInPoints s = (pxX s * 72 `div` dpiX s, pxY s * 72 `div` dpiY s)++epsSize :: ByteString -> Maybe ImageSize+epsSize img = do+ let ls = takeWhile ("%" `B.isPrefixOf`) $ B.lines img+ let ls' = dropWhile (not . ("%%BoundingBox:" `B.isPrefixOf`)) ls+ case ls' of+ [] -> mzero+ (x:_) -> case B.words x of+ (_:_:_:ux:uy:[]) -> do+ ux' <- safeRead $ B.unpack ux+ uy' <- safeRead $ B.unpack uy+ return ImageSize{+ pxX = ux'+ , pxY = uy'+ , dpiX = 72+ , dpiY = 72 }+ _ -> mzero++pngSize :: ByteString -> Maybe ImageSize+pngSize img = do+ let (h, rest) = B.splitAt 8 img+ guard $ h == "\x8a\x4d\x4e\x47\x0d\x0a\x1a\x0a" ||+ h == "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"+ let (i, rest') = B.splitAt 4 $ B.drop 4 rest+ guard $ i == "MHDR" || i == "IHDR"+ let (sizes, rest'') = B.splitAt 8 rest'+ (x,y) <- case map fromIntegral $ unpack $ sizes of+ ([w1,w2,w3,w4,h1,h2,h3,h4] :: [Integer]) -> return+ ((shift w1 24) + (shift w2 16) + (shift w3 8) + w4,+ (shift h1 24) + (shift h2 16) + (shift h3 8) + h4)+ _ -> fail "PNG parse error"+ let (dpix, dpiy) = findpHYs rest''+ return $ ImageSize { pxX = x, pxY = y, dpiX = dpix, dpiY = dpiy }++findpHYs :: ByteString -> (Integer, Integer)+findpHYs x =+ if B.null x || "IDAT" `B.isPrefixOf` x+ then (72,72) -- default, no pHYs+ else if "pHYs" `B.isPrefixOf` x+ then let [x1,x2,x3,x4,y1,y2,y3,y4,u] = map fromIntegral+ $ unpack $ B.take 9 $ B.drop 4 x+ factor = if u == 1 -- dots per meter+ then \z -> z * 254 `div` 10000+ else const 72+ in ( factor $ (shift x1 24) + (shift x2 16) + (shift x3 8) + x4,+ factor $ (shift y1 24) + (shift y2 16) + (shift y3 8) + y4 )+ else findpHYs $ B.drop 1 x -- read another byte++gifSize :: ByteString -> Maybe ImageSize+gifSize img = do+ let (h, rest) = B.splitAt 6 img+ guard $ h == "GIF87a" || h == "GIF89a"+ case map fromIntegral $ unpack $ B.take 4 rest of+ [w2,w1,h2,h1] -> return ImageSize {+ pxX = shift w1 8 + w2,+ pxY = shift h1 8 + h2,+ dpiX = 72,+ dpiY = 72+ }+ _ -> fail "GIF parse error"++jpegSize :: ByteString -> Maybe ImageSize+jpegSize img = do+ let (hdr, rest) = B.splitAt 4 img+ guard $ B.length rest >= 14+ case hdr of+ "\xff\xd8\xff\xe0" -> jfifSize rest+ "\xff\xd8\xff\xe1" -> exifSize $ B.takeWhile (/= '\xff') rest+ _ -> mzero++jfifSize :: ByteString -> Maybe ImageSize+jfifSize rest = do+ let [dpiDensity,dpix1,dpix2,dpiy1,dpiy2] = map fromIntegral+ $ unpack $ B.take 5 $ B.drop 9 $ rest+ let factor = case dpiDensity of+ 1 -> id+ 2 -> \x -> (x * 254 `div` 10)+ _ -> const 72+ let dpix = factor (shift dpix1 8 + dpix2)+ let dpiy = factor (shift dpiy1 8 + dpiy2)+ (w,h) <- findJfifSize rest+ return $ ImageSize { pxX = w, pxY = h, dpiX = dpix, dpiY = dpiy }++findJfifSize :: ByteString -> Maybe (Integer,Integer)+findJfifSize bs = do+ let bs' = B.dropWhile (=='\xff') $ B.dropWhile (/='\xff') bs+ case B.uncons bs' of+ Just (c,bs'') | c >= '\xc0' && c <= '\xc3' -> do+ case map fromIntegral $ unpack $ B.take 4 $ B.drop 3 bs'' of+ [h1,h2,w1,w2] -> return (shift w1 8 + w2, shift h1 8 + h2)+ _ -> fail "JPEG parse error"+ Just (_,bs'') -> do+ case map fromIntegral $ unpack $ B.take 2 bs'' of+ [c1,c2] -> do+ let len = shift c1 8 + c2+ -- skip variables+ findJfifSize $ B.drop len bs''+ _ -> fail "JPEG parse error"+ Nothing -> fail "Did not find length record"++exifSize :: ByteString -> Maybe ImageSize+exifSize bs = runGet (Just <$> exifHeader bl) bl+ where bl = BL.fromChunks [bs]+-- NOTE: It would be nicer to do+-- runGet ((Just <$> exifHeader) <|> return Nothing)+-- which would prevent pandoc from raising an error when an exif header can't+-- be parsed. But we only get an Alternative instance for Get in binary 0.6,+-- and binary 0.5 ships with ghc 7.6.++exifHeader :: BL.ByteString -> Get ImageSize+exifHeader hdr = do+ _app1DataSize <- getWord16be+ exifHdr <- getWord32be+ unless (exifHdr == 0x45786966) $ fail "Did not find exif header"+ zeros <- getWord16be+ unless (zeros == 0) $ fail "Expected zeros after exif header"+ -- beginning of tiff header -- we read whole thing to use+ -- in getting data from offsets:+ let tiffHeader = BL.drop 8 hdr+ byteAlign <- getWord16be+ let bigEndian = byteAlign == 0x4d4d+ let (getWord16, getWord32, getWord64) =+ if bigEndian+ then (getWord16be, getWord32be, getWord64be)+ else (getWord16le, getWord32le, getWord64le)+ let getRational = do+ num <- getWord32+ den <- getWord32+ return $ fromIntegral num / fromIntegral den+ tagmark <- getWord16+ unless (tagmark == 0x002a) $ fail "Failed alignment sanity check"+ ifdOffset <- getWord32+ skip (fromIntegral ifdOffset - 8) -- skip to IDF+ numentries <- getWord16+ let ifdEntry = do+ tag <- getWord16 >>= \t ->+ maybe (return UnknownTagType) return+ (M.lookup t tagTypeTable)+ dataFormat <- getWord16+ numComponents <- getWord32+ (fmt, bytesPerComponent) <-+ case dataFormat of+ 1 -> return (UnsignedByte . runGet getWord8, 1)+ 2 -> return (AsciiString, 1)+ 3 -> return (UnsignedShort . runGet getWord16, 2)+ 4 -> return (UnsignedLong . runGet getWord32, 4)+ 5 -> return (UnsignedRational . runGet getRational, 8)+ 6 -> return (SignedByte . runGet getWord8, 1)+ 7 -> return (Undefined . runGet getWord8, 1)+ 8 -> return (SignedShort . runGet getWord16, 2)+ 9 -> return (SignedLong . runGet getWord32, 4)+ 10 -> return (SignedRational . runGet getRational, 8)+ 11 -> return (SingleFloat . runGet getWord32 {- TODO -}, 4)+ 12 -> return (DoubleFloat . runGet getWord64 {- TODO -}, 8)+ _ -> fail $ "Unknown data format " ++ show dataFormat+ let totalBytes = fromIntegral $ numComponents * bytesPerComponent+ payload <- if totalBytes <= 4 -- data is right here+ then fmt <$>+ (getLazyByteString (fromIntegral totalBytes) <*+ skip (4 - totalBytes))+ else do -- get data from offset+ offs <- getWord32+ return $ fmt $ BL.take (fromIntegral totalBytes) $+ BL.drop (fromIntegral offs) tiffHeader+ return (tag, payload)+ entries <- sequence $ replicate (fromIntegral numentries) ifdEntry+ subentries <- case lookup ExifOffset entries of+ Just (UnsignedLong offset) -> do+ pos <- bytesRead+ skip (fromIntegral offset - (fromIntegral pos - 8))+ numsubentries <- getWord16+ sequence $+ replicate (fromIntegral numsubentries) ifdEntry+ _ -> return []+ let allentries = entries ++ subentries+ (width, height) <- case (lookup ExifImageWidth allentries,+ lookup ExifImageHeight allentries) of+ (Just (UnsignedLong w), Just (UnsignedLong h)) ->+ return (fromIntegral w, fromIntegral h)+ _ -> return defaultSize+ -- we return a default width and height when+ -- the exif header doesn't contain these+ let resfactor = case lookup ResolutionUnit allentries of+ Just (UnsignedShort 1) -> (100 / 254)+ _ -> 1+ let xres = maybe 72 (\(UnsignedRational x) -> floor $ x * resfactor)+ $ lookup XResolution allentries+ let yres = maybe 72 (\(UnsignedRational x) -> floor $ x * resfactor)+ $ lookup YResolution allentries+ return $ ImageSize{+ pxX = width+ , pxY = height+ , dpiX = xres+ , dpiY = yres }++data DataFormat = UnsignedByte Word8+ | AsciiString BL.ByteString+ | UnsignedShort Word16+ | UnsignedLong Word32+ | UnsignedRational Rational+ | SignedByte Word8+ | Undefined Word8+ | SignedShort Word16+ | SignedLong Word32+ | SignedRational Rational+ | SingleFloat Word32+ | DoubleFloat Word64+ deriving (Show)++data TagType = ImageDescription+ | Make+ | Model+ | Orientation+ | XResolution+ | YResolution+ | ResolutionUnit+ | Software+ | DateTime+ | WhitePoint+ | PrimaryChromaticities+ | YCbCrCoefficients+ | YCbCrPositioning+ | ReferenceBlackWhite+ | Copyright+ | ExifOffset+ | ExposureTime+ | FNumber+ | ExposureProgram+ | ISOSpeedRatings+ | ExifVersion+ | DateTimeOriginal+ | DateTimeDigitized+ | ComponentConfiguration+ | CompressedBitsPerPixel+ | ShutterSpeedValue+ | ApertureValue+ | BrightnessValue+ | ExposureBiasValue+ | MaxApertureValue+ | SubjectDistance+ | MeteringMode+ | LightSource+ | Flash+ | FocalLength+ | MakerNote+ | UserComment+ | FlashPixVersion+ | ColorSpace+ | ExifImageWidth+ | ExifImageHeight+ | RelatedSoundFile+ | ExifInteroperabilityOffset+ | FocalPlaneXResolution+ | FocalPlaneYResolution+ | FocalPlaneResolutionUnit+ | SensingMethod+ | FileSource+ | SceneType+ | UnknownTagType+ deriving (Show, Eq, Ord)++tagTypeTable :: M.Map Word16 TagType+tagTypeTable = M.fromList+ [ (0x010e, ImageDescription)+ , (0x010f, Make)+ , (0x0110, Model)+ , (0x0112, Orientation)+ , (0x011a, XResolution)+ , (0x011b, YResolution)+ , (0x0128, ResolutionUnit)+ , (0x0131, Software)+ , (0x0132, DateTime)+ , (0x013e, WhitePoint)+ , (0x013f, PrimaryChromaticities)+ , (0x0211, YCbCrCoefficients)+ , (0x0213, YCbCrPositioning)+ , (0x0214, ReferenceBlackWhite)+ , (0x8298, Copyright)+ , (0x8769, ExifOffset)+ , (0x829a, ExposureTime)+ , (0x829d, FNumber)+ , (0x8822, ExposureProgram)+ , (0x8827, ISOSpeedRatings)+ , (0x9000, ExifVersion)+ , (0x9003, DateTimeOriginal)+ , (0x9004, DateTimeDigitized)+ , (0x9101, ComponentConfiguration)+ , (0x9102, CompressedBitsPerPixel)+ , (0x9201, ShutterSpeedValue)+ , (0x9202, ApertureValue)+ , (0x9203, BrightnessValue)+ , (0x9204, ExposureBiasValue)+ , (0x9205, MaxApertureValue)+ , (0x9206, SubjectDistance)+ , (0x9207, MeteringMode)+ , (0x9208, LightSource)+ , (0x9209, Flash)+ , (0x920a, FocalLength)+ , (0x927c, MakerNote)+ , (0x9286, UserComment)+ , (0xa000, FlashPixVersion)+ , (0xa001, ColorSpace)+ , (0xa002, ExifImageWidth)+ , (0xa003, ExifImageHeight)+ , (0xa004, RelatedSoundFile)+ , (0xa005, ExifInteroperabilityOffset)+ , (0xa20e, FocalPlaneXResolution)+ , (0xa20f, FocalPlaneYResolution)+ , (0xa210, FocalPlaneResolutionUnit)+ , (0xa217, SensingMethod)+ , (0xa300, FileSource)+ , (0xa301, SceneType)+ ]
@@ -0,0 +1,524 @@+{-+Copyright (C) 2011-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.MIME+ Copyright : Copyright (C) 2011-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Mime type lookup for ODT writer.+-}+module Text.Pandoc.MIME ( MimeType, getMimeType, getMimeTypeDef,+ extensionFromMimeType )where+import System.FilePath+import Data.Char ( toLower )+import Data.List (isPrefixOf, isSuffixOf)+import Data.Maybe (fromMaybe)+import qualified Data.Map as M++type MimeType = String++-- | Determine mime type appropriate for file path.+getMimeType :: FilePath -> Maybe MimeType+getMimeType fp+ -- ODT+ | fp == "layout-cache" =+ Just "application/binary"+ | "Formula-" `isPrefixOf` fp && "/" `isSuffixOf` fp =+ Just "application/vnd.oasis.opendocument.formula"+ -- generic+ | otherwise = M.lookup (map toLower $ drop 1 $ takeExtension fp) mimeTypes++-- | Determime mime type appropriate for file path, defaulting to+-- “application/octet-stream” if nothing else fits.+getMimeTypeDef :: FilePath -> MimeType+getMimeTypeDef = fromMaybe "application/octet-stream" . getMimeType++extensionFromMimeType :: MimeType -> Maybe String+extensionFromMimeType mimetype =+ M.lookup (takeWhile (/=';') mimetype) reverseMimeTypes+ -- note: we just look up the basic mime type, dropping the content-encoding etc.++reverseMimeTypes :: M.Map MimeType String+reverseMimeTypes = M.fromList $ map (\(k,v) -> (v,k)) mimeTypesList++mimeTypes :: M.Map String MimeType+mimeTypes = M.fromList mimeTypesList++mimeTypesList :: [(String, MimeType)]+mimeTypesList = -- List borrowed from happstack-server.+ [("gz","application/x-gzip")+ ,("cabal","application/x-cabal")+ ,("%","application/x-trash")+ ,("323","text/h323")+ ,("3gp","video/3gpp")+ ,("7z","application/x-7z-compressed")+ ,("abw","application/x-abiword")+ ,("ai","application/postscript")+ ,("aif","audio/x-aiff")+ ,("aifc","audio/x-aiff")+ ,("aiff","audio/x-aiff")+ ,("alc","chemical/x-alchemy")+ ,("art","image/x-jg")+ ,("asc","text/plain")+ ,("asf","video/x-ms-asf")+ ,("asn","chemical/x-ncbi-asn1")+ ,("aso","chemical/x-ncbi-asn1-binary")+ ,("asx","video/x-ms-asf")+ ,("atom","application/atom")+ ,("atomcat","application/atomcat+xml")+ ,("atomsrv","application/atomserv+xml")+ ,("au","audio/basic")+ ,("avi","video/x-msvideo")+ ,("b","chemical/x-molconn-Z")+ ,("bak","application/x-trash")+ ,("bat","application/x-msdos-program")+ ,("bcpio","application/x-bcpio")+ ,("bib","text/x-bibtex")+ ,("bin","application/octet-stream")+ ,("bmp","image/x-ms-bmp")+ ,("boo","text/x-boo")+ ,("book","application/x-maker")+ ,("bsd","chemical/x-crossfire")+ ,("c","text/x-csrc")+ ,("c++","text/x-c++src")+ ,("c3d","chemical/x-chem3d")+ ,("cab","application/x-cab")+ ,("cac","chemical/x-cache")+ ,("cache","chemical/x-cache")+ ,("cap","application/cap")+ ,("cascii","chemical/x-cactvs-binary")+ ,("cat","application/vnd.ms-pki.seccat")+ ,("cbin","chemical/x-cactvs-binary")+ ,("cbr","application/x-cbr")+ ,("cbz","application/x-cbz")+ ,("cc","text/x-c++src")+ ,("cdf","application/x-cdf")+ ,("cdr","image/x-coreldraw")+ ,("cdt","image/x-coreldrawtemplate")+ ,("cdx","chemical/x-cdx")+ ,("cdy","application/vnd.cinderella")+ ,("cef","chemical/x-cxf")+ ,("cer","chemical/x-cerius")+ ,("chm","chemical/x-chemdraw")+ ,("chrt","application/x-kchart")+ ,("cif","chemical/x-cif")+ ,("class","application/java-vm")+ ,("cls","text/x-tex")+ ,("cmdf","chemical/x-cmdf")+ ,("cml","chemical/x-cml")+ ,("cod","application/vnd.rim.cod")+ ,("com","application/x-msdos-program")+ ,("cpa","chemical/x-compass")+ ,("cpio","application/x-cpio")+ ,("cpp","text/x-c++src")+ ,("cpt","application/mac-compactpro")+ ,("crl","application/x-pkcs7-crl")+ ,("crt","application/x-x509-ca-cert")+ ,("csf","chemical/x-cache-csf")+ ,("csh","application/x-csh")+ ,("csm","chemical/x-csml")+ ,("csml","chemical/x-csml")+ ,("css","text/css")+ ,("csv","text/csv")+ ,("ctab","chemical/x-cactvs-binary")+ ,("ctx","chemical/x-ctx")+ ,("cu","application/cu-seeme")+ ,("cub","chemical/x-gaussian-cube")+ ,("cxf","chemical/x-cxf")+ ,("cxx","text/x-c++src")+ ,("d","text/x-dsrc")+ ,("dat","chemical/x-mopac-input")+ ,("dcr","application/x-director")+ ,("deb","application/x-debian-package")+ ,("dif","video/dv")+ ,("diff","text/x-diff")+ ,("dir","application/x-director")+ ,("djv","image/vnd.djvu")+ ,("djvu","image/vnd.djvu")+ ,("dl","video/dl")+ ,("dll","application/x-msdos-program")+ ,("dmg","application/x-apple-diskimage")+ ,("dms","application/x-dms")+ ,("doc","application/msword")+ ,("dot","application/msword")+ ,("dv","video/dv")+ ,("dvi","application/x-dvi")+ ,("dx","chemical/x-jcamp-dx")+ ,("dxr","application/x-director")+ ,("emb","chemical/x-embl-dl-nucleotide")+ ,("embl","chemical/x-embl-dl-nucleotide")+ ,("emf","image/x-emf")+ ,("eml","message/rfc822")+ ,("ent","chemical/x-ncbi-asn1-ascii")+ ,("eot","application/vnd.ms-fontobject")+ ,("eps","application/postscript")+ ,("etx","text/x-setext")+ ,("exe","application/x-msdos-program")+ ,("ez","application/andrew-inset")+ ,("fb","application/x-maker")+ ,("fbdoc","application/x-maker")+ ,("fch","chemical/x-gaussian-checkpoint")+ ,("fchk","chemical/x-gaussian-checkpoint")+ ,("fig","application/x-xfig")+ ,("flac","application/x-flac")+ ,("fli","video/fli")+ ,("fm","application/x-maker")+ ,("frame","application/x-maker")+ ,("frm","application/x-maker")+ ,("fs","text/plain")+ ,("gal","chemical/x-gaussian-log")+ ,("gam","chemical/x-gamess-input")+ ,("gamin","chemical/x-gamess-input")+ ,("gau","chemical/x-gaussian-input")+ ,("gcd","text/x-pcs-gcd")+ ,("gcf","application/x-graphing-calculator")+ ,("gcg","chemical/x-gcg8-sequence")+ ,("gen","chemical/x-genbank")+ ,("gf","application/x-tex-gf")+ ,("gif","image/gif")+ ,("gjc","chemical/x-gaussian-input")+ ,("gjf","chemical/x-gaussian-input")+ ,("gl","video/gl")+ ,("gnumeric","application/x-gnumeric")+ ,("gpt","chemical/x-mopac-graph")+ ,("gsf","application/x-font")+ ,("gsm","audio/x-gsm")+ ,("gtar","application/x-gtar")+ ,("h","text/x-chdr")+ ,("h++","text/x-c++hdr")+ ,("hdf","application/x-hdf")+ ,("hh","text/x-c++hdr")+ ,("hin","chemical/x-hin")+ ,("hpp","text/x-c++hdr")+ ,("hqx","application/mac-binhex40")+ ,("hs","text/x-haskell")+ ,("hta","application/hta")+ ,("htc","text/x-component")+ ,("htm","text/html")+ ,("html","text/html")+ ,("hxx","text/x-c++hdr")+ ,("ica","application/x-ica")+ ,("ice","x-conference/x-cooltalk")+ ,("ico","image/x-icon")+ ,("ics","text/calendar")+ ,("icz","text/calendar")+ ,("ief","image/ief")+ ,("iges","model/iges")+ ,("igs","model/iges")+ ,("iii","application/x-iphone")+ ,("inp","chemical/x-gamess-input")+ ,("ins","application/x-internet-signup")+ ,("iso","application/x-iso9660-image")+ ,("isp","application/x-internet-signup")+ ,("ist","chemical/x-isostar")+ ,("istr","chemical/x-isostar")+ ,("jad","text/vnd.sun.j2me.app-descriptor")+ ,("jar","application/java-archive")+ ,("java","text/x-java")+ ,("jdx","chemical/x-jcamp-dx")+ ,("jmz","application/x-jmol")+ ,("jng","image/x-jng")+ ,("jnlp","application/x-java-jnlp-file")+ ,("jpe","image/jpeg")+ ,("jpeg","image/jpeg")+ ,("jfif","image/jpeg")+ ,("jpg","image/jpeg")+ ,("js","application/x-javascript")+ ,("kar","audio/midi")+ ,("key","application/pgp-keys")+ ,("kil","application/x-killustrator")+ ,("kin","chemical/x-kinemage")+ ,("kml","application/vnd.google-earth.kml+xml")+ ,("kmz","application/vnd.google-earth.kmz")+ ,("kpr","application/x-kpresenter")+ ,("kpt","application/x-kpresenter")+ ,("ksp","application/x-kspread")+ ,("kwd","application/x-kword")+ ,("kwt","application/x-kword")+ ,("latex","application/x-latex")+ ,("lha","application/x-lha")+ ,("lhs","text/x-literate-haskell")+ ,("lsf","video/x-la-asf")+ ,("lsx","video/x-la-asf")+ ,("ltx","text/x-tex")+ ,("lyx","application/x-lyx")+ ,("lzh","application/x-lzh")+ ,("lzx","application/x-lzx")+ ,("m3u","audio/mpegurl")+ ,("m4a","audio/mpeg")+ ,("m4v","video/x-m4v")+ ,("maker","application/x-maker")+ ,("man","application/x-troff-man")+ ,("mcif","chemical/x-mmcif")+ ,("mcm","chemical/x-macmolecule")+ ,("mdb","application/msaccess")+ ,("me","application/x-troff-me")+ ,("mesh","model/mesh")+ ,("mid","audio/midi")+ ,("midi","audio/midi")+ ,("mif","application/x-mif")+ ,("mm","application/x-freemind")+ ,("mmd","chemical/x-macromodel-input")+ ,("mmf","application/vnd.smaf")+ ,("mml","text/mathml")+ ,("mmod","chemical/x-macromodel-input")+ ,("mng","video/x-mng")+ ,("moc","text/x-moc")+ ,("mol","chemical/x-mdl-molfile")+ ,("mol2","chemical/x-mol2")+ ,("moo","chemical/x-mopac-out")+ ,("mop","chemical/x-mopac-input")+ ,("mopcrt","chemical/x-mopac-input")+ ,("mov","video/quicktime")+ ,("movie","video/x-sgi-movie")+ ,("mp2","audio/mpeg")+ ,("mp3","audio/mpeg")+ ,("mp4","video/mp4")+ ,("mpc","chemical/x-mopac-input")+ ,("mpe","video/mpeg")+ ,("mpeg","video/mpeg")+ ,("mpega","audio/mpeg")+ ,("mpg","video/mpeg")+ ,("mpga","audio/mpeg")+ ,("ms","application/x-troff-ms")+ ,("msh","model/mesh")+ ,("msi","application/x-msi")+ ,("mvb","chemical/x-mopac-vib")+ ,("mxu","video/vnd.mpegurl")+ ,("nb","application/mathematica")+ ,("nc","application/x-netcdf")+ ,("nwc","application/x-nwc")+ ,("o","application/x-object")+ ,("oda","application/oda")+ ,("odb","application/vnd.oasis.opendocument.database")+ ,("odc","application/vnd.oasis.opendocument.chart")+ ,("odf","application/vnd.oasis.opendocument.formula")+ ,("odg","application/vnd.oasis.opendocument.graphics")+ ,("odi","application/vnd.oasis.opendocument.image")+ ,("odm","application/vnd.oasis.opendocument.text-master")+ ,("odp","application/vnd.oasis.opendocument.presentation")+ ,("ods","application/vnd.oasis.opendocument.spreadsheet")+ ,("odt","application/vnd.oasis.opendocument.text")+ ,("oga","audio/ogg")+ ,("ogg","application/ogg")+ ,("ogv","video/ogg")+ ,("ogx","application/ogg")+ ,("old","application/x-trash")+ ,("otg","application/vnd.oasis.opendocument.graphics-template")+ ,("oth","application/vnd.oasis.opendocument.text-web")+ ,("otp","application/vnd.oasis.opendocument.presentation-template")+ ,("ots","application/vnd.oasis.opendocument.spreadsheet-template")+ ,("otf","application/x-font-opentype")+ ,("ott","application/vnd.oasis.opendocument.text-template")+ ,("oza","application/x-oz-application")+ ,("p","text/x-pascal")+ ,("p7r","application/x-pkcs7-certreqresp")+ ,("pac","application/x-ns-proxy-autoconfig")+ ,("pas","text/x-pascal")+ ,("pat","image/x-coreldrawpattern")+ ,("patch","text/x-diff")+ ,("pbm","image/x-portable-bitmap")+ ,("pcap","application/cap")+ ,("pcf","application/x-font")+ ,("pcf.Z","application/x-font")+ ,("pcx","image/pcx")+ ,("pdb","chemical/x-pdb")+ ,("pdf","application/pdf")+ ,("pfa","application/x-font")+ ,("pfb","application/x-font")+ ,("pgm","image/x-portable-graymap")+ ,("pgn","application/x-chess-pgn")+ ,("pgp","application/pgp-signature")+ ,("php","application/x-httpd-php")+ ,("php3","application/x-httpd-php3")+ ,("php3p","application/x-httpd-php3-preprocessed")+ ,("php4","application/x-httpd-php4")+ ,("phps","application/x-httpd-php-source")+ ,("pht","application/x-httpd-php")+ ,("phtml","application/x-httpd-php")+ ,("pk","application/x-tex-pk")+ ,("pl","text/x-perl")+ ,("pls","audio/x-scpls")+ ,("pm","text/x-perl")+ ,("png","image/png")+ ,("pnm","image/x-portable-anymap")+ ,("pot","text/plain")+ ,("ppm","image/x-portable-pixmap")+ ,("pps","application/vnd.ms-powerpoint")+ ,("ppt","application/vnd.ms-powerpoint")+ ,("prf","application/pics-rules")+ ,("prt","chemical/x-ncbi-asn1-ascii")+ ,("ps","application/postscript")+ ,("psd","image/x-photoshop")+ ,("py","text/x-python")+ ,("pyc","application/x-python-code")+ ,("pyo","application/x-python-code")+ ,("qt","video/quicktime")+ ,("qtl","application/x-quicktimeplayer")+ ,("ra","audio/x-pn-realaudio")+ ,("ram","audio/x-pn-realaudio")+ ,("rar","application/rar")+ ,("ras","image/x-cmu-raster")+ ,("rd","chemical/x-mdl-rdfile")+ ,("rdf","application/rdf+xml")+ ,("rgb","image/x-rgb")+ ,("rhtml","application/x-httpd-eruby")+ ,("rm","audio/x-pn-realaudio")+ ,("roff","application/x-troff")+ ,("ros","chemical/x-rosdal")+ ,("rpm","application/x-redhat-package-manager")+ ,("rss","application/rss+xml")+ ,("rtf","application/rtf")+ ,("rtx","text/richtext")+ ,("rxn","chemical/x-mdl-rxnfile")+ ,("sct","text/scriptlet")+ ,("sd","chemical/x-mdl-sdfile")+ ,("sd2","audio/x-sd2")+ ,("sda","application/vnd.stardivision.draw")+ ,("sdc","application/vnd.stardivision.calc")+ ,("sdd","application/vnd.stardivision.impress")+ ,("sdf","application/vnd.stardivision.math")+ ,("sds","application/vnd.stardivision.chart")+ ,("sdw","application/vnd.stardivision.writer")+ ,("ser","application/java-serialized-object")+ ,("sgf","application/x-go-sgf")+ ,("sgl","application/vnd.stardivision.writer-global")+ ,("sh","application/x-sh")+ ,("shar","application/x-shar")+ ,("shtml","text/html")+ ,("sid","audio/prs.sid")+ ,("sik","application/x-trash")+ ,("silo","model/mesh")+ ,("sis","application/vnd.symbian.install")+ ,("sisx","x-epoc/x-sisx-app")+ ,("sit","application/x-stuffit")+ ,("sitx","application/x-stuffit")+ ,("skd","application/x-koan")+ ,("skm","application/x-koan")+ ,("skp","application/x-koan")+ ,("skt","application/x-koan")+ ,("smi","application/smil")+ ,("smil","application/smil")+ ,("snd","audio/basic")+ ,("spc","chemical/x-galactic-spc")+ ,("spl","application/futuresplash")+ ,("spx","audio/ogg")+ ,("src","application/x-wais-source")+ ,("stc","application/vnd.sun.xml.calc.template")+ ,("std","application/vnd.sun.xml.draw.template")+ ,("sti","application/vnd.sun.xml.impress.template")+ ,("stl","application/vnd.ms-pki.stl")+ ,("stw","application/vnd.sun.xml.writer.template")+ ,("sty","text/x-tex")+ ,("sv4cpio","application/x-sv4cpio")+ ,("sv4crc","application/x-sv4crc")+ ,("svg","image/svg+xml")+ ,("svgz","image/svg+xml")+ ,("sw","chemical/x-swissprot")+ ,("swf","application/x-shockwave-flash")+ ,("swfl","application/x-shockwave-flash")+ ,("sxc","application/vnd.sun.xml.calc")+ ,("sxd","application/vnd.sun.xml.draw")+ ,("sxg","application/vnd.sun.xml.writer.global")+ ,("sxi","application/vnd.sun.xml.impress")+ ,("sxm","application/vnd.sun.xml.math")+ ,("sxw","application/vnd.sun.xml.writer")+ ,("t","application/x-troff")+ ,("tar","application/x-tar")+ ,("taz","application/x-gtar")+ ,("tcl","application/x-tcl")+ ,("tex","text/x-tex")+ ,("texi","application/x-texinfo")+ ,("texinfo","application/x-texinfo")+ ,("text","text/plain")+ ,("tgf","chemical/x-mdl-tgf")+ ,("tgz","application/x-gtar")+ ,("tif","image/tiff")+ ,("tiff","image/tiff")+ ,("tk","text/x-tcl")+ ,("tm","text/texmacs")+ ,("torrent","application/x-bittorrent")+ ,("tr","application/x-troff")+ ,("ts","text/texmacs")+ ,("tsp","application/dsptype")+ ,("tsv","text/tab-separated-values")+ ,("ttf","application/x-font-truetype")+ ,("txt","text/plain")+ ,("udeb","application/x-debian-package")+ ,("uls","text/iuls")+ ,("ustar","application/x-ustar")+ ,("val","chemical/x-ncbi-asn1-binary")+ ,("vcd","application/x-cdlink")+ ,("vcf","text/x-vcard")+ ,("vcs","text/x-vcalendar")+ ,("vmd","chemical/x-vmd")+ ,("vms","chemical/x-vamas-iso14976")+ ,("vrm","x-world/x-vrml")+ ,("vrml","model/vrml")+ ,("vs","text/plain")+ ,("vsd","application/vnd.visio")+ ,("vtt","text/vtt")+ ,("wad","application/x-doom")+ ,("wav","audio/x-wav")+ ,("wax","audio/x-ms-wax")+ ,("wbmp","image/vnd.wap.wbmp")+ ,("wbxml","application/vnd.wap.wbxml")+ ,("webm","video/webm")+ ,("wk","application/x-123")+ ,("wm","video/x-ms-wm")+ ,("wma","audio/x-ms-wma")+ ,("wmd","application/x-ms-wmd")+ ,("wmf","image/x-wmf")+ ,("wml","text/vnd.wap.wml")+ ,("wmlc","application/vnd.wap.wmlc")+ ,("wmls","text/vnd.wap.wmlscript")+ ,("wmlsc","application/vnd.wap.wmlscriptc")+ ,("wmv","video/x-ms-wmv")+ ,("wmx","video/x-ms-wmx")+ ,("wmz","application/x-ms-wmz")+ ,("woff","application/x-font-woff")+ ,("wp5","application/wordperfect5.1")+ ,("wpd","application/wordperfect")+ ,("wrl","model/vrml")+ ,("wsc","text/scriptlet")+ ,("wvx","video/x-ms-wvx")+ ,("wz","application/x-wingz")+ ,("xbm","image/x-xbitmap")+ ,("xcf","application/x-xcf")+ ,("xht","application/xhtml+xml")+ ,("xhtml","application/xhtml+xml")+ ,("xlb","application/vnd.ms-excel")+ ,("xls","application/vnd.ms-excel")+ ,("xlt","application/vnd.ms-excel")+ ,("xml","application/xml")+ ,("xpi","application/x-xpinstall")+ ,("xpm","image/x-xpixmap")+ ,("xsl","application/xml")+ ,("xtel","chemical/x-xtel")+ ,("xul","application/vnd.mozilla.xul+xml")+ ,("xwd","image/x-xwindowdump")+ ,("xyz","chemical/x-xyz")+ ,("zip","application/zip")+ ,("zmt","chemical/x-mopac-input")+ ]+
@@ -0,0 +1,107 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-+Copyright (C) 2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.MediaBag+ Copyright : Copyright (C) 2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Definition of a MediaBag object to hold binary resources, and an+interface for interacting with it.+-}+module Text.Pandoc.MediaBag (+ MediaBag,+ lookupMedia,+ insertMedia,+ mediaDirectory,+ extractMediaBag+ ) where+import System.FilePath+import System.Directory (createDirectoryIfMissing)+import qualified Data.Map as M+import qualified Data.ByteString.Lazy as BL+import Data.Monoid (Monoid)+import Control.Monad (when)+import Text.Pandoc.MIME (MimeType, getMimeTypeDef)+import qualified Text.Pandoc.UTF8 as UTF8+import Data.Maybe (fromMaybe)+import System.IO (stderr)++-- | A container for a collection of binary resources, with names and+-- mime types. Note that a 'MediaBag' is a Monoid, so 'mempty'+-- can be used for an empty 'MediaBag', and '<>' can be used to append+-- two 'MediaBag's.+newtype MediaBag = MediaBag (M.Map [String] (MimeType, BL.ByteString))+ deriving (Monoid)++instance Show MediaBag where+ show bag = "MediaBag " ++ show (mediaDirectory bag)++-- | Insert a media item into a 'MediaBag', replacing any existing+-- value with the same name.+insertMedia :: FilePath -- ^ relative path and canonical name of resource+ -> Maybe MimeType -- ^ mime type (Nothing = determine from extension)+ -> BL.ByteString -- ^ contents of resource+ -> MediaBag+ -> MediaBag+insertMedia fp mbMime contents (MediaBag mediamap) =+ MediaBag (M.insert (splitPath fp) (mime, contents) mediamap)+ where mime = fromMaybe fallback mbMime+ fallback = case takeExtension fp of+ ".gz" -> getMimeTypeDef $ dropExtension fp+ _ -> getMimeTypeDef fp++-- | Lookup a media item in a 'MediaBag', returning mime type and contents.+lookupMedia :: FilePath+ -> MediaBag+ -> Maybe (MimeType, BL.ByteString)+lookupMedia fp (MediaBag mediamap) = M.lookup (splitPath fp) mediamap++-- | Get a list of the file paths stored in a 'MediaBag', with+-- their corresponding mime types and the lengths in bytes of the contents.+mediaDirectory :: MediaBag -> [(String, MimeType, Int)]+mediaDirectory (MediaBag mediamap) =+ M.foldWithKey (\fp (mime,contents) ->+ (((joinPath fp), mime, fromIntegral $ BL.length contents):)) [] mediamap++-- | Extract contents of MediaBag to a given directory. Print informational+-- messages if 'verbose' is true.+extractMediaBag :: Bool+ -> FilePath+ -> MediaBag+ -> IO ()+extractMediaBag verbose dir (MediaBag mediamap) = do+ sequence_ $ M.foldWithKey+ (\fp (_ ,contents) ->+ ((writeMedia verbose dir (joinPath fp, contents)):)) [] mediamap++writeMedia :: Bool -> FilePath -> (FilePath, BL.ByteString) -> IO ()+writeMedia verbose dir (subpath, bs) = do+ -- we join and split to convert a/b/c to a\b\c on Windows;+ -- in zip containers all paths use /+ let fullpath = dir </> normalise subpath+ createDirectoryIfMissing True $ takeDirectory fullpath+ when verbose $ UTF8.hPutStrLn stderr $ "pandoc: extracting " ++ fullpath+ BL.writeFile fullpath bs++
@@ -0,0 +1,419 @@+{-+Copyright (C) 2012-2014 John MacFarlane <jgm@berkeley.edu>+Copyright (C) 2014 Tim T.Y. Lin <timtylin@gmail.com>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Options+ Copyright : Copyright (C) 2012-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Data structures and functions for representing parser and writer+options.+-}+module Text.Pandoc.Options ( Extension(..)+ , pandocExtensions+ , strictExtensions+ , phpMarkdownExtraExtensions+ , githubMarkdownExtensions+ , multimarkdownExtensions+ , scholarlyMarkdownExtensions+ , ReaderOptions(..)+ , HTMLMathMethod (..)+ , CiteMethod (..)+ , ObfuscationMethod (..)+ , HTMLSlideVariant (..)+ , EPUBVersion (..)+ , WriterOptions (..)+ , TrackChanges (..)+ , def+ , isEnabled+ ) where+import Data.Set (Set)+import qualified Data.Set as Set+import Data.Default+import Text.Pandoc.Highlighting (Style, pygments)+import Text.Pandoc.MediaBag (MediaBag)+import Data.Monoid++-- | Individually selectable syntax extensions.+data Extension =+ Ext_footnotes -- ^ Pandoc/PHP/MMD style footnotes+ | Ext_inline_notes -- ^ Pandoc-style inline notes+ | Ext_pandoc_title_block -- ^ Pandoc title block+ | Ext_yaml_metadata_block -- ^ YAML metadata block+ | Ext_mmd_title_block -- ^ Multimarkdown metadata block+ | Ext_table_captions -- ^ Pandoc-style table captions+ | Ext_implicit_figures -- ^ A paragraph with just an image is a figure+ | Ext_simple_tables -- ^ Pandoc-style simple tables+ | Ext_multiline_tables -- ^ Pandoc-style multiline tables+ | Ext_grid_tables -- ^ Grid tables (pandoc, reST)+ | Ext_pipe_tables -- ^ Pipe tables (as in PHP markdown extra)+ | Ext_citations -- ^ Pandoc/citeproc citations+ | Ext_raw_tex -- ^ Allow raw TeX (other than math)+ | Ext_raw_html -- ^ Allow raw HTML+ | Ext_tex_math_dollars -- ^ TeX math between $..$ or $$..$$+ | Ext_tex_math_single_backslash -- ^ TeX math btw \(..\) \[..\]+ | Ext_tex_math_double_backslash -- ^ TeX math btw \\(..\\) \\[..\\]+ | Ext_latex_macros -- ^ Parse LaTeX macro definitions (for math only)+ | Ext_fenced_code_blocks -- ^ Parse fenced code blocks+ | Ext_fenced_code_attributes -- ^ Allow attributes on fenced code blocks+ | Ext_backtick_code_blocks -- ^ Github style ``` code blocks+ | Ext_inline_code_attributes -- ^ Allow attributes on inline code+ | Ext_markdown_in_html_blocks -- ^ Interpret as markdown inside HTML blocks+ | Ext_native_divs -- ^ Use Div blocks for contents of <div> tags+ | Ext_native_spans -- ^ Use Span inlines for contents of <span>+ | Ext_markdown_attribute -- ^ Interpret text inside HTML as markdown+ -- iff container has attribute 'markdown'+ | Ext_escaped_line_breaks -- ^ Treat a backslash at EOL as linebreak+ | Ext_link_attributes -- ^ MMD style reference link attributes+ | Ext_autolink_bare_uris -- ^ Make all absolute URIs into links+ | Ext_fancy_lists -- ^ Enable fancy list numbers and delimiters+ | Ext_lists_without_preceding_blankline -- ^ Allow lists without preceding blank+ | Ext_startnum -- ^ Make start number of ordered list significant+ | Ext_definition_lists -- ^ Definition lists as in pandoc, mmd, php+ | Ext_compact_definition_lists -- ^ Definition lists without+ -- space between items, and disallow laziness+ | Ext_example_lists -- ^ Markdown-style numbered examples+ | Ext_all_symbols_escapable -- ^ Make all non-alphanumerics escapable+ | Ext_intraword_underscores -- ^ Treat underscore inside word as literal+ | Ext_blank_before_blockquote -- ^ Require blank line before a blockquote+ | Ext_blank_before_header -- ^ Require blank line before a header+ | Ext_strikeout -- ^ Strikeout using ~~this~~ syntax+ | Ext_superscript -- ^ Superscript using ^this^ syntax+ | Ext_subscript -- ^ Subscript using ~this~ syntax+ | Ext_hard_line_breaks -- ^ All newlines become hard line breaks+ | Ext_ignore_line_breaks -- ^ Newlines in paragraphs are ignored+ | Ext_literate_haskell -- ^ Enable literate Haskell conventions+ | Ext_abbreviations -- ^ PHP markdown extra abbreviation definitions+ | Ext_auto_identifiers -- ^ Automatic identifiers for headers+ | Ext_ascii_identifiers -- ^ ascii-only identifiers for headers+ | Ext_header_attributes -- ^ Explicit header attributes {#id .class k=v}+ | Ext_mmd_header_identifiers -- ^ Multimarkdown style header identifiers [myid]+ | Ext_implicit_header_references -- ^ Implicit reference links for headers+ | Ext_line_blocks -- ^ RST style line blocks+ | Ext_epub_html_exts -- ^ Recognise the EPUB extended version of HTML+ | Ext_scholarly_markdown -- ^ Enables all Scholarly Markdown extensions+ deriving (Show, Read, Enum, Eq, Ord, Bounded)++pandocExtensions :: Set Extension+pandocExtensions = Set.fromList+ [ Ext_footnotes+ , Ext_inline_notes+ , Ext_pandoc_title_block+ , Ext_yaml_metadata_block+ , Ext_table_captions+ , Ext_implicit_figures+ , Ext_simple_tables+ , Ext_multiline_tables+ , Ext_grid_tables+ , Ext_pipe_tables+ , Ext_citations+ , Ext_raw_tex+ , Ext_raw_html+ , Ext_tex_math_dollars+ , Ext_latex_macros+ , Ext_fenced_code_blocks+ , Ext_fenced_code_attributes+ , Ext_backtick_code_blocks+ , Ext_inline_code_attributes+ , Ext_markdown_in_html_blocks+ , Ext_native_divs+ , Ext_native_spans+ , Ext_escaped_line_breaks+ , Ext_fancy_lists+ , Ext_startnum+ , Ext_definition_lists+ , Ext_example_lists+ , Ext_all_symbols_escapable+ , Ext_intraword_underscores+ , Ext_blank_before_blockquote+ , Ext_blank_before_header+ , Ext_strikeout+ , Ext_superscript+ , Ext_subscript+ , Ext_auto_identifiers+ , Ext_header_attributes+ , Ext_implicit_header_references+ , Ext_line_blocks+ ]++phpMarkdownExtraExtensions :: Set Extension+phpMarkdownExtraExtensions = Set.fromList+ [ Ext_footnotes+ , Ext_pipe_tables+ , Ext_raw_html+ , Ext_markdown_attribute+ , Ext_fenced_code_blocks+ , Ext_definition_lists+ , Ext_intraword_underscores+ , Ext_header_attributes+ , Ext_abbreviations+ ]++githubMarkdownExtensions :: Set Extension+githubMarkdownExtensions = Set.fromList+ [ Ext_pipe_tables+ , Ext_raw_html+ , Ext_tex_math_single_backslash+ , Ext_fenced_code_blocks+ , Ext_auto_identifiers+ , Ext_ascii_identifiers+ , Ext_backtick_code_blocks+ , Ext_autolink_bare_uris+ , Ext_intraword_underscores+ , Ext_strikeout+ , Ext_hard_line_breaks+ , Ext_lists_without_preceding_blankline+ ]++multimarkdownExtensions :: Set Extension+multimarkdownExtensions = Set.fromList+ [ Ext_pipe_tables+ , Ext_raw_html+ , Ext_markdown_attribute+ , Ext_link_attributes+ , Ext_raw_tex+ , Ext_tex_math_double_backslash+ , Ext_intraword_underscores+ , Ext_mmd_title_block+ , Ext_footnotes+ , Ext_definition_lists+ , Ext_all_symbols_escapable+ , Ext_implicit_header_references+ , Ext_auto_identifiers+ , Ext_mmd_header_identifiers+ ]++scholarlyMarkdownExtensions :: Set Extension+scholarlyMarkdownExtensions = Set.fromList+ [ Ext_footnotes+ , Ext_inline_notes+ , Ext_pandoc_title_block+ , Ext_yaml_metadata_block+ , Ext_table_captions+ , Ext_implicit_figures+ , Ext_simple_tables+ , Ext_multiline_tables+ , Ext_grid_tables+ , Ext_pipe_tables+ , Ext_citations+ , Ext_raw_tex+ , Ext_raw_html+ , Ext_tex_math_dollars+ , Ext_latex_macros+ , Ext_fenced_code_blocks+ , Ext_fenced_code_attributes+ , Ext_backtick_code_blocks+ , Ext_inline_code_attributes+ , Ext_markdown_in_html_blocks+ , Ext_escaped_line_breaks+ , Ext_fancy_lists+ , Ext_startnum+ , Ext_definition_lists+ , Ext_example_lists+ , Ext_all_symbols_escapable+ , Ext_intraword_underscores+ , Ext_blank_before_blockquote+ , Ext_blank_before_header+ , Ext_strikeout+ , Ext_superscript+ , Ext_subscript+ , Ext_auto_identifiers+ , Ext_header_attributes+ , Ext_implicit_header_references+ , Ext_line_blocks+ , Ext_scholarly_markdown+ ]++strictExtensions :: Set Extension+strictExtensions = Set.fromList+ [ Ext_raw_html ]++data ReaderOptions = ReaderOptions{+ readerExtensions :: Set Extension -- ^ Syntax extensions+ , readerSmart :: Bool -- ^ Smart punctuation+ , readerStandalone :: Bool -- ^ Standalone document with header+ , readerParseRaw :: Bool -- ^ Parse raw HTML, LaTeX+ , readerColumns :: Int -- ^ Number of columns in terminal+ , readerTabStop :: Int -- ^ Tab stop+ , readerOldDashes :: Bool -- ^ Use pandoc <= 1.8.2.1 behavior+ -- in parsing dashes; -- is em-dash;+ -- - before numerial is en-dash+ , readerApplyMacros :: Bool -- ^ Apply macros to TeX math+ , readerIndentedCodeClasses :: [String] -- ^ Default classes for+ -- indented code blocks+ , readerDefaultImageExtension :: String -- ^ Default extension for images+ , readerTrace :: Bool -- ^ Print debugging info+ , readerTrackChanges :: TrackChanges+} deriving (Show, Read)++instance Default ReaderOptions+ where def = ReaderOptions{+ readerExtensions = pandocExtensions+ , readerSmart = False+ , readerStandalone = False+ , readerParseRaw = False+ , readerColumns = 80+ , readerTabStop = 4+ , readerOldDashes = False+ , readerApplyMacros = True+ , readerIndentedCodeClasses = []+ , readerDefaultImageExtension = ""+ , readerTrace = False+ , readerTrackChanges = AcceptChanges+ }++--+-- Writer options+--++data EPUBVersion = EPUB2 | EPUB3 deriving (Eq, Show, Read)++data HTMLMathMethod = PlainMath+ | LaTeXMathML (Maybe String) -- url of LaTeXMathML.js+ | JsMath (Maybe String) -- url of jsMath load script+ | GladTeX+ | WebTeX String -- url of TeX->image script.+ | MathML (Maybe String) -- url of MathMLinHTML.js+ | MathJax String -- url of MathJax.js+ | KaTeX String String -- url of stylesheet and katex.js+ deriving (Show, Read, Eq)++data CiteMethod = Citeproc -- use citeproc to render them+ | Natbib -- output natbib cite commands+ | Biblatex -- output biblatex cite commands+ deriving (Show, Read, Eq)++-- | Methods for obfuscating email addresses in HTML.+data ObfuscationMethod = NoObfuscation+ | ReferenceObfuscation+ | JavascriptObfuscation+ deriving (Show, Read, Eq)++-- | Varieties of HTML slide shows.+data HTMLSlideVariant = S5Slides+ | SlidySlides+ | SlideousSlides+ | DZSlides+ | RevealJsSlides+ | NoSlides+ deriving (Show, Read, Eq)++-- | Options for accepting or rejecting MS Word track-changes.+data TrackChanges = AcceptChanges+ | RejectChanges+ | AllChanges+ deriving (Show, Read, Eq)++-- | Options for writers+data WriterOptions = WriterOptions+ { writerStandalone :: Bool -- ^ Include header and footer+ , writerTemplate :: String -- ^ Template to use in standalone mode+ , writerVariables :: [(String, String)] -- ^ Variables to set in template+ , writerTabStop :: Int -- ^ Tabstop for conversion btw spaces and tabs+ , writerTableOfContents :: Bool -- ^ Include table of contents+ , writerSlideVariant :: HTMLSlideVariant -- ^ Are we writing S5, Slidy or Slideous?+ , writerIncremental :: Bool -- ^ True if lists should be incremental+ , writerHTMLMathMethod :: HTMLMathMethod -- ^ How to print math in HTML+ , writerIgnoreNotes :: Bool -- ^ Ignore footnotes (used in making toc)+ , writerNumberSections :: Bool -- ^ Number sections in LaTeX+ , writerNumberOffset :: [Int] -- ^ Starting number for section, subsection, ...+ , writerSectionDivs :: Bool -- ^ Put sections in div tags in HTML+ , writerExtensions :: Set Extension -- ^ Markdown extensions that can be used+ , writerReferenceLinks :: Bool -- ^ Use reference links in writing markdown, rst+ , writerWrapText :: Bool -- ^ Wrap text to line length+ , writerColumns :: Int -- ^ Characters in a line (for text wrapping)+ , writerEmailObfuscation :: ObfuscationMethod -- ^ How to obfuscate emails+ , writerIdentifierPrefix :: String -- ^ Prefix for section & note ids in HTML+ -- and for footnote marks in markdown+ , writerSourceURL :: Maybe String -- ^ Absolute URL + directory of 1st source file+ , writerUserDataDir :: Maybe FilePath -- ^ Path of user data directory+ , writerCiteMethod :: CiteMethod -- ^ How to print cites+ , writerHtml5 :: Bool -- ^ Produce HTML5+ , writerHtmlQTags :: Bool -- ^ Use @<q>@ tags for quotes in HTML+ , writerBeamer :: Bool -- ^ Produce beamer LaTeX slide show+ , writerSlideLevel :: Maybe Int -- ^ Force header level of slides+ , writerChapters :: Bool -- ^ Use "chapter" for top-level sects+ , writerListings :: Bool -- ^ Use listings package for code+ , writerHighlight :: Bool -- ^ Highlight source code+ , writerHighlightStyle :: Style -- ^ Style to use for highlighting+ , writerSetextHeaders :: Bool -- ^ Use setext headers for levels 1-2 in markdown+ , writerTeXLigatures :: Bool -- ^ Use tex ligatures quotes, dashes in latex+ , writerEpubVersion :: Maybe EPUBVersion -- ^ Nothing or EPUB version+ , writerEpubMetadata :: String -- ^ Metadata to include in EPUB+ , writerEpubStylesheet :: Maybe String -- ^ EPUB stylesheet specified at command line+ , writerEpubFonts :: [FilePath] -- ^ Paths to fonts to embed+ , writerEpubChapterLevel :: Int -- ^ Header level for chapters (separate files)+ , writerTOCDepth :: Int -- ^ Number of levels to include in TOC+ , writerReferenceODT :: Maybe FilePath -- ^ Path to reference ODT if specified+ , writerReferenceDocx :: Maybe FilePath -- ^ Path to reference DOCX if specified+ , writerMediaBag :: MediaBag -- ^ Media collected by docx or epub reader+ , writerScholarly :: Bool -- ^ Rendering a ScholMD document+ } deriving Show++instance Default WriterOptions where+ def = WriterOptions { writerStandalone = False+ , writerTemplate = ""+ , writerVariables = []+ , writerTabStop = 4+ , writerTableOfContents = False+ , writerSlideVariant = NoSlides+ , writerIncremental = False+ , writerHTMLMathMethod = PlainMath+ , writerIgnoreNotes = False+ , writerNumberSections = False+ , writerNumberOffset = [0,0,0,0,0,0]+ , writerSectionDivs = False+ , writerExtensions = pandocExtensions+ , writerReferenceLinks = False+ , writerWrapText = True+ , writerColumns = 72+ , writerEmailObfuscation = JavascriptObfuscation+ , writerIdentifierPrefix = ""+ , writerSourceURL = Nothing+ , writerUserDataDir = Nothing+ , writerCiteMethod = Citeproc+ , writerHtml5 = False+ , writerHtmlQTags = False+ , writerBeamer = False+ , writerSlideLevel = Nothing+ , writerChapters = False+ , writerListings = False+ , writerHighlight = False+ , writerHighlightStyle = pygments+ , writerSetextHeaders = True+ , writerTeXLigatures = True+ , writerEpubVersion = Nothing+ , writerEpubMetadata = ""+ , writerEpubStylesheet = Nothing+ , writerEpubFonts = []+ , writerEpubChapterLevel = 1+ , writerTOCDepth = 3+ , writerReferenceODT = Nothing+ , writerReferenceDocx = Nothing+ , writerMediaBag = mempty+ , writerScholarly = False+ }++-- | Returns True if the given extension is enabled.+isEnabled :: Extension -> WriterOptions -> Bool+isEnabled ext opts = ext `Set.member` (writerExtensions opts)
@@ -0,0 +1,208 @@+{-# LANGUAGE OverloadedStrings, CPP, ScopedTypeVariables #-}+{-+Copyright (C) 2012-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.PDF+ Copyright : Copyright (C) 2012-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of LaTeX documents to PDF.+-}+module Text.Pandoc.PDF ( makePDF ) where++import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Lazy as B+import qualified Data.ByteString.Lazy.Char8 as BC+import qualified Data.ByteString as BS+import System.Exit (ExitCode (..))+import System.FilePath+import System.Directory+import Data.Digest.Pure.SHA (showDigest, sha1)+import System.Environment+import Control.Monad (unless, (<=<))+import qualified Control.Exception as E+import Control.Applicative ((<$))+import Data.List (isInfixOf)+import Data.Maybe (fromMaybe)+import qualified Text.Pandoc.UTF8 as UTF8+import Text.Pandoc.Definition+import Text.Pandoc.Walk (walkM)+import Text.Pandoc.Shared (fetchItem', warn, withTempDir)+import Text.Pandoc.Options (WriterOptions(..))+import Text.Pandoc.MIME (extensionFromMimeType, getMimeType)+import Text.Pandoc.Process (pipeProcess)+import qualified Data.ByteString.Lazy as BL+import qualified Codec.Picture as JP+#ifdef _WINDOWS+import Data.List (intercalate)+#endif++#ifdef _WINDOWS+changePathSeparators :: FilePath -> FilePath+changePathSeparators = intercalate "/" . splitDirectories+#endif++makePDF :: String -- ^ pdf creator (pdflatex, lualatex, xelatex)+ -> (WriterOptions -> Pandoc -> String) -- ^ writer+ -> WriterOptions -- ^ options+ -> Pandoc -- ^ document+ -> IO (Either ByteString ByteString)+makePDF program writer opts doc = withTempDir "tex2pdf." $ \tmpdir -> do+ doc' <- handleImages opts tmpdir doc+ let source = writer opts doc'+ tex2pdf' tmpdir program source++handleImages :: WriterOptions+ -> FilePath -- ^ temp dir to store images+ -> Pandoc -- ^ document+ -> IO Pandoc+handleImages opts tmpdir = walkM (convertImages tmpdir) <=< walkM (handleImage' opts tmpdir)++handleImage' :: WriterOptions+ -> FilePath+ -> Inline+ -> IO Inline+handleImage' opts tmpdir (Image attr ils (src,tit)) = do+ exists <- doesFileExist src+ if exists+ then return $ Image attr ils (src,tit)+ else do+ res <- fetchItem' (writerMediaBag opts) (writerSourceURL opts) src+ case res of+ Right (contents, Just mime) -> do+ let ext = fromMaybe (takeExtension src) $+ extensionFromMimeType mime+ let basename = showDigest $ sha1 $ BL.fromChunks [contents]+ let fname = tmpdir </> basename <.> ext+ BS.writeFile fname contents+ return $ Image attr ils (fname,tit)+ _ -> do+ warn $ "Could not find image `" ++ src ++ "', skipping..."+ return $ Image attr ils (src,tit)+handleImage' _ _ x = return x++convertImages :: FilePath -> Inline -> IO Inline+convertImages tmpdir (Image attr ils (src, tit)) = do+ img <- convertImage tmpdir src+ newPath <-+ case img of+ Left e -> src <$+ warn ("Unable to convert image `" ++ src ++ "':\n" ++ e)+ Right fp -> return fp+ return (Image attr ils (newPath, tit))+convertImages _ x = return x++-- Convert formats which do not work well in pdf to png+convertImage :: FilePath -> FilePath -> IO (Either String FilePath)+convertImage tmpdir fname =+ case mime of+ Just "image/png" -> doNothing+ Just "image/jpeg" -> doNothing+ Just "application/pdf" -> doNothing+ _ -> JP.readImage fname >>= \res ->+ case res of+ Left msg -> return $ Left msg+ Right img ->+ E.catch (Right fileOut <$ JP.savePngImage fileOut img) $+ \(e :: E.SomeException) -> return (Left (show e))+ where+ fileOut = replaceDirectory (replaceExtension fname (".png")) tmpdir+ mime = getMimeType fname+ doNothing = return (Right fname)++tex2pdf' :: FilePath -- ^ temp directory for output+ -> String -- ^ tex program+ -> String -- ^ tex source+ -> IO (Either ByteString ByteString)+tex2pdf' tmpDir program source = do+ let numruns = if "\\tableofcontents" `isInfixOf` source+ then 3 -- to get page numbers+ else 2 -- 1 run won't give you PDF bookmarks+ (exit, log', mbPdf) <- runTeXProgram program numruns tmpDir source+ case (exit, mbPdf) of+ (ExitFailure _, _) -> do+ let logmsg = extractMsg log'+ let extramsg =+ case logmsg of+ x | "! Package inputenc Error" `BC.isPrefixOf` x ->+ "\nTry running pandoc with --latex-engine=xelatex."+ _ -> ""+ return $ Left $ logmsg <> extramsg+ (ExitSuccess, Nothing) -> return $ Left ""+ (ExitSuccess, Just pdf) -> return $ Right pdf++(<>) :: ByteString -> ByteString -> ByteString+(<>) = B.append++-- parsing output++extractMsg :: ByteString -> ByteString+extractMsg log' = do+ let msg' = dropWhile (not . ("!" `BC.isPrefixOf`)) $ BC.lines log'+ let (msg'',rest) = break ("l." `BC.isPrefixOf`) msg'+ let lineno = take 1 rest+ if null msg'+ then log'+ else BC.unlines (msg'' ++ lineno)++-- running tex programs++-- Run a TeX program on an input bytestring and return (exit code,+-- contents of stdout, contents of produced PDF if any). Rerun+-- a fixed number of times to resolve references.+runTeXProgram :: String -> Int -> FilePath -> String+ -> IO (ExitCode, ByteString, Maybe ByteString)+runTeXProgram program runsLeft tmpDir source = do+ let file = tmpDir </> "input.tex"+ exists <- doesFileExist file+ unless exists $ UTF8.writeFile file source+#ifdef _WINDOWS+ -- note: we want / even on Windows, for TexLive+ let tmpDir' = changePathSeparators tmpDir+ let file' = changePathSeparators file+#else+ let tmpDir' = tmpDir+ let file' = file+#endif+ let programArgs = ["-halt-on-error", "-interaction", "nonstopmode",+ "-output-directory", tmpDir', file']+ env' <- getEnvironment+ let sep = searchPathSeparator:[]+ let texinputs = maybe (tmpDir' ++ sep) ((tmpDir' ++ sep) ++)+ $ lookup "TEXINPUTS" env'+ let env'' = ("TEXINPUTS", texinputs) :+ [(k,v) | (k,v) <- env', k /= "TEXINPUTS"]+ (exit, out, err) <- pipeProcess (Just env'') program programArgs BL.empty+ if runsLeft > 1+ then runTeXProgram program (runsLeft - 1) tmpDir source+ else do+ let pdfFile = replaceDirectory (replaceExtension file ".pdf") tmpDir+ pdfExists <- doesFileExist pdfFile+ pdf <- if pdfExists+ -- We read PDF as a strict bytestring to make sure that the+ -- temp directory is removed on Windows.+ -- See https://github.com/jgm/pandoc/issues/1192.+ then (Just . B.fromChunks . (:[])) `fmap` BS.readFile pdfFile+ else return Nothing+ return (exit, out <> err, pdf)+
@@ -0,0 +1,1309 @@+{-# LANGUAGE+ FlexibleContexts+, GeneralizedNewtypeDeriving+, TypeSynonymInstances+, MultiParamTypeClasses+, FlexibleInstances #-}+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>+Copyright (C) 2014 Tim T.Y. Lin <timtylin@gmail.com>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Parsing+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++A utility library with parsers used in pandoc readers.+-}+module Text.Pandoc.Parsing ( anyLine,+ many1Till,+ notFollowedBy',+ oneOfStrings,+ oneOfStringsCI,+ exactly,+ spaceChar,+ nonspaceChar,+ skipSpaces,+ blankline,+ blanklines,+ enclosed,+ stringAnyCase,+ parseFromString,+ lineClump,+ charsInBalanced,+ romanNumeral,+ emailAddress,+ uri,+ mathInline,+ mathDisplay,+ mathInlineWith',+ withHorizDisplacement,+ withRaw,+ escaped,+ characterReference,+ anyOrderedListMarker,+ orderedListMarker,+ charRef,+ lineBlockLines,+ lineBlockLine,+ tableWith,+ widthsFromIndices,+ gridTableWith,+ readWith,+ readWithM,+ testStringWith,+ guardEnabled,+ guardDisabled,+ updateLastStrPos,+ notAfterString,+ getNumericalLabel,+ ParserState (..),+ XRefIdentifiers (..),+ HasReaderOptions (..),+ HasHeaderMap (..),+ HasIdentifierList (..),+ HasMacros (..),+ HasLastStrPosition (..),+ defaultParserState,+ HeaderType (..),+ ParserContext (..),+ QuoteContext (..),+ HasQuoteContext (..),+ NoteTable,+ NoteTable',+ KeyTable,+ SubstTable,+ Key (..),+ toKey,+ registerHeader,+ smartPunctuation,+ singleQuoteStart,+ singleQuoteEnd,+ doubleQuoteStart,+ doubleQuoteEnd,+ ellipses,+ apostrophe,+ dash,+ nested,+ citeKey,+ macro,+ applyMacros',+ Parser,+ ParserT,+ F(..),+ runF,+ askF,+ asksF,+ token,+ -- * Re-exports from Text.Pandoc.Parsec+ Stream,+ runParser,+ runParserT,+ parse,+ anyToken,+ getInput,+ setInput,+ unexpected,+ char,+ letter,+ digit,+ alphaNum,+ skipMany,+ skipMany1,+ spaces,+ space,+ anyChar,+ satisfy,+ newline,+ string,+ count,+ eof,+ noneOf,+ oneOf,+ lookAhead,+ notFollowedBy,+ many,+ many1,+ manyTill,+ (<|>),+ (<?>),+ choice,+ try,+ sepBy,+ sepBy1,+ sepEndBy,+ sepEndBy1,+ endBy,+ endBy1,+ option,+ optional,+ optionMaybe,+ getState,+ setState,+ updateState,+ SourcePos,+ getPosition,+ setPosition,+ sourceColumn,+ sourceLine,+ setSourceColumn,+ setSourceLine,+ newPos,+ )+where++import Text.Pandoc.Definition+import Text.Pandoc.Options+import Text.Pandoc.Builder (Blocks, Inlines, rawBlock, HasMeta(..))+import qualified Text.Pandoc.Builder as B+import Text.Pandoc.XML (fromEntities)+import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)+import Text.Parsec hiding (token)+import Text.Parsec.Pos (newPos)+import Data.Char ( toLower, toUpper, ord, chr, isAscii, isAlphaNum,+ isHexDigit, isSpace )+import Data.List ( intercalate, transpose, elemIndex, findIndex )+import Text.Pandoc.Shared+import qualified Data.Map as M+import Text.TeXMath.Readers.TeX.Macros (applyMacros, Macro,+ parseMacroDefinitions)+import Text.Pandoc.Compat.TagSoupEntity ( lookupEntity )+import Text.Pandoc.Asciify (toAsciiChar)+import Data.Default+import qualified Data.Set as Set+import Control.Monad.Reader+import Control.Monad.Identity+import Control.Applicative ((<$>), (<*>), (*>), (<*), (<$), Applicative)+import Data.Monoid+import Data.Maybe (catMaybes, fromJust)++type Parser t s = Parsec t s++type ParserT = ParsecT++newtype F a = F { unF :: Reader ParserState a } deriving (Monad, Applicative, Functor)++runF :: F a -> ParserState -> a+runF = runReader . unF++askF :: F ParserState+askF = F ask++asksF :: (ParserState -> a) -> F a+asksF f = F $ asks f++instance Monoid a => Monoid (F a) where+ mempty = return mempty+ mappend = liftM2 mappend+ mconcat = liftM mconcat . sequence++-- | Parse any line of text+anyLine :: Stream [Char] m Char => ParserT [Char] st m [Char]+anyLine = do+ -- This is much faster than:+ -- manyTill anyChar newline+ inp <- getInput+ pos <- getPosition+ case break (=='\n') inp of+ (this, '\n':rest) -> do+ -- needed to persuade parsec that this won't match an empty string:+ anyChar+ setInput rest+ setPosition $ incSourceLine (setSourceColumn pos 1) 1+ return this+ _ -> mzero++-- | Like @manyTill@, but reads at least one item.+many1Till :: Stream s m t+ => ParserT s st m a+ -> ParserT s st m end+ -> ParserT s st m [a]+many1Till p end = do+ first <- p+ rest <- manyTill p end+ return (first:rest)++-- | A more general form of @notFollowedBy@. This one allows any+-- type of parser to be specified, and succeeds only if that parser fails.+-- It does not consume any input.+notFollowedBy' :: (Show b, Stream s m a) => ParserT s st m b -> ParserT s st m ()+notFollowedBy' p = try $ join $ do a <- try p+ return (unexpected (show a))+ <|>+ return (return ())+-- (This version due to Andrew Pimlott on the Haskell mailing list.)++oneOfStrings' :: Stream s m Char => (Char -> Char -> Bool) -> [String] -> ParserT s st m String+oneOfStrings' _ [] = fail "no strings"+oneOfStrings' matches strs = try $ do+ c <- anyChar+ let strs' = [xs | (x:xs) <- strs, x `matches` c]+ case strs' of+ [] -> fail "not found"+ _ -> (c:) <$> oneOfStrings' matches strs'+ <|> if "" `elem` strs'+ then return [c]+ else fail "not found"++-- | Parses one of a list of strings. If the list contains+-- two strings one of which is a prefix of the other, the longer+-- string will be matched if possible.+oneOfStrings :: Stream s m Char => [String] -> ParserT s st m String+oneOfStrings = oneOfStrings' (==)++-- | Parses one of a list of strings (tried in order), case insensitive.+oneOfStringsCI :: Stream s m Char => [String] -> ParserT s st m String+oneOfStringsCI = oneOfStrings' ciMatch+ where ciMatch x y = toLower' x == toLower' y+ -- this optimizes toLower by checking common ASCII case+ -- first, before calling the expensive unicode-aware+ -- function:+ toLower' c | c >= 'A' && c <= 'Z' = chr (ord c + 32)+ | isAscii c = c+ | otherwise = toLower c++-- | Parses an exact number of characters, no more and no less+exactly :: Stream s m Char => Int -> Char -> ParserT s st m [Char]+exactly cnt ch = count cnt (char ch) <* notFollowedBy (char ch)++-- | Parses a space or tab.+spaceChar :: Stream s m Char => ParserT s st m Char+spaceChar = satisfy $ \c -> c == ' ' || c == '\t'++-- | Parses a nonspace, nonnewline character.+nonspaceChar :: Stream s m Char => ParserT s st m Char+nonspaceChar = satisfy $ flip notElem ['\t', '\n', ' ', '\r']++-- | Skips zero or more spaces or tabs.+skipSpaces :: Stream s m Char => ParserT s st m ()+skipSpaces = skipMany spaceChar++-- | Skips zero or more spaces or tabs, then reads a newline.+blankline :: Stream s m Char => ParserT s st m Char+blankline = try $ skipSpaces >> newline++-- | Parses one or more blank lines and returns a string of newlines.+blanklines :: Stream s m Char => ParserT s st m [Char]+blanklines = many1 blankline++-- | Parses material enclosed between start and end parsers.+enclosed :: Stream s m Char => ParserT s st m t -- ^ start parser+ -> ParserT s st m end -- ^ end parser+ -> ParserT s st m a -- ^ content parser (to be used repeatedly)+ -> ParserT s st m [a]+enclosed start end parser = try $+ start >> notFollowedBy space >> many1Till parser end++-- | Parse string, case insensitive.+stringAnyCase :: Stream s m Char => [Char] -> ParserT s st m String+stringAnyCase [] = string ""+stringAnyCase (x:xs) = do+ firstChar <- char (toUpper x) <|> char (toLower x)+ rest <- stringAnyCase xs+ return (firstChar:rest)++-- | Parse contents of 'str' using 'parser' and return result.+parseFromString :: Stream s m t => ParserT s st m a -> s -> ParserT s st m a+parseFromString parser str = do+ oldPos <- getPosition+ oldInput <- getInput+ setInput str+ result <- parser+ setInput oldInput+ setPosition oldPos+ return result++-- | Parse raw line block up to and including blank lines.+lineClump :: Stream [Char] m Char => ParserT [Char] st m String+lineClump = blanklines+ <|> (many1 (notFollowedBy blankline >> anyLine) >>= return . unlines)++-- | Parse a string of characters between an open character+-- and a close character, including text between balanced+-- pairs of open and close, which must be different. For example,+-- @charsInBalanced '(' ')' anyChar@ will parse "(hello (there))"+-- and return "hello (there)".+charsInBalanced :: Stream s m Char => Char -> Char -> ParserT s st m Char+ -> ParserT s st m String+charsInBalanced open close parser = try $ do+ char open+ let isDelim c = c == open || c == close+ raw <- many $ many1 (notFollowedBy (satisfy isDelim) >> parser)+ <|> (do res <- charsInBalanced open close parser+ return $ [open] ++ res ++ [close])+ char close+ return $ concat raw++-- old charsInBalanced would be:+-- charsInBalanced open close (noneOf "\n" <|> char '\n' >> notFollowedBy blankline)+-- old charsInBalanced' would be:+-- charsInBalanced open close anyChar++-- Auxiliary functions for romanNumeral:++lowercaseRomanDigits :: [Char]+lowercaseRomanDigits = ['i','v','x','l','c','d','m']++uppercaseRomanDigits :: [Char]+uppercaseRomanDigits = map toUpper lowercaseRomanDigits++-- | Parses a roman numeral (uppercase or lowercase), returns number.+romanNumeral :: Stream s m Char => Bool -- ^ Uppercase if true+ -> ParserT s st m Int+romanNumeral upperCase = do+ let romanDigits = if upperCase+ then uppercaseRomanDigits+ else lowercaseRomanDigits+ lookAhead $ oneOf romanDigits+ let [one, five, ten, fifty, hundred, fivehundred, thousand] =+ map char romanDigits+ thousands <- many thousand >>= (return . (1000 *) . length)+ ninehundreds <- option 0 $ try $ hundred >> thousand >> return 900+ fivehundreds <- many fivehundred >>= (return . (500 *) . length)+ fourhundreds <- option 0 $ try $ hundred >> fivehundred >> return 400+ hundreds <- many hundred >>= (return . (100 *) . length)+ nineties <- option 0 $ try $ ten >> hundred >> return 90+ fifties <- many fifty >>= (return . (50 *) . length)+ forties <- option 0 $ try $ ten >> fifty >> return 40+ tens <- many ten >>= (return . (10 *) . length)+ nines <- option 0 $ try $ one >> ten >> return 9+ fives <- many five >>= (return . (5 *) . length)+ fours <- option 0 $ try $ one >> five >> return 4+ ones <- many one >>= (return . length)+ let total = thousands + ninehundreds + fivehundreds + fourhundreds ++ hundreds + nineties + fifties + forties + tens + nines ++ fives + fours + ones+ if total == 0+ then fail "not a roman numeral"+ else return total++-- Parsers for email addresses and URIs++-- | Parses an email address; returns original and corresponding+-- escaped mailto: URI.+emailAddress :: Stream s m Char => ParserT s st m (String, String)+emailAddress = try $ toResult <$> mailbox <*> (char '@' *> domain)+ where toResult mbox dom = let full = fromEntities $ mbox ++ '@':dom+ in (full, escapeURI $ "mailto:" ++ full)+ mailbox = intercalate "." <$> (emailWord `sepby1` dot)+ domain = intercalate "." <$> (subdomain `sepby1` dot)+ dot = char '.'+ subdomain = many1 $ alphaNum <|> innerPunct+ innerPunct = try (satisfy (\c -> isEmailPunct c || c == '@') <*+ notFollowedBy space)+ emailWord = many1 $ satisfy isEmailChar+ isEmailChar c = isAlphaNum c || isEmailPunct c+ isEmailPunct c = c `elem` "!\"#$%&'*+-/=?^_{|}~;"+ -- note: sepBy1 from parsec consumes input when sep+ -- succeeds and p fails, so we use this variant here.+ sepby1 p sep = (:) <$> p <*> (many (try $ sep >> p))+++-- Schemes from http://www.iana.org/assignments/uri-schemes.html plus+-- the unofficial schemes coap, doi, javascript, isbn, pmid+schemes :: [String]+schemes = ["coap","doi","javascript","aaa","aaas","about","acap","cap","cid",+ "crid","data","dav","dict","dns","file","ftp","geo","go","gopher",+ "h323","http","https","iax","icap","im","imap","info","ipp","iris",+ "iris.beep","iris.xpc","iris.xpcs","iris.lwz","ldap","mailto","mid",+ "msrp","msrps","mtqp","mupdate","news","nfs","ni","nih","nntp",+ "opaquelocktoken","pop","pres","rtsp","service","session","shttp","sieve",+ "sip","sips","sms","snmp","soap.beep","soap.beeps","tag","tel","telnet",+ "tftp","thismessage","tn3270","tip","tv","urn","vemmi","ws","wss","xcon",+ "xcon-userid","xmlrpc.beep","xmlrpc.beeps","xmpp","z39.50r","z39.50s",+ "adiumxtra","afp","afs","aim","apt","attachment","aw","beshare","bitcoin",+ "bolo","callto","chrome","chrome-extension","com-eventbrite-attendee",+ "content", "cvs","dlna-playsingle","dlna-playcontainer","dtn","dvb",+ "ed2k","facetime","feed","finger","fish","gg","git","gizmoproject",+ "gtalk","hcp","icon","ipn","irc","irc6","ircs","itms","jar","jms",+ "keyparc","lastfm","ldaps","magnet","maps","market","message","mms",+ "ms-help","msnim","mumble","mvn","notes","oid","palm","paparazzi",+ "platform","proxy","psyc","query","res","resource","rmi","rsync",+ "rtmp","secondlife","sftp","sgn","skype","smb","soldat","spotify",+ "ssh","steam","svn","teamspeak","things","udp","unreal","ut2004",+ "ventrilo","view-source","webcal","wtai","wyciwyg","xfire","xri",+ "ymsgr", "isbn", "pmid"]++uriScheme :: Stream s m Char => ParserT s st m String+uriScheme = oneOfStringsCI schemes++-- | Parses a URI. Returns pair of original and URI-escaped version.+uri :: Stream [Char] m Char => ParserT [Char] st m (String, String)+uri = try $ do+ scheme <- uriScheme+ char ':'+ -- We allow punctuation except at the end, since+ -- we don't want the trailing '.' in 'http://google.com.' We want to allow+ -- http://en.wikipedia.org/wiki/State_of_emergency_(disambiguation)+ -- as a URL, while NOT picking up the closing paren in+ -- (http://wikipedia.org). So we include balanced parens in the URL.+ let isWordChar c = isAlphaNum c || c == '_' || c == '/' || c == '+' ||+ not (isAscii c)+ let wordChar = satisfy isWordChar+ let percentEscaped = try $ char '%' >> skipMany1 (satisfy isHexDigit)+ let entity = () <$ characterReference+ let punct = skipMany1 (char ',')+ <|> () <$ (satisfy (\c -> not (isSpace c) && c /= '<'))+ let uriChunk = skipMany1 wordChar+ <|> percentEscaped+ <|> entity+ <|> (try $ punct >>+ lookAhead (void (satisfy isWordChar) <|> percentEscaped))+ str <- snd <$> withRaw (skipMany1 ( () <$+ (enclosed (char '(') (char ')') uriChunk+ <|> enclosed (char '{') (char '}') uriChunk+ <|> enclosed (char '[') (char ']') uriChunk)+ <|> uriChunk))+ str' <- option str $ char '/' >> return (str ++ "/")+ let uri' = scheme ++ ":" ++ fromEntities str'+ return (uri', escapeURI uri')++-- | Parse the internal code of an inline math element until it encounters a+-- successful parse of the specified closing parser.+mathInlineCodeUntil :: Stream s m Char => ParserT s st m String -> ParserT s st m [String]+mathInlineCodeUntil cl = many1Till (+ count 1 (noneOf " \t\n\\")+ <|> (char '\\' >> anyChar >>= \c -> return ['\\',c])+ <|> do (blankline <* notFollowedBy' blankline) <|>+ (oneOf " \t" <* skipMany (oneOf " \t"))+ notFollowedBy (char '$')+ return " "+ ) (try $ cl)++mathInlineWith :: Stream s m Char => String -> String -> ParserT s st m String+mathInlineWith op cl = try $ do+ string op+ notFollowedBy space+ words' <- mathInlineCodeUntil (string cl)+ notFollowedBy digit -- to prevent capture of $5+ return $ concat words'++mathDisplayWith :: Stream s m Char => String -> String -> ParserT s st m String+mathDisplayWith op cl = try $ do+ string op+ many1Till (noneOf "\n" <|> (newline <* notFollowedBy' blankline)) (try $ string cl)++-- | Generic version of mathInlineWith that takes any opening and closing+-- parsers instead of just strings.+mathInlineWith' :: (HasReaderOptions st , Stream s m Char) => ParserT s st m String+ -> ParserT s st m String+ -> ParserT s st m String+mathInlineWith' op cl = try $ do+ op+ notFollowedBy space+ words' <- mathInlineCodeUntil cl+ notFollowedBy digit -- to prevent capture of $5+ return $ concat words'++mathDisplay :: (HasReaderOptions st, Stream s m Char)+ => ParserT s st m String+mathDisplay =+ (guardEnabled Ext_tex_math_dollars >> mathDisplayWith "$$" "$$")+ <|> (guardEnabled Ext_tex_math_single_backslash >>+ mathDisplayWith "\\[" "\\]")+ <|> (guardEnabled Ext_tex_math_double_backslash >>+ mathDisplayWith "\\\\[" "\\\\]")++mathInline :: (HasReaderOptions st , Stream s m Char)+ => ParserT s st m String+mathInline =+ (guardEnabled Ext_tex_math_dollars >> mathInlineWith "$" "$")+ <|> (guardEnabled Ext_tex_math_single_backslash >>+ mathInlineWith "\\(" "\\)")+ <|> (guardEnabled Ext_tex_math_double_backslash >>+ mathInlineWith "\\\\(" "\\\\)")++-- | Applies a parser, returns tuple of its results and its horizontal+-- displacement (the difference between the source column at the end+-- and the source column at the beginning). Vertical displacement+-- (source row) is ignored.+withHorizDisplacement :: Stream s m Char+ => ParserT s st m a -- ^ Parser to apply+ -> ParserT s st m (a, Int) -- ^ (result, displacement)+withHorizDisplacement parser = do+ pos1 <- getPosition+ result <- parser+ pos2 <- getPosition+ return (result, sourceColumn pos2 - sourceColumn pos1)++-- | Applies a parser and returns the raw string that was parsed,+-- along with the value produced by the parser.+withRaw :: Stream [Char] m Char => ParsecT [Char] st m a -> ParsecT [Char] st m (a, [Char])+withRaw parser = do+ pos1 <- getPosition+ inp <- getInput+ result <- parser+ pos2 <- getPosition+ let (l1,c1) = (sourceLine pos1, sourceColumn pos1)+ let (l2,c2) = (sourceLine pos2, sourceColumn pos2)+ let inplines = take ((l2 - l1) + 1) $ lines inp+ let raw = case inplines of+ [] -> ""+ [l] -> take (c2 - c1) l+ ls -> unlines (init ls) ++ take (c2 - 1) (last ls)+ return (result, raw)++-- | Parses backslash, then applies character parser.+escaped :: Stream s m Char+ => ParserT s st m Char -- ^ Parser for character to escape+ -> ParserT s st m Char+escaped parser = try $ char '\\' >> parser++-- | Parse character entity.+characterReference :: Stream s m Char => ParserT s st m Char+characterReference = try $ do+ char '&'+ ent <- many1Till nonspaceChar (char ';')+ case lookupEntity ent of+ Just c -> return c+ Nothing -> fail "entity not found"++-- | Parses an uppercase roman numeral and returns (UpperRoman, number).+upperRoman :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)+upperRoman = do+ num <- romanNumeral True+ return (UpperRoman, num)++-- | Parses a lowercase roman numeral and returns (LowerRoman, number).+lowerRoman :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)+lowerRoman = do+ num <- romanNumeral False+ return (LowerRoman, num)++-- | Parses a decimal numeral and returns (Decimal, number).+decimal :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)+decimal = do+ num <- many1 digit+ return (Decimal, read num)++-- | Parses a '@' and optional label and+-- returns (DefaultStyle, [next example number]). The next+-- example number is incremented in parser state, and the label+-- (if present) is added to the label table.+exampleNum :: Stream s m Char+ => ParserT s ParserState m (ListNumberStyle, Int)+exampleNum = do+ char '@'+ lab <- many (alphaNum <|> satisfy (\c -> c == '_' || c == '-'))+ st <- getState+ let num = stateNextExample st+ let newlabels = if null lab+ then stateExamples st+ else M.insert lab num $ stateExamples st+ updateState $ \s -> s{ stateNextExample = num + 1+ , stateExamples = newlabels }+ return (Example, num)++-- | Parses a '#' returns (DefaultStyle, 1).+defaultNum :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)+defaultNum = do+ char '#'+ return (DefaultStyle, 1)++-- | Parses a lowercase letter and returns (LowerAlpha, number).+lowerAlpha :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)+lowerAlpha = do+ ch <- oneOf ['a'..'z']+ return (LowerAlpha, ord ch - ord 'a' + 1)++-- | Parses an uppercase letter and returns (UpperAlpha, number).+upperAlpha :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)+upperAlpha = do+ ch <- oneOf ['A'..'Z']+ return (UpperAlpha, ord ch - ord 'A' + 1)++-- | Parses a roman numeral i or I+romanOne :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)+romanOne = (char 'i' >> return (LowerRoman, 1)) <|>+ (char 'I' >> return (UpperRoman, 1))++-- | Parses an ordered list marker and returns list attributes.+anyOrderedListMarker :: Stream s m Char => ParserT s ParserState m ListAttributes+anyOrderedListMarker = choice $+ [delimParser numParser | delimParser <- [inPeriod, inOneParen, inTwoParens],+ numParser <- [decimal, exampleNum, defaultNum, romanOne,+ lowerAlpha, lowerRoman, upperAlpha, upperRoman]]++-- | Parses a list number (num) followed by a period, returns list attributes.+inPeriod :: Stream s m Char+ => ParserT s st m (ListNumberStyle, Int)+ -> ParserT s st m ListAttributes+inPeriod num = try $ do+ (style, start) <- num+ char '.'+ let delim = if style == DefaultStyle+ then DefaultDelim+ else Period+ return (start, style, delim)++-- | Parses a list number (num) followed by a paren, returns list attributes.+inOneParen :: Stream s m Char+ => ParserT s st m (ListNumberStyle, Int)+ -> ParserT s st m ListAttributes+inOneParen num = try $ do+ (style, start) <- num+ char ')'+ return (start, style, OneParen)++-- | Parses a list number (num) enclosed in parens, returns list attributes.+inTwoParens :: Stream s m Char+ => ParserT s st m (ListNumberStyle, Int)+ -> ParserT s st m ListAttributes+inTwoParens num = try $ do+ char '('+ (style, start) <- num+ char ')'+ return (start, style, TwoParens)++-- | Parses an ordered list marker with a given style and delimiter,+-- returns number.+orderedListMarker :: Stream s m Char+ => ListNumberStyle+ -> ListNumberDelim+ -> ParserT s ParserState m Int+orderedListMarker style delim = do+ let num = defaultNum <|> -- # can continue any kind of list+ case style of+ DefaultStyle -> decimal+ Example -> exampleNum+ Decimal -> decimal+ UpperRoman -> upperRoman+ LowerRoman -> lowerRoman+ UpperAlpha -> upperAlpha+ LowerAlpha -> lowerAlpha+ let context = case delim of+ DefaultDelim -> inPeriod+ Period -> inPeriod+ OneParen -> inOneParen+ TwoParens -> inTwoParens+ (start, _, _) <- context num+ return start++-- | Parses a character reference and returns a Str element.+charRef :: Stream s m Char => ParserT s st m Inline+charRef = do+ c <- characterReference+ return $ Str [c]++lineBlockLine :: Stream [Char] m Char => ParserT [Char] st m String+lineBlockLine = try $ do+ char '|'+ char ' '+ white <- many (spaceChar >> return '\160')+ notFollowedBy newline+ line <- anyLine+ continuations <- many (try $ char ' ' >> anyLine)+ return $ white ++ unwords (line : continuations)++-- | Parses an RST-style line block and returns a list of strings.+lineBlockLines :: Stream [Char] m Char => ParserT [Char] st m [String]+lineBlockLines = try $ do+ lines' <- many1 lineBlockLine+ skipMany1 $ blankline <|> try (char '|' >> blankline)+ return lines'++-- | Parse a table using 'headerParser', 'rowParser',+-- 'lineParser', and 'footerParser'.+tableWith :: Stream s m Char+ => ParserT s ParserState m ([[Block]], [Alignment], [Int])+ -> ([Int] -> ParserT s ParserState m [[Block]])+ -> ParserT s ParserState m sep+ -> ParserT s ParserState m end+ -> ParserT s ParserState m Block+tableWith headerParser rowParser lineParser footerParser = try $ do+ (heads, aligns, indices) <- headerParser+ lines' <- rowParser indices `sepEndBy1` lineParser+ footerParser+ numColumns <- getOption readerColumns+ let widths = if (indices == [])+ then replicate (length aligns) 0.0+ else widthsFromIndices numColumns indices+ return $ Table [] aligns widths heads lines'++-- Calculate relative widths of table columns, based on indices+widthsFromIndices :: Int -- Number of columns on terminal+ -> [Int] -- Indices+ -> [Double] -- Fractional relative sizes of columns+widthsFromIndices _ [] = []+widthsFromIndices numColumns' indices =+ let numColumns = max numColumns' (if null indices then 0 else last indices)+ lengths' = zipWith (-) indices (0:indices)+ lengths = reverse $+ case reverse lengths' of+ [] -> []+ [x] -> [x]+ -- compensate for the fact that intercolumn+ -- spaces are counted in widths of all columns+ -- but the last...+ (x:y:zs) -> if x < y && y - x <= 2+ then y:y:zs+ else x:y:zs+ totLength = sum lengths+ quotient = if totLength > numColumns+ then fromIntegral totLength+ else fromIntegral numColumns+ fracs = map (\l -> (fromIntegral l) / quotient) lengths in+ tail fracs++---++-- Parse a grid table: starts with row of '-' on top, then header+-- (which may be grid), then the rows,+-- which may be grid, separated by blank lines, and+-- ending with a footer (dashed line followed by blank line).+gridTableWith :: Stream [Char] m Char+ => ParserT [Char] ParserState m [Block] -- ^ Block list parser+ -> Bool -- ^ Headerless table+ -> ParserT [Char] ParserState m Block+gridTableWith blocks headless =+ tableWith (gridTableHeader headless blocks) (gridTableRow blocks)+ (gridTableSep '-') gridTableFooter++gridTableSplitLine :: [Int] -> String -> [String]+gridTableSplitLine indices line = map removeFinalBar $ tail $+ splitStringByIndices (init indices) $ trimr line++gridPart :: Stream s m Char => Char -> ParserT s st m (Int, Int)+gridPart ch = do+ dashes <- many1 (char ch)+ char '+'+ return (length dashes, length dashes + 1)++gridDashedLines :: Stream s m Char => Char -> ParserT s st m [(Int,Int)]+gridDashedLines ch = try $ char '+' >> many1 (gridPart ch) <* blankline++removeFinalBar :: String -> String+removeFinalBar =+ reverse . dropWhile (`elem` " \t") . dropWhile (=='|') . reverse++-- | Separator between rows of grid table.+gridTableSep :: Stream s m Char => Char -> ParserT s ParserState m Char+gridTableSep ch = try $ gridDashedLines ch >> return '\n'++-- | Parse header for a grid table.+gridTableHeader :: Stream [Char] m Char+ => Bool -- ^ Headerless table+ -> ParserT [Char] ParserState m [Block]+ -> ParserT [Char] ParserState m ([[Block]], [Alignment], [Int])+gridTableHeader headless blocks = try $ do+ optional blanklines+ dashes <- gridDashedLines '-'+ rawContent <- if headless+ then return $ repeat ""+ else many1+ (notFollowedBy (gridTableSep '=') >> char '|' >>+ many1Till anyChar newline)+ if headless+ then return ()+ else gridTableSep '=' >> return ()+ let lines' = map snd dashes+ let indices = scanl (+) 0 lines'+ let aligns = replicate (length lines') AlignDefault+ -- RST does not have a notion of alignments+ let rawHeads = if headless+ then replicate (length dashes) ""+ else map (intercalate " ") $ transpose+ $ map (gridTableSplitLine indices) rawContent+ heads <- mapM (parseFromString blocks) $ map trim rawHeads+ return (heads, aligns, indices)++gridTableRawLine :: Stream s m Char => [Int] -> ParserT s ParserState m [String]+gridTableRawLine indices = do+ char '|'+ line <- many1Till anyChar newline+ return (gridTableSplitLine indices line)++-- | Parse row of grid table.+gridTableRow :: Stream [Char] m Char+ => ParserT [Char] ParserState m [Block]+ -> [Int]+ -> ParserT [Char] ParserState m [[Block]]+gridTableRow blocks indices = do+ colLines <- many1 (gridTableRawLine indices)+ let cols = map ((++ "\n") . unlines . removeOneLeadingSpace) $+ transpose colLines+ mapM (liftM compactifyCell . parseFromString blocks) cols++removeOneLeadingSpace :: [String] -> [String]+removeOneLeadingSpace xs =+ if all startsWithSpace xs+ then map (drop 1) xs+ else xs+ where startsWithSpace "" = True+ startsWithSpace (y:_) = y == ' '++compactifyCell :: [Block] -> [Block]+compactifyCell bs = head $ compactify [bs]++-- | Parse footer for a grid table.+gridTableFooter :: Stream s m Char => ParserT s ParserState m [Char]+gridTableFooter = blanklines++---++-- | Removes the ParsecT layer from the monad transformer stack+readWithM :: (Monad m, Functor m)+ => ParserT [Char] st m a -- ^ parser+ -> st -- ^ initial state+ -> String -- ^ input+ -> m a+readWithM parser state input =+ handleError <$> (runParserT parser state "source" input)+ where+ handleError (Left err') =+ let errPos = errorPos err'+ errLine = sourceLine errPos+ errColumn = sourceColumn errPos+ theline = (lines input ++ [""]) !! (errLine - 1)+ in error $ "\nError at " ++ show err' ++ "\n" +++ theline ++ "\n" ++ replicate (errColumn - 1) ' ' +++ "^"+ handleError (Right result) = result++-- | Parse a string with a given parser and state+readWith :: Parser [Char] st a+ -> st+ -> String+ -> a+readWith p t inp = runIdentity $ readWithM p t inp++-- | Parse a string with @parser@ (for testing).+testStringWith :: (Show a, Stream [Char] Identity Char)+ => ParserT [Char] ParserState Identity a+ -> [Char]+ -> IO ()+testStringWith parser str = UTF8.putStrLn $ show $+ readWith parser defaultParserState str++-- | Parsing options.+data ParserState = ParserState+ { stateOptions :: ReaderOptions, -- ^ User options+ stateParserContext :: ParserContext, -- ^ Inside list?+ stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?+ stateAllowLinks :: Bool, -- ^ Allow parsing of links+ stateMaxNestingLevel :: Int, -- ^ Max # of nested Strong/Emph+ stateLastStrPos :: Maybe SourcePos, -- ^ Position after last str parsed+ stateKeys :: KeyTable, -- ^ List of reference keys (with fallbacks)+ stateSubstitutions :: SubstTable, -- ^ List of substitution references+ stateNotes :: NoteTable, -- ^ List of notes (raw bodies)+ stateNotes' :: NoteTable', -- ^ List of notes (parsed bodies)+ stateMeta :: Meta, -- ^ Document metadata+ stateMeta' :: F Meta, -- ^ Document metadata+ stateHeaderTable :: [HeaderType], -- ^ Ordered list of header types used+ stateHeaders :: M.Map Inlines String, -- ^ List of headers and ids (used for implicit ref links)+ stateIdentifiers :: [String], -- ^ List of header identifiers used+ stateXRefIdents :: XRefIdentifiers, -- ^ Idents for numerical x-refs+ stateNextExample :: Int, -- ^ Number of next example+ stateExamples :: M.Map String Int, -- ^ Map from example labels to numbers+ stateHasChapters :: Bool, -- ^ True if \chapter encountered+ stateMacros :: [Macro], -- ^ List of macros defined so far+ stateMathDefs :: String, -- ^ not-parsed LaTeX math macros+ stateRstDefaultRole :: String, -- ^ Current rST default interpreted text role+ stateRstCustomRoles :: M.Map String (String, Maybe String, Attr -> (String, Attr)), -- ^ Current rST custom text roles+ -- Triple represents: 1) Base role, 2) Optional format (only for :raw:+ -- roles), 3) Source language annotation for code (could be used to+ -- annotate role classes too).+ stateKeepSpacing :: Bool, -- ^ switch for strict spacing mode+ stateLastWidth :: Maybe String, -- ^ last defined image width+ stateLastHeight :: Maybe String, -- ^ last defined image height+ stateCaption :: Maybe Inlines, -- ^ Caption in current environment+ stateInHtmlBlock :: Maybe String, -- ^ Tag type of HTML block being parsed+ stateMarkdownAttribute :: Bool, -- ^ True if in markdown=1 context+ stateWarnings :: [String] -- ^ Warnings generated by the parser+ }++-- | Lists of identifiers that are potentially cross-referenceable+data XRefIdentifiers = XRefIdentifiers+ { idsForMath :: [String], -- Equations+ idsForFigure :: [String], -- Figures+ idsForSubfigure :: [([String], Int)], -- Subfigures (corresp. with numerical label of a figure)+ idsForTables :: [String], -- Tables+ idsForAlgorithms :: [String], -- Algorithms, Listings+ idsForCodeBlocks :: [String], -- Code listings (as floats)+ idsForStatements :: [String] -- Theorems, Definitons, Examples, etc+ }++defaultXRefIdentifiers :: XRefIdentifiers+defaultXRefIdentifiers =+ XRefIdentifiers { idsForMath = [],+ idsForFigure = [],+ idsForSubfigure = [],+ idsForTables = [],+ idsForAlgorithms = [],+ idsForCodeBlocks = [],+ idsForStatements = []}++-- | Generate a default numerical label for numbered cross-references+getNumericalLabel :: String -> XRefIdentifiers -> String+getNumericalLabel ident ids+ | ident `elem` (idsForMath ids) = numInIdList ident $ idsForMath ids+ | ident `elem` (idsForFigure ids) = numInIdList ident $ idsForFigure ids+ | any ((ident `elem`) . fst) (idsForSubfigure ids) =+ let figId = fromJust $ findIndex ((ident `elem`) . fst) $ idsForSubfigure ids+ numSubfig = fromJust $ elemIndex ident $ fst ((idsForSubfigure ids) !! figId)+ numFig = snd ((idsForSubfigure ids) !! figId)+ in if length (fst $ (idsForSubfigure ids) !! figId) == 1+ then (show numFig)+ else (show numFig) ++ (alphEnum (numSubfig+1))+ | ident `elem` (idsForTables ids) = numInIdList ident $ idsForTables ids+ | ident `elem` (idsForAlgorithms ids) = numInIdList ident $ idsForAlgorithms ids+ | ident `elem` (idsForCodeBlocks ids) = numInIdList ident $ idsForCodeBlocks ids+ | ident `elem` (idsForStatements ids) = numInIdList ident $ idsForStatements ids+ | otherwise = "#" ++ ident++-- | Show index in list stripped of empty entries+numInIdList :: String -> [String] -> String+numInIdList ident idList =+ case (elemIndex ident $ filter (/= "") idList) of+ Just index -> show (index + 1) -- elemIndex starts from zero+ Nothing -> ""++instance Default ParserState where+ def = defaultParserState++instance HasMeta ParserState where+ setMeta field val st =+ st{ stateMeta = setMeta field val $ stateMeta st }+ deleteMeta field st =+ st{ stateMeta = deleteMeta field $ stateMeta st }++class HasReaderOptions st where+ extractReaderOptions :: st -> ReaderOptions+ getOption :: (Stream s m t) => (ReaderOptions -> b) -> ParserT s st m b+ -- default+ getOption f = (f . extractReaderOptions) <$> getState++class HasQuoteContext st m where+ getQuoteContext :: (Stream s m t) => ParsecT s st m QuoteContext+ withQuoteContext :: QuoteContext -> ParsecT s st m a -> ParsecT s st m a++instance Monad m => HasQuoteContext ParserState m where+ getQuoteContext = stateQuoteContext <$> getState+ withQuoteContext context parser = do+ oldState <- getState+ let oldQuoteContext = stateQuoteContext oldState+ setState oldState { stateQuoteContext = context }+ result <- parser+ newState <- getState+ setState newState { stateQuoteContext = oldQuoteContext }+ return result++instance HasReaderOptions ParserState where+ extractReaderOptions = stateOptions++class HasHeaderMap st where+ extractHeaderMap :: st -> M.Map Inlines String+ updateHeaderMap :: (M.Map Inlines String -> M.Map Inlines String) ->+ st -> st++instance HasHeaderMap ParserState where+ extractHeaderMap = stateHeaders+ updateHeaderMap f st = st{ stateHeaders = f $ stateHeaders st }++class HasIdentifierList st where+ extractIdentifierList :: st -> [String]+ updateIdentifierList :: ([String] -> [String]) -> st -> st++instance HasIdentifierList ParserState where+ extractIdentifierList = stateIdentifiers+ updateIdentifierList f st = st{ stateIdentifiers = f $ stateIdentifiers st }++class HasMacros st where+ extractMacros :: st -> [Macro]+ updateMacros :: ([Macro] -> [Macro]) -> st -> st++instance HasMacros ParserState where+ extractMacros = stateMacros+ updateMacros f st = st{ stateMacros = f $ stateMacros st }++class HasLastStrPosition st where+ setLastStrPos :: SourcePos -> st -> st+ getLastStrPos :: st -> Maybe SourcePos++instance HasLastStrPosition ParserState where+ setLastStrPos pos st = st{ stateLastStrPos = Just pos }+ getLastStrPos st = stateLastStrPos st++defaultParserState :: ParserState+defaultParserState =+ ParserState { stateOptions = def,+ stateParserContext = NullState,+ stateQuoteContext = NoQuote,+ stateAllowLinks = True,+ stateMaxNestingLevel = 6,+ stateLastStrPos = Nothing,+ stateKeys = M.empty,+ stateSubstitutions = M.empty,+ stateNotes = [],+ stateNotes' = [],+ stateMeta = nullMeta,+ stateMeta' = return nullMeta,+ stateHeaderTable = [],+ stateHeaders = M.empty,+ stateIdentifiers = [],+ stateXRefIdents = defaultXRefIdentifiers,+ stateNextExample = 1,+ stateExamples = M.empty,+ stateHasChapters = False,+ stateMacros = [],+ stateMathDefs = "",+ stateRstDefaultRole = "title-reference",+ stateRstCustomRoles = M.empty,+ stateKeepSpacing = False,+ stateLastWidth = Nothing,+ stateLastHeight = Nothing,+ stateCaption = Nothing,+ stateInHtmlBlock = Nothing,+ stateMarkdownAttribute = False,+ stateWarnings = []}++-- | Succeed only if the extension is enabled.+guardEnabled :: (Stream s m a, HasReaderOptions st) => Extension -> ParserT s st m ()+guardEnabled ext = getOption readerExtensions >>= guard . Set.member ext++-- | Succeed only if the extension is disabled.+guardDisabled :: (Stream s m a, HasReaderOptions st) => Extension -> ParserT s st m ()+guardDisabled ext = getOption readerExtensions >>= guard . not . Set.member ext++-- | Update the position on which the last string ended.+updateLastStrPos :: (Stream s m a, HasLastStrPosition st) => ParserT s st m ()+updateLastStrPos = getPosition >>= updateState . setLastStrPos++-- | Whether we are right after the end of a string.+notAfterString :: (Stream s m a, HasLastStrPosition st) => ParserT s st m Bool+notAfterString = do+ pos <- getPosition+ st <- getState+ return $ getLastStrPos st /= Just pos++data HeaderType+ = SingleHeader Char -- ^ Single line of characters underneath+ | DoubleHeader Char -- ^ Lines of characters above and below+ deriving (Eq, Show)++data ParserContext+ = ListItemState -- ^ Used when running parser on list item contents+ | NullState -- ^ Default state+ deriving (Eq, Show)++data QuoteContext+ = InSingleQuote -- ^ Used when parsing inside single quotes+ | InDoubleQuote -- ^ Used when parsing inside double quotes+ | NoQuote -- ^ Used when not parsing inside quotes+ deriving (Eq, Show)++type NoteTable = [(String, String)]++type NoteTable' = [(String, F Blocks)] -- used in markdown reader++newtype Key = Key String deriving (Show, Read, Eq, Ord)++toKey :: String -> Key+toKey = Key . map toLower . unwords . words++type KeyTable = M.Map Key Target++type SubstTable = M.Map Key Inlines++-- | Add header to the list of headers in state, together+-- with its associated identifier. If the identifier is null+-- and the auto_identifers extension is set, generate a new+-- unique identifier, and update the list of identifiers+-- in state.+registerHeader :: (Stream s m a, HasReaderOptions st, HasHeaderMap st, HasIdentifierList st)+ => Attr -> Inlines -> ParserT s st m Attr+registerHeader (ident,classes,kvs) header' = do+ ids <- extractIdentifierList <$> getState+ exts <- getOption readerExtensions+ let insert' = M.insertWith (\_new old -> old)+ if null ident && Ext_auto_identifiers `Set.member` exts+ then do+ let id' = uniqueIdent (B.toList header') ids+ let id'' = if Ext_ascii_identifiers `Set.member` exts+ then catMaybes $ map toAsciiChar id'+ else id'+ updateState $ updateIdentifierList $+ if id' == id'' then (id' :) else ([id', id''] ++)+ updateState $ updateHeaderMap $ insert' header' id'+ return (id'',classes,kvs)+ else do+ unless (null ident) $+ updateState $ updateHeaderMap $ insert' header' ident+ return (ident,classes,kvs)++-- | Fail unless we're in "smart typography" mode.+failUnlessSmart :: (Stream s m a, HasReaderOptions st) => ParserT s st m ()+failUnlessSmart = getOption readerSmart >>= guard++smartPunctuation :: (HasReaderOptions st, HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)+ => ParserT s st m Inlines+ -> ParserT s st m Inlines+smartPunctuation inlineParser = do+ failUnlessSmart+ choice [ quoted inlineParser, apostrophe, dash, ellipses ]++apostrophe :: Stream s m Char => ParserT s st m Inlines+apostrophe = (char '\'' <|> char '\8217') >> return (B.str "\x2019")++quoted :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)+ => ParserT s st m Inlines+ -> ParserT s st m Inlines+quoted inlineParser = doubleQuoted inlineParser <|> singleQuoted inlineParser++singleQuoted :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)+ => ParserT s st m Inlines+ -> ParserT s st m Inlines+singleQuoted inlineParser = try $ do+ singleQuoteStart+ withQuoteContext InSingleQuote $ many1Till inlineParser singleQuoteEnd >>=+ return . B.singleQuoted . mconcat++doubleQuoted :: (HasQuoteContext st m, Stream s m Char)+ => ParserT s st m Inlines+ -> ParserT s st m Inlines+doubleQuoted inlineParser = try $ do+ doubleQuoteStart+ withQuoteContext InDoubleQuote $ manyTill inlineParser doubleQuoteEnd >>=+ return . B.doubleQuoted . mconcat++failIfInQuoteContext :: (HasQuoteContext st m, Stream s m t)+ => QuoteContext+ -> ParserT s st m ()+failIfInQuoteContext context = do+ context' <- getQuoteContext+ if context' == context+ then fail "already inside quotes"+ else return ()++charOrRef :: Stream s m Char => String -> ParserT s st m Char+charOrRef cs =+ oneOf cs <|> try (do c <- characterReference+ guard (c `elem` cs)+ return c)++singleQuoteStart :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)+ => ParserT s st m ()+singleQuoteStart = do+ failIfInQuoteContext InSingleQuote+ -- single quote start can't be right after str+ guard =<< notAfterString+ () <$ charOrRef "'\8216\145"++singleQuoteEnd :: Stream s m Char+ => ParserT s st m ()+singleQuoteEnd = try $ do+ charOrRef "'\8217\146"+ notFollowedBy alphaNum++doubleQuoteStart :: (HasQuoteContext st m, Stream s m Char)+ => ParserT s st m ()+doubleQuoteStart = do+ failIfInQuoteContext InDoubleQuote+ try $ do charOrRef "\"\8220\147"+ notFollowedBy . satisfy $ flip elem [' ', '\t', '\n']++doubleQuoteEnd :: Stream s m Char+ => ParserT s st m ()+doubleQuoteEnd = void (charOrRef "\"\8221\148")++ellipses :: Stream s m Char+ => ParserT s st m Inlines+ellipses = try (string "..." >> return (B.str "\8230"))++dash :: (HasReaderOptions st, Stream s m Char)+ => ParserT s st m Inlines+dash = try $ do+ oldDashes <- getOption readerOldDashes+ if oldDashes+ then do+ char '-'+ (char '-' >> return (B.str "\8212"))+ <|> (lookAhead digit >> return (B.str "\8211"))+ else do+ string "--"+ (char '-' >> return (B.str "\8212"))+ <|> return (B.str "\8211")++-- This is used to prevent exponential blowups for things like:+-- a**a*a**a*a**a*a**a*a**a*a**a*a**+nested :: Stream s m a+ => ParserT s ParserState m a+ -> ParserT s ParserState m a+nested p = do+ nestlevel <- stateMaxNestingLevel <$> getState+ guard $ nestlevel > 0+ updateState $ \st -> st{ stateMaxNestingLevel = stateMaxNestingLevel st - 1 }+ res <- p+ updateState $ \st -> st{ stateMaxNestingLevel = nestlevel }+ return res++citeKey :: (Stream s m Char, HasLastStrPosition st)+ => ParserT s st m (Bool, String)+citeKey = try $ do+ guard =<< notAfterString+ suppress_author <- option False (char '-' *> return True)+ char '@'+ firstChar <- letter <|> char '_'+ let regchar = satisfy (\c -> isAlphaNum c || c == '_')+ let internal p = try $ p <* lookAhead regchar+ rest <- many $ regchar <|> internal (oneOf ":.#$%&-+?<>~/")+ let key = firstChar:rest+ return (suppress_author, key)+++token :: (Stream s m t)+ => (t -> String)+ -> (t -> SourcePos)+ -> (t -> Maybe a)+ -> ParsecT s st m a+token pp pos match = tokenPrim pp (\_ t _ -> pos t) match++--+-- Macros+--++-- | Parse a \newcommand or \renewcommand macro definition.+macro :: (Stream [Char] m Char, HasMacros st, HasReaderOptions st)+ => ParserT [Char] st m Blocks+macro = do+ apply <- getOption readerApplyMacros+ inp <- getInput+ case parseMacroDefinitions inp of+ ([], _) -> mzero+ (ms, rest) -> do def' <- count (length inp - length rest) anyChar+ if apply+ then do+ updateState $ \st ->+ updateMacros (ms ++) st+ return mempty+ else return $ rawBlock "latex" def'++-- | Apply current macros to string.+applyMacros' :: (HasReaderOptions st, HasMacros st, Stream [Char] m Char)+ => String+ -> ParserT [Char] st m String+applyMacros' target = do+ apply <- getOption readerApplyMacros+ if apply+ then do macros <- extractMacros <$> getState+ return $ applyMacros macros target+ else return target
@@ -0,0 +1,534 @@+{-# LANGUAGE GeneralizedNewtypeDeriving, CPP #-}+{-+Copyright (C) 2010-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111(-1)307 USA+-}++{- |+ Module : Text.Pandoc.Pretty+ Copyright : Copyright (C) 2010-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++A prettyprinting library for the production of text documents,+including wrapped text, indentated blocks, and tables.+-}++module Text.Pandoc.Pretty (+ Doc+ , render+ , cr+ , blankline+ , blanklines+ , space+ , text+ , char+ , prefixed+ , flush+ , nest+ , hang+ , beforeNonBlank+ , nowrap+ , offset+ , height+ , lblock+ , cblock+ , rblock+ , (<>)+ , (<+>)+ , ($$)+ , ($+$)+ , isEmpty+ , empty+ , cat+ , hcat+ , hsep+ , vcat+ , vsep+ , nestle+ , chomp+ , inside+ , braces+ , brackets+ , parens+ , quotes+ , doubleQuotes+ , charWidth+ , realLength+ )++where+import Data.Sequence (Seq, fromList, (<|), singleton, mapWithIndex, viewl, ViewL(..))+import Data.Foldable (toList)+import Data.List (intercalate)+import Data.Monoid+import Data.String+import Control.Monad.State+import Data.Char (isSpace)++data RenderState a = RenderState{+ output :: [a] -- ^ In reverse order+ , prefix :: String+ , usePrefix :: Bool+ , lineLength :: Maybe Int -- ^ 'Nothing' means no wrapping+ , column :: Int+ , newlines :: Int -- ^ Number of preceding newlines+ }++type DocState a = State (RenderState a) ()++data D = Text Int String+ | Block Int [String]+ | Prefixed String Doc+ | BeforeNonBlank Doc+ | Flush Doc+ | BreakingSpace+ | CarriageReturn+ | NewLine+ | BlankLines Int -- number of blank lines+ deriving (Show)++newtype Doc = Doc { unDoc :: Seq D }+ deriving (Monoid, Show)++instance IsString Doc where+ fromString = text++isBlank :: D -> Bool+isBlank BreakingSpace = True+isBlank CarriageReturn = True+isBlank NewLine = True+isBlank (BlankLines _) = True+isBlank (Text _ (c:_)) = isSpace c+isBlank _ = False++-- | True if the document is empty.+isEmpty :: Doc -> Bool+isEmpty = null . toList . unDoc++-- | The empty document.+empty :: Doc+empty = mempty++#if MIN_VERSION_base(4,5,0)+-- (<>) is defined in Data.Monoid+#else+infixr 6 <>++-- | An infix synonym for 'mappend'.+-- @a <> b@ is the result of concatenating @a@ with @b@.+(<>) :: Monoid m => m -> m -> m+(<>) = mappend+{-# INLINE (<>) #-}+#endif++-- | Concatenate a list of 'Doc's.+cat :: [Doc] -> Doc+cat = mconcat++-- | Same as 'cat'.+hcat :: [Doc] -> Doc+hcat = mconcat++-- | Concatenate a list of 'Doc's, putting breakable spaces+-- between them.+infixr 6 <+>+(<+>) :: Doc -> Doc -> Doc+(<+>) x y = if isEmpty x+ then y+ else if isEmpty y+ then x+ else x <> space <> y++-- | Same as 'cat', but putting breakable spaces between the+-- 'Doc's.+hsep :: [Doc] -> Doc+hsep = foldr (<+>) empty++infixr 5 $$+-- | @a $$ b@ puts @a@ above @b@.+($$) :: Doc -> Doc -> Doc+($$) x y = if isEmpty x+ then y+ else if isEmpty y+ then x+ else x <> cr <> y++infixr 5 $+$+-- | @a $$ b@ puts @a@ above @b@, with a blank line between.+($+$) :: Doc -> Doc -> Doc+($+$) x y = if isEmpty x+ then y+ else if isEmpty y+ then x+ else x <> blankline <> y++-- | List version of '$$'.+vcat :: [Doc] -> Doc+vcat = foldr ($$) empty++-- | List version of '$+$'.+vsep :: [Doc] -> Doc+vsep = foldr ($+$) empty++-- | Removes leading blank lines from a 'Doc'.+nestle :: Doc -> Doc+nestle (Doc d) = Doc $ go d+ where go x = case viewl x of+ (BlankLines _ :< rest) -> go rest+ (NewLine :< rest) -> go rest+ _ -> x++-- | Chomps trailing blank space off of a 'Doc'.+chomp :: Doc -> Doc+chomp d = Doc (fromList dl')+ where dl = toList (unDoc d)+ dl' = reverse $ go $ reverse dl+ go [] = []+ go (BreakingSpace : xs) = go xs+ go (CarriageReturn : xs) = go xs+ go (NewLine : xs) = go xs+ go (BlankLines _ : xs) = go xs+ go (Prefixed s d' : xs) = Prefixed s (chomp d') : xs+ go xs = xs++outp :: (IsString a, Monoid a)+ => Int -> String -> DocState a+outp off s | off < 0 = do -- offset < 0 means newline characters+ st' <- get+ let rawpref = prefix st'+ when (column st' == 0 && usePrefix st' && not (null rawpref)) $ do+ let pref = reverse $ dropWhile isSpace $ reverse rawpref+ modify $ \st -> st{ output = fromString pref : output st+ , column = column st + realLength pref }+ let numnewlines = length $ takeWhile (=='\n') $ reverse s+ modify $ \st -> st { output = fromString s : output st+ , column = 0+ , newlines = newlines st + numnewlines }+outp off s = do -- offset >= 0 (0 might be combining char)+ st' <- get+ let pref = prefix st'+ when (column st' == 0 && usePrefix st' && not (null pref)) $ do+ modify $ \st -> st{ output = fromString pref : output st+ , column = column st + realLength pref }+ modify $ \st -> st{ output = fromString s : output st+ , column = column st + off+ , newlines = 0 }++-- | Renders a 'Doc'. @render (Just n)@ will use+-- a line length of @n@ to reflow text on breakable spaces.+-- @render Nothing@ will not reflow text.+render :: (Monoid a, IsString a)+ => Maybe Int -> Doc -> a+render linelen doc = fromString . mconcat . reverse . output $+ execState (renderDoc doc) startingState+ where startingState = RenderState{+ output = mempty+ , prefix = ""+ , usePrefix = True+ , lineLength = linelen+ , column = 0+ , newlines = 2 }++renderDoc :: (IsString a, Monoid a)+ => Doc -> DocState a+renderDoc = renderList . toList . unDoc++renderList :: (IsString a, Monoid a)+ => [D] -> DocState a+renderList [] = return ()+renderList (Text off s : xs) = do+ outp off s+ renderList xs++renderList (Prefixed pref d : xs) = do+ st <- get+ let oldPref = prefix st+ put st{ prefix = prefix st ++ pref }+ renderDoc d+ modify $ \s -> s{ prefix = oldPref }+ renderList xs++renderList (Flush d : xs) = do+ st <- get+ let oldUsePrefix = usePrefix st+ put st{ usePrefix = False }+ renderDoc d+ modify $ \s -> s{ usePrefix = oldUsePrefix }+ renderList xs++renderList (BeforeNonBlank d : xs) =+ case xs of+ (x:_) | isBlank x -> renderList xs+ | otherwise -> renderDoc d >> renderList xs+ [] -> renderList xs++renderList (BlankLines num : xs) = do+ st <- get+ case output st of+ _ | newlines st > num || null xs -> return ()+ | otherwise -> replicateM_ (1 + num - newlines st) (outp (-1) "\n")+ renderList xs++renderList (CarriageReturn : xs) = do+ st <- get+ if newlines st > 0 || null xs+ then renderList xs+ else do+ outp (-1) "\n"+ renderList xs++renderList (NewLine : xs) = do+ outp (-1) "\n"+ renderList xs++renderList (BreakingSpace : CarriageReturn : xs) = renderList (CarriageReturn:xs)+renderList (BreakingSpace : NewLine : xs) = renderList (NewLine:xs)+renderList (BreakingSpace : BlankLines n : xs) = renderList (BlankLines n:xs)+renderList (BreakingSpace : BreakingSpace : xs) = renderList (BreakingSpace:xs)+renderList (BreakingSpace : xs) = do+ let isText (Text _ _) = True+ isText (Block _ _) = True+ isText _ = False+ let isBreakingSpace BreakingSpace = True+ isBreakingSpace _ = False+ let xs' = dropWhile isBreakingSpace xs+ let next = takeWhile isText xs'+ st <- get+ let off = sum $ map offsetOf next+ case lineLength st of+ Just l | column st + 1 + off > l -> do+ outp (-1) "\n"+ renderList xs'+ _ -> do+ outp 1 " "+ renderList xs'++renderList (b1@Block{} : b2@Block{} : xs) =+ renderList (mergeBlocks False b1 b2 : xs)++renderList (b1@Block{} : BreakingSpace : b2@Block{} : xs) =+ renderList (mergeBlocks True b1 b2 : xs)++renderList (Block width lns : xs) = do+ st <- get+ let oldPref = prefix st+ case column st - realLength oldPref of+ n | n > 0 -> modify $ \s -> s{ prefix = oldPref ++ replicate n ' ' }+ _ -> return ()+ renderDoc $ blockToDoc width lns+ modify $ \s -> s{ prefix = oldPref }+ renderList xs++mergeBlocks :: Bool -> D -> D -> D+mergeBlocks addSpace (Block w1 lns1) (Block w2 lns2) =+ Block (w1 + w2 + if addSpace then 1 else 0) $+ zipWith (\l1 l2 -> pad w1 l1 ++ l2) (lns1 ++ empties) (map sp lns2 ++ empties)+ where empties = replicate (abs $ length lns1 - length lns2) ""+ pad n s = s ++ replicate (n - realLength s) ' '+ sp "" = ""+ sp xs = if addSpace then (' ' : xs) else xs+mergeBlocks _ _ _ = error "mergeBlocks tried on non-Block!"++blockToDoc :: Int -> [String] -> Doc+blockToDoc _ lns = text $ intercalate "\n" lns++offsetOf :: D -> Int+offsetOf (Text o _) = o+offsetOf (Block w _) = w+offsetOf BreakingSpace = 1+offsetOf _ = 0++-- | A literal string.+text :: String -> Doc+text = Doc . toChunks+ where toChunks :: String -> Seq D+ toChunks [] = mempty+ toChunks s = case break (=='\n') s of+ ([], _:ys) -> NewLine <| toChunks ys+ (xs, _:ys) -> Text (realLength xs) xs <|+ (NewLine <| toChunks ys)+ (xs, []) -> singleton $ Text (realLength xs) xs++-- | A character.+char :: Char -> Doc+char c = text [c]++-- | A breaking (reflowable) space.+space :: Doc+space = Doc $ singleton BreakingSpace++-- | A carriage return. Does nothing if we're at the beginning of+-- a line; otherwise inserts a newline.+cr :: Doc+cr = Doc $ singleton CarriageReturn++-- | Inserts a blank line unless one exists already.+-- (@blankline <> blankline@ has the same effect as @blankline@.+blankline :: Doc+blankline = Doc $ singleton (BlankLines 1)++-- | Inserts a blank lines unless they exists already.+-- (@blanklines m <> blanklines n@ has the same effect as @blankline (max m n)@.+blanklines :: Int -> Doc+blanklines n = Doc $ singleton (BlankLines n)++-- | Uses the specified string as a prefix for every line of+-- the inside document (except the first, if not at the beginning+-- of the line).+prefixed :: String -> Doc -> Doc+prefixed pref doc = Doc $ singleton $ Prefixed pref doc++-- | Makes a 'Doc' flush against the left margin.+flush :: Doc -> Doc+flush doc = Doc $ singleton $ Flush doc++-- | Indents a 'Doc' by the specified number of spaces.+nest :: Int -> Doc -> Doc+nest ind = prefixed (replicate ind ' ')++-- | A hanging indent. @hang ind start doc@ prints @start@,+-- then @doc@, leaving an indent of @ind@ spaces on every+-- line but the first.+hang :: Int -> Doc -> Doc -> Doc+hang ind start doc = start <> nest ind doc++-- | @beforeNonBlank d@ conditionally includes @d@ unless it is+-- followed by blank space.+beforeNonBlank :: Doc -> Doc+beforeNonBlank d = Doc $ singleton (BeforeNonBlank d)++-- | Makes a 'Doc' non-reflowable.+nowrap :: Doc -> Doc+nowrap doc = Doc $ mapWithIndex replaceSpace $ unDoc doc+ where replaceSpace _ BreakingSpace = Text 1 " "+ replaceSpace _ x = x++-- | Returns the width of a 'Doc'.+offset :: Doc -> Int+offset d = case map realLength . lines . render Nothing $ d of+ [] -> 0+ os -> maximum os++block :: (String -> String) -> Int -> Doc -> Doc+block filler width = Doc . singleton . Block width .+ map filler . chop width . render (Just width)++-- | @lblock n d@ is a block of width @n@ characters, with+-- text derived from @d@ and aligned to the left.+lblock :: Int -> Doc -> Doc+lblock = block id++-- | Like 'lblock' but aligned to the right.+rblock :: Int -> Doc -> Doc+rblock w = block (\s -> replicate (w - realLength s) ' ' ++ s) w++-- | Like 'lblock' but aligned centered.+cblock :: Int -> Doc -> Doc+cblock w = block (\s -> replicate ((w - realLength s) `div` 2) ' ' ++ s) w++-- | Returns the height of a block or other 'Doc'.+height :: Doc -> Int+height = length . lines . render Nothing++chop :: Int -> String -> [String]+chop _ [] = []+chop n cs = case break (=='\n') cs of+ (xs, ys) -> if len <= n+ then case ys of+ [] -> [xs]+ (_:[]) -> [xs, ""]+ (_:zs) -> xs : chop n zs+ else take n xs : chop n (drop n xs ++ ys)+ where len = realLength xs++-- | Encloses a 'Doc' inside a start and end 'Doc'.+inside :: Doc -> Doc -> Doc -> Doc+inside start end contents =+ start <> contents <> end++-- | Puts a 'Doc' in curly braces.+braces :: Doc -> Doc+braces = inside (char '{') (char '}')++-- | Puts a 'Doc' in square brackets.+brackets :: Doc -> Doc+brackets = inside (char '[') (char ']')++-- | Puts a 'Doc' in parentheses.+parens :: Doc -> Doc+parens = inside (char '(') (char ')')++-- | Wraps a 'Doc' in single quotes.+quotes :: Doc -> Doc+quotes = inside (char '\'') (char '\'')++-- | Wraps a 'Doc' in double quotes.+doubleQuotes :: Doc -> Doc+doubleQuotes = inside (char '"') (char '"')++-- | Returns width of a character in a monospace font: 0 for a combining+-- character, 1 for a regular character, 2 for an East Asian wide character.+charWidth :: Char -> Int+charWidth c =+ case c of+ _ | c < '\x0300' -> 1+ | c >= '\x0300' && c <= '\x036F' -> 0 -- combining+ | c >= '\x0370' && c <= '\x10FC' -> 1+ | c >= '\x1100' && c <= '\x115F' -> 2+ | c >= '\x1160' && c <= '\x11A2' -> 1+ | c >= '\x11A3' && c <= '\x11A7' -> 2+ | c >= '\x11A8' && c <= '\x11F9' -> 1+ | c >= '\x11FA' && c <= '\x11FF' -> 2+ | c >= '\x1200' && c <= '\x2328' -> 1+ | c >= '\x2329' && c <= '\x232A' -> 2+ | c >= '\x232B' && c <= '\x2E31' -> 1+ | c >= '\x2E80' && c <= '\x303E' -> 2+ | c == '\x303F' -> 1+ | c >= '\x3041' && c <= '\x3247' -> 2+ | c >= '\x3248' && c <= '\x324F' -> 1 -- ambiguous+ | c >= '\x3250' && c <= '\x4DBF' -> 2+ | c >= '\x4DC0' && c <= '\x4DFF' -> 1+ | c >= '\x4E00' && c <= '\xA4C6' -> 2+ | c >= '\xA4D0' && c <= '\xA95F' -> 1+ | c >= '\xA960' && c <= '\xA97C' -> 2+ | c >= '\xA980' && c <= '\xABF9' -> 1+ | c >= '\xAC00' && c <= '\xD7FB' -> 2+ | c >= '\xD800' && c <= '\xDFFF' -> 1+ | c >= '\xE000' && c <= '\xF8FF' -> 1 -- ambiguous+ | c >= '\xF900' && c <= '\xFAFF' -> 2+ | c >= '\xFB00' && c <= '\xFDFD' -> 1+ | c >= '\xFE00' && c <= '\xFE0F' -> 1 -- ambiguous+ | c >= '\xFE10' && c <= '\xFE19' -> 2+ | c >= '\xFE20' && c <= '\xFE26' -> 1+ | c >= '\xFE30' && c <= '\xFE6B' -> 2+ | c >= '\xFE70' && c <= '\xFEFF' -> 1+ | c >= '\xFF01' && c <= '\xFF60' -> 2+ | c >= '\xFF61' && c <= '\x16A38' -> 1+ | c >= '\x1B000' && c <= '\x1B001' -> 2+ | c >= '\x1D000' && c <= '\x1F1FF' -> 1+ | c >= '\x1F200' && c <= '\x1F251' -> 2+ | c >= '\x1F300' && c <= '\x1F773' -> 1+ | c >= '\x20000' && c <= '\x3FFFD' -> 2+ | otherwise -> 1++-- | Get real length of string, taking into account combining and double-wide+-- characters.+realLength :: String -> Int+realLength = sum . map charWidth
@@ -0,0 +1,104 @@+{-+Copyright (C) 2013-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Process+ Copyright : Copyright (C) 2013-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++ByteString variant of 'readProcessWithExitCode'.+-}+module Text.Pandoc.Process (pipeProcess)+where+import System.Process+import System.Exit (ExitCode (..))+import Control.Exception+import System.IO (hClose, hFlush)+import Control.Concurrent (putMVar, takeMVar, newEmptyMVar, forkIO)+import Control.Monad (unless)+import qualified Data.ByteString.Lazy as BL++{- |+Version of 'System.Process.readProcessWithExitCode' that uses lazy bytestrings+instead of strings and allows setting environment variables.++@readProcessWithExitCode@ creates an external process, reads its+standard output and standard error strictly, waits until the process+terminates, and then returns the 'ExitCode' of the process,+the standard output, and the standard error.++If an asynchronous exception is thrown to the thread executing+@readProcessWithExitCode@, the forked process will be terminated and+@readProcessWithExitCode@ will wait (block) until the process has been+terminated.+-}++pipeProcess+ :: Maybe [(String, String)] -- ^ environment variables+ -> FilePath -- ^ Filename of the executable (see 'proc' for details)+ -> [String] -- ^ any arguments+ -> BL.ByteString -- ^ standard input+ -> IO (ExitCode,BL.ByteString,BL.ByteString) -- ^ exitcode, stdout, stderr+pipeProcess mbenv cmd args input =+ mask $ \restore -> do+ (Just inh, Just outh, Just errh, pid) <- createProcess (proc cmd args)+ { env = mbenv,+ std_in = CreatePipe,+ std_out = CreatePipe,+ std_err = CreatePipe }+ flip onException+ (do hClose inh; hClose outh; hClose errh;+ terminateProcess pid; waitForProcess pid) $ restore $ do+ -- fork off a thread to start consuming stdout+ out <- BL.hGetContents outh+ waitOut <- forkWait $ evaluate $ BL.length out++ -- fork off a thread to start consuming stderr+ err <- BL.hGetContents errh+ waitErr <- forkWait $ evaluate $ BL.length err++ -- now write and flush any input+ let writeInput = do+ unless (BL.null input) $ do+ BL.hPutStr inh input+ hFlush inh+ hClose inh++ writeInput++ -- wait on the output+ waitOut+ waitErr++ hClose outh+ hClose errh++ -- wait on the process+ ex <- waitForProcess pid++ return (ex, out, err)++forkWait :: IO a -> IO (IO a)+forkWait a = do+ res <- newEmptyMVar+ _ <- mask $ \restore -> forkIO $ try (restore a) >>= putMVar res+ return (takeMVar res >>= either (\ex -> throwIO (ex :: SomeException)) return)
@@ -0,0 +1,965 @@+{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-}+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Readers.HTML+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of HTML to 'Pandoc' document.+-}+module Text.Pandoc.Readers.HTML ( readHtml+ , htmlTag+ , htmlInBalanced+ , isInlineTag+ , isBlockTag+ , isTextTag+ , isCommentTag+ ) where++import Text.HTML.TagSoup+import Text.HTML.TagSoup.Match+import Text.Pandoc.Definition+import qualified Text.Pandoc.Builder as B+import Text.Pandoc.Builder (Blocks, Inlines, trimInlines, HasMeta(..))+import Text.Pandoc.Shared ( extractSpaces, renderTags'+ , escapeURI, safeRead )+import Text.Pandoc.Options (ReaderOptions(readerParseRaw, readerTrace)+ , Extension (Ext_epub_html_exts,+ Ext_native_divs, Ext_native_spans))+import Text.Pandoc.Parsing hiding ((<|>))+import Text.Pandoc.Walk+import Data.Maybe ( fromMaybe, isJust)+import Data.List ( intercalate, isInfixOf )+import Data.Char ( isDigit )+import Control.Monad ( liftM, guard, when, mzero, void, unless )+import Control.Arrow ((***))+import Control.Applicative ( (<$>), (<$), (<*), (*>), (<|>))+import Data.Monoid (mconcat, Monoid, mempty, (<>), First (..))+import Text.Printf (printf)+import Debug.Trace (trace)+import Text.TeXMath (readMathML, writeTeX)+import Data.Default (Default (..), def)+import Control.Monad.Reader (Reader,ask, asks, local, runReader)+++-- | Convert HTML-formatted string to 'Pandoc' document.+readHtml :: ReaderOptions -- ^ Reader options+ -> String -- ^ String to parse (assumes @'\n'@ line endings)+ -> Pandoc+readHtml opts inp =+ case flip runReader def $ runParserT parseDoc (HTMLState def{ stateOptions = opts } []) "source" tags of+ Left err' -> error $ "\nError at " ++ show err'+ Right result -> result+ where tags = stripPrefixes . canonicalizeTags $+ parseTagsOptions parseOptions{ optTagPosition = True } inp+ parseDoc = do+ blocks <- (fixPlains False) . mconcat <$> manyTill block eof+ meta <- stateMeta . parserState <$> getState+ bs' <- replaceNotes (B.toList blocks)+ return $ Pandoc meta bs'++replaceNotes :: [Block] -> TagParser [Block]+replaceNotes = walkM replaceNotes'++replaceNotes' :: Inline -> TagParser Inline+replaceNotes' (RawInline (Format "noteref") ref) = maybe (Str "") (Note . B.toList) . lookup ref <$> getNotes+ where+ getNotes = noteTable <$> getState+replaceNotes' x = return x++data HTMLState =+ HTMLState+ { parserState :: ParserState,+ noteTable :: [(String, Blocks)]+ }++data HTMLLocal = HTMLLocal { quoteContext :: QuoteContext+ , inChapter :: Bool -- ^ Set if in chapter section+ , inPlain :: Bool -- ^ Set if in pPlain+ }++setInChapter :: HTMLParser s a -> HTMLParser s a+setInChapter = local (\s -> s {inChapter = True})++setInPlain :: HTMLParser s a -> HTMLParser s a+setInPlain = local (\s -> s {inPlain = True})++type HTMLParser s = ParserT s HTMLState (Reader HTMLLocal)++type TagParser = HTMLParser [Tag String]++pBody :: TagParser Blocks+pBody = pInTags "body" block++pHead :: TagParser Blocks+pHead = pInTags "head" $ pTitle <|> pMetaTag <|> (mempty <$ pAnyTag)+ where pTitle = pInTags "title" inline >>= setTitle . trimInlines+ setTitle t = mempty <$ (updateState $ B.setMeta "title" t)+ pMetaTag = do+ mt <- pSatisfy (~== TagOpen "meta" [])+ let name = fromAttrib "name" mt+ if null name+ then return mempty+ else do+ let content = fromAttrib "content" mt+ updateState $ B.setMeta name (B.text content)+ return mempty++block :: TagParser Blocks+block = do+ tr <- getOption readerTrace+ pos <- getPosition+ res <- choice+ [ eSection+ , eSwitch B.para block+ , mempty <$ eFootnote+ , mempty <$ eTOC+ , mempty <$ eTitlePage+ , pPara+ , pHeader+ , pBlockQuote+ , pCodeBlock+ , pList+ , pHrule+ , pTable+ , pHead+ , pBody+ , pDiv+ , pPlain+ , pRawHtmlBlock+ ]+ when tr $ trace (printf "line %d: %s" (sourceLine pos)+ (take 60 $ show $ B.toList res)) (return ())+ return res++namespaces :: [(String, TagParser Inlines)]+namespaces = [(mathMLNamespace, pMath True)]++mathMLNamespace :: String+mathMLNamespace = "http://www.w3.org/1998/Math/MathML"++eSwitch :: Monoid a => (Inlines -> a) -> TagParser a -> TagParser a+eSwitch constructor parser = try $ do+ guardEnabled Ext_epub_html_exts+ pSatisfy (~== TagOpen "switch" [])+ cases <- getFirst . mconcat <$>+ manyTill (First <$> (eCase <* skipMany pBlank) )+ (lookAhead $ try $ pSatisfy (~== TagOpen "default" []))+ skipMany pBlank+ fallback <- pInTags "default" (skipMany pBlank *> parser <* skipMany pBlank)+ skipMany pBlank+ pSatisfy (~== TagClose "switch")+ return $ maybe fallback constructor cases++eCase :: TagParser (Maybe Inlines)+eCase = do+ skipMany pBlank+ TagOpen _ attr <- lookAhead $ pSatisfy $ (~== TagOpen "case" [])+ case (flip lookup namespaces) =<< lookup "required-namespace" attr of+ Just p -> Just <$> (pInTags "case" (skipMany pBlank *> p <* skipMany pBlank))+ Nothing -> Nothing <$ manyTill pAnyTag (pSatisfy (~== TagClose "case"))++eFootnote :: TagParser ()+eFootnote = try $ do+ let notes = ["footnote", "rearnote"]+ guardEnabled Ext_epub_html_exts+ (TagOpen tag attr) <- lookAhead $ pAnyTag+ guard (maybe False (flip elem notes) (lookup "type" attr))+ let ident = fromMaybe "" (lookup "id" attr)+ content <- pInTags tag block+ addNote ident content++addNote :: String -> Blocks -> TagParser ()+addNote uid cont = updateState (\s -> s {noteTable = (uid, cont) : (noteTable s)})++eNoteref :: TagParser Inlines+eNoteref = try $ do+ guardEnabled Ext_epub_html_exts+ TagOpen tag attr <- lookAhead $ pAnyTag+ guard (maybe False (== "noteref") (lookup "type" attr))+ let ident = maybe "" (dropWhile (== '#')) (lookup "href" attr)+ guard (not (null ident))+ pInTags tag block+ return $ B.rawInline "noteref" ident++-- Strip TOC if there is one, better to generate again+eTOC :: TagParser ()+eTOC = try $ do+ guardEnabled Ext_epub_html_exts+ (TagOpen tag attr) <- lookAhead $ pAnyTag+ guard (maybe False (== "toc") (lookup "type" attr))+ void (pInTags tag block)++pList :: TagParser Blocks+pList = pBulletList <|> pOrderedList <|> pDefinitionList++pBulletList :: TagParser Blocks+pBulletList = try $ do+ pSatisfy (~== TagOpen "ul" [])+ let nonItem = pSatisfy (\t ->+ not (tagOpen (`elem` ["li","ol","ul","dl"]) (const True) t) &&+ not (t ~== TagClose "ul"))+ -- note: if they have an <ol> or <ul> not in scope of a <li>,+ -- treat it as a list item, though it's not valid xhtml...+ skipMany nonItem+ items <- manyTill (pListItem nonItem) (pCloses "ul")+ return $ B.bulletList $ map (fixPlains True) items++pListItem :: TagParser a -> TagParser Blocks+pListItem nonItem = do+ TagOpen _ attr <- lookAhead $ pSatisfy (~== TagOpen "li" [])+ let liDiv = maybe mempty (\x -> B.divWith (x, [], []) mempty) (lookup "id" attr)+ (liDiv <>) <$> pInTags "li" block <* skipMany nonItem++pOrderedList :: TagParser Blocks+pOrderedList = try $ do+ TagOpen _ attribs <- pSatisfy (~== TagOpen "ol" [])+ let (start, style) = (sta', sty')+ where sta = fromMaybe "1" $+ lookup "start" attribs+ sta' = if all isDigit sta+ then read sta+ else 1+ sty = fromMaybe (fromMaybe "" $+ lookup "style" attribs) $+ lookup "class" attribs+ sty' = case sty of+ "lower-roman" -> LowerRoman+ "upper-roman" -> UpperRoman+ "lower-alpha" -> LowerAlpha+ "upper-alpha" -> UpperAlpha+ "decimal" -> Decimal+ _ -> DefaultStyle+ let nonItem = pSatisfy (\t ->+ not (tagOpen (`elem` ["li","ol","ul","dl"]) (const True) t) &&+ not (t ~== TagClose "ol"))+ -- note: if they have an <ol> or <ul> not in scope of a <li>,+ -- treat it as a list item, though it's not valid xhtml...+ skipMany nonItem+ items <- manyTill (pListItem nonItem) (pCloses "ol")+ return $ B.orderedListWith (start, style, DefaultDelim) $ map (fixPlains True) items++pDefinitionList :: TagParser Blocks+pDefinitionList = try $ do+ pSatisfy (~== TagOpen "dl" [])+ items <- manyTill pDefListItem (pCloses "dl")+ return $ B.definitionList items++pDefListItem :: TagParser (Inlines, [Blocks])+pDefListItem = try $ do+ let nonItem = pSatisfy (\t -> not (t ~== TagOpen "dt" []) &&+ not (t ~== TagOpen "dd" []) && not (t ~== TagClose "dl"))+ terms <- many1 (try $ skipMany nonItem >> pInTags "dt" inline)+ defs <- many1 (try $ skipMany nonItem >> pInTags "dd" block)+ skipMany nonItem+ let term = foldl1 (\x y -> x <> B.linebreak <> y) terms+ return (term, map (fixPlains True) defs)++fixPlains :: Bool -> Blocks -> Blocks+fixPlains inList bs = if any isParaish bs'+ then B.fromList $ map plainToPara bs'+ else bs+ where isParaish (Para _) = True+ isParaish (CodeBlock _ _) = True+ isParaish (Header _ _ _) = True+ isParaish (BlockQuote _) = True+ isParaish (BulletList _) = not inList+ isParaish (OrderedList _ _) = not inList+ isParaish (DefinitionList _) = not inList+ isParaish _ = False+ plainToPara (Plain xs) = Para xs+ plainToPara x = x+ bs' = B.toList bs++pRawTag :: TagParser String+pRawTag = do+ tag <- pAnyTag+ let ignorable x = x `elem` ["html","head","body","!DOCTYPE","?xml"]+ if tagOpen ignorable (const True) tag || tagClose ignorable tag+ then return []+ else return $ renderTags' [tag]++pDiv :: TagParser Blocks+pDiv = try $ do+ guardEnabled Ext_native_divs+ TagOpen _ attr <- lookAhead $ pSatisfy $ tagOpen (=="div") (const True)+ contents <- pInTags "div" block+ return $ B.divWith (mkAttr attr) contents++pRawHtmlBlock :: TagParser Blocks+pRawHtmlBlock = do+ raw <- pHtmlBlock "script" <|> pHtmlBlock "style" <|> pRawTag+ parseRaw <- getOption readerParseRaw+ if parseRaw && not (null raw)+ then return $ B.rawBlock "html" raw+ else return mempty++pHtmlBlock :: String -> TagParser String+pHtmlBlock t = try $ do+ open <- pSatisfy (~== TagOpen t [])+ contents <- manyTill pAnyTag (pSatisfy (~== TagClose t))+ return $ renderTags' $ [open] ++ contents ++ [TagClose t]++-- Sets chapter context+eSection :: TagParser Blocks+eSection = try $ do+ let matchChapter as = maybe False (isInfixOf "chapter") (lookup "type" as)+ let sectTag = tagOpen (`elem` sectioningContent) matchChapter+ TagOpen tag _ <- lookAhead $ pSatisfy sectTag+ setInChapter (pInTags tag block)++headerLevel :: String -> TagParser Int+headerLevel tagtype = do+ let level = read (drop 1 tagtype)+ (try $ do+ guardEnabled Ext_epub_html_exts+ asks inChapter >>= guard+ return (level - 1))+ <|>+ return level++eTitlePage :: TagParser ()+eTitlePage = try $ do+ let isTitlePage as = maybe False (isInfixOf "titlepage") (lookup "type" as)+ let groupTag = tagOpen (\x -> x `elem` groupingContent || x == "section")+ isTitlePage+ TagOpen tag _ <- lookAhead $ pSatisfy groupTag+ () <$ pInTags tag block++pHeader :: TagParser Blocks+pHeader = try $ do+ TagOpen tagtype attr <- pSatisfy $+ tagOpen (`elem` ["h1","h2","h3","h4","h5","h6"])+ (const True)+ let bodyTitle = TagOpen tagtype attr ~== TagOpen "h1" [("class","title")]+ level <- headerLevel tagtype+ contents <- trimInlines . mconcat <$> manyTill inline (pCloses tagtype <|> eof)+ let ident = fromMaybe "" $ lookup "id" attr+ let classes = maybe [] words $ lookup "class" attr+ let keyvals = [(k,v) | (k,v) <- attr, k /= "class", k /= "id"]+ return $ if bodyTitle+ then mempty -- skip a representation of the title in the body+ else B.headerWith (ident, classes, keyvals) level contents++pHrule :: TagParser Blocks+pHrule = do+ pSelfClosing (=="hr") (const True)+ return B.horizontalRule++pTable :: TagParser Blocks+pTable = try $ do+ TagOpen _ _ <- pSatisfy (~== TagOpen "table" [])+ skipMany pBlank+ caption <- option mempty $ pInTags "caption" inline <* skipMany pBlank+ -- TODO actually read these and take width information from them+ widths' <- pColgroup <|> many pCol+ head' <- option [] $ pOptInTag "thead" $ pInTags "tr" (pCell "th")+ skipMany pBlank+ rows <- pOptInTag "tbody"+ $ many1 $ try $ skipMany pBlank >> pInTags "tr" (pCell "td")+ skipMany pBlank+ TagClose _ <- pSatisfy (~== TagClose "table")+ let isSinglePlain x = case B.toList x of+ [Plain _] -> True+ _ -> False+ let isSimple = all isSinglePlain $ concat (head':rows)+ let cols = length $ if null head' then head rows else head'+ -- fail if there are colspans or rowspans+ guard $ all (\r -> length r == cols) rows+ let aligns = replicate cols AlignDefault+ let widths = if null widths'+ then if isSimple+ then replicate cols 0+ else replicate cols (1.0 / fromIntegral cols)+ else widths'+ return $ B.table caption (zip aligns widths) head' rows++pCol :: TagParser Double+pCol = try $ do+ TagOpen _ attribs <- pSatisfy (~== TagOpen "col" [])+ skipMany pBlank+ optional $ pSatisfy (~== TagClose "col")+ skipMany pBlank+ return $ case lookup "width" attribs of+ Just x | not (null x) && last x == '%' ->+ fromMaybe 0.0 $ safeRead ('0':'.':init x)+ _ -> 0.0++pColgroup :: TagParser [Double]+pColgroup = try $ do+ pSatisfy (~== TagOpen "colgroup" [])+ skipMany pBlank+ manyTill pCol (pCloses "colgroup" <|> eof) <* skipMany pBlank++pCell :: String -> TagParser [Blocks]+pCell celltype = try $ do+ skipMany pBlank+ res <- pInTags celltype block+ skipMany pBlank+ return [res]++pBlockQuote :: TagParser Blocks+pBlockQuote = do+ contents <- pInTags "blockquote" block+ return $ B.blockQuote $ fixPlains False contents++pPlain :: TagParser Blocks+pPlain = do+ contents <- setInPlain $ trimInlines . mconcat <$> many1 inline+ if B.isNull contents+ then return mempty+ else return $ B.plain contents++pPara :: TagParser Blocks+pPara = do+ contents <- trimInlines <$> pInTags "p" inline+ return $ B.para contents++pCodeBlock :: TagParser Blocks+pCodeBlock = try $ do+ TagOpen _ attr <- pSatisfy (~== TagOpen "pre" [])+ contents <- manyTill pAnyTag (pCloses "pre" <|> eof)+ let rawText = concatMap tagToString contents+ -- drop leading newline if any+ let result' = case rawText of+ '\n':xs -> xs+ _ -> rawText+ -- drop trailing newline if any+ let result = case reverse result' of+ '\n':_ -> init result'+ _ -> result'+ return $ B.codeBlockWith (mkAttr attr) result++tagToString :: Tag String -> String+tagToString (TagText s) = s+tagToString (TagOpen "br" _) = "\n"+tagToString _ = ""++inline :: TagParser Inlines+inline = choice+ [ eNoteref+ , eSwitch id inline+ , pTagText+ , pQ+ , pEmph+ , pStrong+ , pSuperscript+ , pSubscript+ , pStrikeout+ , pLineBreak+ , pLink+ , pImage+ , pCode+ , pSpan+ , pMath False+ , pRawHtmlInline+ ]++pLocation :: TagParser ()+pLocation = do+ (TagPosition r c) <- pSat isTagPosition+ setPosition $ newPos "input" r c++pSat :: (Tag String -> Bool) -> TagParser (Tag String)+pSat f = do+ pos <- getPosition+ token show (const pos) (\x -> if f x then Just x else Nothing)++pSatisfy :: (Tag String -> Bool) -> TagParser (Tag String)+pSatisfy f = try $ optional pLocation >> pSat f++pAnyTag :: TagParser (Tag String)+pAnyTag = pSatisfy (const True)++pSelfClosing :: (String -> Bool) -> ([Attribute String] -> Bool)+ -> TagParser (Tag String)+pSelfClosing f g = do+ open <- pSatisfy (tagOpen f g)+ optional $ pSatisfy (tagClose f)+ return open++pQ :: TagParser Inlines+pQ = do+ context <- asks quoteContext+ let quoteType = case context of+ InDoubleQuote -> SingleQuote+ _ -> DoubleQuote+ let innerQuoteContext = if quoteType == SingleQuote+ then InSingleQuote+ else InDoubleQuote+ let constructor = case quoteType of+ SingleQuote -> B.singleQuoted+ DoubleQuote -> B.doubleQuoted+ withQuoteContext innerQuoteContext $+ pInlinesInTags "q" constructor++pEmph :: TagParser Inlines+pEmph = pInlinesInTags "em" B.emph <|> pInlinesInTags "i" B.emph++pStrong :: TagParser Inlines+pStrong = pInlinesInTags "strong" B.strong <|> pInlinesInTags "b" B.strong++pSuperscript :: TagParser Inlines+pSuperscript = pInlinesInTags "sup" B.superscript++pSubscript :: TagParser Inlines+pSubscript = pInlinesInTags "sub" B.subscript++pStrikeout :: TagParser Inlines+pStrikeout = do+ pInlinesInTags "s" B.strikeout <|>+ pInlinesInTags "strike" B.strikeout <|>+ pInlinesInTags "del" B.strikeout <|>+ try (do pSatisfy (~== TagOpen "span" [("class","strikeout")])+ contents <- mconcat <$> manyTill inline (pCloses "span")+ return $ B.strikeout contents)++pLineBreak :: TagParser Inlines+pLineBreak = do+ pSelfClosing (=="br") (const True)+ return B.linebreak++pLink :: TagParser Inlines+pLink = pRelLink <|> pAnchor++pAnchor :: TagParser Inlines+pAnchor = try $ do+ tag <- pSatisfy (tagOpenLit "a" (isJust . lookup "id"))+ return $ B.spanWith (fromAttrib "id" tag , [], []) mempty++pRelLink :: TagParser Inlines+pRelLink = try $ do+ tag <- pSatisfy (tagOpenLit "a" (isJust . lookup "href"))+ let url = fromAttrib "href" tag+ let title = fromAttrib "title" tag+ let uid = fromAttrib "id" tag+ let spanC = case uid of+ [] -> id+ s -> B.spanWith (s, [], [])+ lab <- trimInlines . mconcat <$> manyTill inline (pCloses "a")+ return $ spanC $ B.link (escapeURI url) title lab++-- | TODO: parse additional attributes into Attr+pImage :: TagParser Inlines+pImage = do+ tag <- pSelfClosing (=="img") (isJust . lookup "src")+ let url = fromAttrib "src" tag+ let title = fromAttrib "title" tag+ let alt = fromAttrib "alt" tag+ return $ B.image (escapeURI url) title (B.text alt)++pCode :: TagParser Inlines+pCode = try $ do+ (TagOpen open attr) <- pSatisfy $ tagOpen (`elem` ["code","tt"]) (const True)+ result <- manyTill pAnyTag (pCloses open)+ return $ B.codeWith (mkAttr attr) $ intercalate " " $ lines $ innerText result++pSpan :: TagParser Inlines+pSpan = try $ do+ guardEnabled Ext_native_spans+ TagOpen _ attr <- lookAhead $ pSatisfy $ tagOpen (=="span") (const True)+ contents <- pInTags "span" inline+ let attr' = mkAttr attr+ return $ case attr' of+ ("",[],[("style",s)])+ | filter (`notElem` " \t;") s == "font-variant:small-caps" ->+ B.smallcaps contents+ _ -> B.spanWith (mkAttr attr) contents++pRawHtmlInline :: TagParser Inlines+pRawHtmlInline = do+ inplain <- asks inPlain+ result <- pSatisfy (tagComment (const True))+ <|> if inplain+ then pSatisfy (not . isBlockTag)+ else pSatisfy isInlineTag+ parseRaw <- getOption readerParseRaw+ if parseRaw+ then return $ B.rawInline "html" $ renderTags' [result]+ else return mempty++mathMLToTeXMath :: String -> Either String String+mathMLToTeXMath s = writeTeX <$> readMathML s++pMath :: Bool -> TagParser Inlines+pMath inCase = try $ do+ open@(TagOpen _ attr) <- pSatisfy $ tagOpen (=="math") (const True)+ unless (inCase) (guard (maybe False (== mathMLNamespace) (lookup "xmlns" attr)))+ contents <- manyTill pAnyTag (pSatisfy (~== TagClose "math"))+ let math = mathMLToTeXMath $+ (renderTags $ [open] ++ contents ++ [TagClose "math"])+ let constructor =+ maybe B.math (\x -> if (x == "inline") then B.math else B.displayMath)+ (lookup "display" attr)+ return $ either (const mempty)+ (\x -> if null x then mempty else constructor x) math++pInlinesInTags :: String -> (Inlines -> Inlines)+ -> TagParser Inlines+pInlinesInTags tagtype f = extractSpaces f <$> pInTags tagtype inline++pInTags :: (Monoid a) => String -> TagParser a+ -> TagParser a+pInTags tagtype parser = try $ do+ pSatisfy (~== TagOpen tagtype [])+ mconcat <$> manyTill parser (pCloses tagtype <|> eof)++pOptInTag :: String -> TagParser a+ -> TagParser a+pOptInTag tagtype parser = try $ do+ open <- option False (pSatisfy (~== TagOpen tagtype []) >> return True)+ skipMany pBlank+ x <- parser+ skipMany pBlank+ when open $ pCloses tagtype+ return x++pCloses :: String -> TagParser ()+pCloses tagtype = try $ do+ t <- lookAhead $ pSatisfy $ \tag -> isTagClose tag || isTagOpen tag+ case t of+ (TagClose t') | t' == tagtype -> pAnyTag >> return ()+ (TagOpen t' _) | t' `closes` tagtype -> return ()+ (TagClose "ul") | tagtype == "li" -> return ()+ (TagClose "ol") | tagtype == "li" -> return ()+ (TagClose "dl") | tagtype == "li" -> return ()+ (TagClose "table") | tagtype == "td" -> return ()+ (TagClose "table") | tagtype == "tr" -> return ()+ _ -> mzero++pTagText :: TagParser Inlines+pTagText = try $ do+ (TagText str) <- pSatisfy isTagText+ st <- getState+ qu <- ask+ case flip runReader qu $ runParserT (many pTagContents) st "text" str of+ Left _ -> fail $ "Could not parse `" ++ str ++ "'"+ Right result -> return $ mconcat result++pBlank :: TagParser ()+pBlank = try $ do+ (TagText str) <- pSatisfy isTagText+ guard $ all isSpace str++type InlinesParser = HTMLParser String++pTagContents :: InlinesParser Inlines+pTagContents =+ B.displayMath <$> mathDisplay+ <|> B.math <$> mathInline+ <|> pStr+ <|> pSpace+ <|> smartPunctuation pTagContents+ <|> pSymbol+ <|> pBad++pStr :: InlinesParser Inlines+pStr = do+ result <- many1 $ satisfy $ \c ->+ not (isSpace c) && not (isSpecial c) && not (isBad c)+ updateLastStrPos+ return $ B.str result++isSpecial :: Char -> Bool+isSpecial '"' = True+isSpecial '\'' = True+isSpecial '.' = True+isSpecial '-' = True+isSpecial '$' = True+isSpecial '\8216' = True+isSpecial '\8217' = True+isSpecial '\8220' = True+isSpecial '\8221' = True+isSpecial _ = False++pSymbol :: InlinesParser Inlines+pSymbol = satisfy isSpecial >>= return . B.str . (:[])++isBad :: Char -> Bool+isBad c = c >= '\128' && c <= '\159' -- not allowed in HTML++pBad :: InlinesParser Inlines+pBad = do+ c <- satisfy isBad+ let c' = case c of+ '\128' -> '\8364'+ '\130' -> '\8218'+ '\131' -> '\402'+ '\132' -> '\8222'+ '\133' -> '\8230'+ '\134' -> '\8224'+ '\135' -> '\8225'+ '\136' -> '\710'+ '\137' -> '\8240'+ '\138' -> '\352'+ '\139' -> '\8249'+ '\140' -> '\338'+ '\142' -> '\381'+ '\145' -> '\8216'+ '\146' -> '\8217'+ '\147' -> '\8220'+ '\148' -> '\8221'+ '\149' -> '\8226'+ '\150' -> '\8211'+ '\151' -> '\8212'+ '\152' -> '\732'+ '\153' -> '\8482'+ '\154' -> '\353'+ '\155' -> '\8250'+ '\156' -> '\339'+ '\158' -> '\382'+ '\159' -> '\376'+ _ -> '?'+ return $ B.str [c']++pSpace :: InlinesParser Inlines+pSpace = many1 (satisfy isSpace) >> return B.space++--+-- Constants+--++eitherBlockOrInline :: [String]+eitherBlockOrInline = ["audio", "applet", "button", "iframe",+ "del", "ins",+ "progress", "map", "area", "noscript", "script",+ "object", "svg", "video", "source"]++{-+inlineHtmlTags :: [[Char]]+inlineHtmlTags = ["a", "abbr", "acronym", "b", "basefont", "bdo", "big",+ "br", "cite", "code", "dfn", "em", "font", "i", "img",+ "input", "kbd", "label", "q", "s", "samp", "select",+ "small", "span", "strike", "strong", "sub", "sup",+ "textarea", "tt", "u", "var"]+-}++blockHtmlTags :: [String]+blockHtmlTags = ["?xml", "!DOCTYPE", "address", "article", "aside",+ "blockquote", "body", "button", "canvas",+ "caption", "center", "col", "colgroup", "dd", "dir", "div",+ "dl", "dt", "embed", "fieldset", "figcaption", "figure",+ "footer", "form", "h1", "h2", "h3", "h4",+ "h5", "h6", "head", "header", "hgroup", "hr", "html",+ "isindex", "menu", "noframes", "ol", "output", "p", "pre",+ "section", "table", "tbody", "textarea",+ "thead", "tfoot", "ul", "dd",+ "dt", "frameset", "li", "tbody", "td", "tfoot",+ "th", "thead", "tr", "script", "style"]++-- We want to allow raw docbook in markdown documents, so we+-- include docbook block tags here too.+blockDocBookTags :: [String]+blockDocBookTags = ["calloutlist", "bibliolist", "glosslist", "itemizedlist",+ "orderedlist", "segmentedlist", "simplelist",+ "variablelist", "caution", "important", "note", "tip",+ "warning", "address", "literallayout", "programlisting",+ "programlistingco", "screen", "screenco", "screenshot",+ "synopsis", "example", "informalexample", "figure",+ "informalfigure", "table", "informaltable", "para",+ "simpara", "formalpara", "equation", "informalequation",+ "figure", "screenshot", "mediaobject", "qandaset",+ "procedure", "task", "cmdsynopsis", "funcsynopsis",+ "classsynopsis", "blockquote", "epigraph", "msgset",+ "sidebar", "title"]++epubTags :: [String]+epubTags = ["case", "switch", "default"]++blockTags :: [String]+blockTags = blockHtmlTags ++ blockDocBookTags ++ epubTags++isInlineTag :: Tag String -> Bool+isInlineTag t = tagOpen isInlineTagName (const True) t ||+ tagClose isInlineTagName t ||+ tagComment (const True) t+ where isInlineTagName x = x `notElem` blockTags++isBlockTag :: Tag String -> Bool+isBlockTag t = tagOpen isBlockTagName (const True) t ||+ tagClose isBlockTagName t ||+ tagComment (const True) t+ where isBlockTagName ('?':_) = True+ isBlockTagName ('!':_) = True+ isBlockTagName x = x `elem` blockTags+ || x `elem` eitherBlockOrInline++isTextTag :: Tag String -> Bool+isTextTag = tagText (const True)++isCommentTag :: Tag String -> Bool+isCommentTag = tagComment (const True)++-- taken from HXT and extended+-- See http://www.w3.org/TR/html5/syntax.html sec 8.1.2.4 optional tags+closes :: String -> String -> Bool+_ `closes` "body" = False+_ `closes` "html" = False+"a" `closes` "a" = True+"li" `closes` "li" = True+"th" `closes` t | t `elem` ["th","td"] = True+"tr" `closes` t | t `elem` ["th","td","tr"] = True+"dd" `closes` t | t `elem` ["dt", "dd"] = True+"dt" `closes` t | t `elem` ["dt","dd"] = True+"rt" `closes` t | t `elem` ["rb", "rt", "rtc"] = True+"optgroup" `closes` "optgroup" = True+"optgroup" `closes` "option" = True+"option" `closes` "option" = True+-- http://www.w3.org/TR/html-markup/p.html+x `closes` "p" | x `elem` ["address", "article", "aside", "blockquote",+ "dir", "div", "dl", "fieldset", "footer", "form", "h1", "h2", "h3", "h4",+ "h5", "h6", "header", "hr", "menu", "nav", "ol", "p", "pre", "section",+ "table", "ul"] = True+"meta" `closes` "meta" = True+"form" `closes` "form" = True+"label" `closes` "label" = True+"map" `closes` "map" = True+"object" `closes` "object" = True+_ `closes` t | t `elem` ["option","style","script","textarea","title"] = True+t `closes` "select" | t /= "option" = True+"thead" `closes` t | t `elem` ["colgroup"] = True+"tfoot" `closes` t | t `elem` ["thead","colgroup"] = True+"tbody" `closes` t | t `elem` ["tbody","tfoot","thead","colgroup"] = True+t `closes` t2 |+ t `elem` ["h1","h2","h3","h4","h5","h6","dl","ol","ul","table","div","p"] &&+ t2 `elem` ["h1","h2","h3","h4","h5","h6","p" ] = True -- not "div"+t1 `closes` t2 |+ t1 `elem` blockTags &&+ t2 `notElem` (blockTags ++ eitherBlockOrInline) = True+_ `closes` _ = False++--- parsers for use in markdown, textile readers++-- | Matches a stretch of HTML in balanced tags.+htmlInBalanced :: (Monad m)+ => (Tag String -> Bool)+ -> ParserT String st m String+htmlInBalanced f = try $ do+ (TagOpen t _, tag) <- htmlTag f+ guard $ '/' `notElem` tag -- not a self-closing tag+ let stopper = htmlTag (~== TagClose t)+ let anytag = snd <$> htmlTag (const True)+ contents <- many $ notFollowedBy' stopper >>+ (htmlInBalanced f <|> anytag <|> count 1 anyChar)+ endtag <- liftM snd stopper+ return $ tag ++ concat contents ++ endtag++-- | Matches a tag meeting a certain condition.+htmlTag :: Monad m+ => (Tag String -> Bool)+ -> ParserT [Char] st m (Tag String, String)+htmlTag f = try $ do+ lookAhead $ char '<' >> (oneOf "/!?" <|> letter)+ (next : _) <- getInput >>= return . canonicalizeTags . parseTags+ guard $ f next+ -- advance the parser+ case next of+ TagComment s -> do+ count (length s + 4) anyChar+ skipMany (satisfy (/='>'))+ char '>'+ return (next, "<!--" ++ s ++ "-->")+ _ -> do+ rendered <- manyTill anyChar (char '>')+ return (next, rendered ++ ">")++mkAttr :: [(String, String)] -> Attr+mkAttr attr = (attribsId, attribsClasses, attribsKV)+ where attribsId = fromMaybe "" $ lookup "id" attr+ attribsClasses = (words $ fromMaybe "" $ lookup "class" attr) ++ epubTypes+ attribsKV = filter (\(k,_) -> k /= "class" && k /= "id") attr+ epubTypes = words $ fromMaybe "" $ lookup "epub:type" attr++-- Strip namespace prefixes+stripPrefixes :: [Tag String] -> [Tag String]+stripPrefixes = map stripPrefix++stripPrefix :: Tag String -> Tag String+stripPrefix (TagOpen s as) =+ TagOpen (stripPrefix' s) (map (stripPrefix' *** id) as)+stripPrefix (TagClose s) = TagClose (stripPrefix' s)+stripPrefix x = x++stripPrefix' :: String -> String+stripPrefix' s =+ case span (/= ':') s of+ (_, "") -> s+ (_, (_:ts)) -> ts++isSpace :: Char -> Bool+isSpace ' ' = True+isSpace '\t' = True+isSpace '\n' = True+isSpace '\r' = True+isSpace _ = False++-- Instances++-- This signature should be more general+-- MonadReader HTMLLocal m => HasQuoteContext st m+instance HasQuoteContext st (Reader HTMLLocal) where+ getQuoteContext = asks quoteContext+ withQuoteContext q = local (\s -> s{quoteContext = q})++instance HasReaderOptions HTMLState where+ extractReaderOptions = extractReaderOptions . parserState++instance Default HTMLState where+ def = HTMLState def []++instance HasMeta HTMLState where+ setMeta s b st = st {parserState = setMeta s b $ parserState st}+ deleteMeta s st = st {parserState = deleteMeta s $ parserState st}++instance Default HTMLLocal where+ def = HTMLLocal NoQuote False False++instance HasLastStrPosition HTMLState where+ setLastStrPos s st = st {parserState = setLastStrPos s (parserState st)}+ getLastStrPos = getLastStrPos . parserState+++-- EPUB Specific+--+--+sectioningContent :: [String]+sectioningContent = ["article", "aside", "nav", "section"]+++groupingContent :: [String]+groupingContent = ["p", "hr", "pre", "blockquote", "ol"+ , "ul", "li", "dl", "dt", "dt", "dd"+ , "figure", "figcaption", "div", "main"]+++{-++types :: [(String, ([String], Int))]+types = -- Document divisions+ map (\s -> (s, (["section", "body"], 0)))+ ["volume", "part", "chapter", "division"]+ ++ -- Document section and components+ [+ ("abstract", ([], 0))]+-}
@@ -0,0 +1,1294 @@+{-# LANGUAGE ScopedTypeVariables, OverloadedStrings #-}+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Readers.LaTeX+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of LaTeX to 'Pandoc' document.+-}+module Text.Pandoc.Readers.LaTeX ( readLaTeX,+ rawLaTeXInline,+ rawLaTeXBlock,+ inlineCommand,+ handleIncludes+ ) where++import Text.Pandoc.Definition+import Text.Pandoc.Walk+import Text.Pandoc.Shared+import Text.Pandoc.Options+import Text.Pandoc.Parsing hiding ((<|>), many, optional, space,+ mathDisplay, mathInline)+import qualified Text.Pandoc.UTF8 as UTF8+import Data.Char ( chr, ord )+import Control.Monad.Trans (lift)+import Control.Monad+import Text.Pandoc.Builder+import Data.Char (isLetter, isAlphaNum)+import Control.Applicative+import Data.Monoid+import Data.Maybe (fromMaybe)+import System.Environment (getEnv)+import System.FilePath (replaceExtension, (</>))+import Data.List (intercalate, intersperse)+import qualified Data.Map as M+import qualified Control.Exception as E+import System.FilePath (takeExtension, addExtension)+import Text.Pandoc.Highlighting (fromListingsLanguage)++-- | Parse LaTeX from string and return 'Pandoc' document.+readLaTeX :: ReaderOptions -- ^ Reader options+ -> String -- ^ String to parse (assumes @'\n'@ line endings)+ -> Pandoc+readLaTeX opts = readWith parseLaTeX def{ stateOptions = opts }++parseLaTeX :: LP Pandoc+parseLaTeX = do+ bs <- blocks+ eof+ st <- getState+ let meta = stateMeta st+ let (Pandoc _ bs') = doc bs+ return $ Pandoc meta bs'++type LP = Parser [Char] ParserState++anyControlSeq :: LP String+anyControlSeq = do+ char '\\'+ next <- option '\n' anyChar+ name <- case next of+ '\n' -> return ""+ c | isLetter c -> (c:) <$> (many letter <* optional sp)+ | otherwise -> return [c]+ return name++controlSeq :: String -> LP String+controlSeq name = try $ do+ char '\\'+ case name of+ "" -> mzero+ [c] | not (isLetter c) -> string [c]+ cs -> string cs <* notFollowedBy letter <* optional sp+ return name++dimenarg :: LP String+dimenarg = try $ do+ ch <- option "" $ string "="+ num <- many1 digit+ dim <- oneOfStrings ["pt","pc","in","bp","cm","mm","dd","cc","sp"]+ return $ ch ++ num ++ dim++sp :: LP ()+sp = skipMany1 $ satisfy (\c -> c == ' ' || c == '\t')+ <|> (try $ newline <* lookAhead anyChar <* notFollowedBy blankline)++isLowerHex :: Char -> Bool+isLowerHex x = x >= '0' && x <= '9' || x >= 'a' && x <= 'f'++tildeEscape :: LP Char+tildeEscape = try $ do+ string "^^"+ c <- satisfy (\x -> x >= '\0' && x <= '\128')+ d <- if isLowerHex c+ then option "" $ count 1 (satisfy isLowerHex)+ else return ""+ if null d+ then case ord c of+ x | x >= 64 && x <= 127 -> return $ chr (x - 64)+ | otherwise -> return $ chr (x + 64)+ else return $ chr $ read ('0':'x':c:d)++comment :: LP ()+comment = do+ char '%'+ skipMany (satisfy (/='\n'))+ optional newline+ return ()++bgroup :: LP ()+bgroup = () <$ char '{'+ <|> () <$ controlSeq "bgroup"+ <|> () <$ controlSeq "begingroup"++egroup :: LP ()+egroup = () <$ char '}'+ <|> () <$ controlSeq "egroup"+ <|> () <$ controlSeq "endgroup"++grouped :: Monoid a => LP a -> LP a+grouped parser = try $ bgroup *> (mconcat <$> manyTill parser egroup)++braced :: LP String+braced = bgroup *> (concat <$> manyTill+ ( many1 (satisfy (\c -> c /= '\\' && c /= '}' && c /= '{'))+ <|> try (string "\\}")+ <|> try (string "\\{")+ <|> try (string "\\\\")+ <|> ((\x -> "{" ++ x ++ "}") <$> braced)+ <|> count 1 anyChar+ ) egroup)++bracketed :: Monoid a => LP a -> LP a+bracketed parser = try $ char '[' *> (mconcat <$> manyTill parser (char ']'))++mathDisplay :: LP String -> LP Inlines+mathDisplay p = displayMath <$> (try p >>= applyMacros' . trim)++mathInline :: LP String -> LP Inlines+mathInline p = math <$> (try p >>= applyMacros')++mathChars :: LP String+mathChars = concat <$>+ many ( many1 (satisfy (\c -> c /= '$' && c /='\\'))+ <|> (\c -> ['\\',c]) <$> (try $ char '\\' *> anyChar)+ )++quoted' :: (Inlines -> Inlines) -> LP String -> LP () -> LP Inlines+quoted' f starter ender = do+ startchs <- starter+ try ((f . mconcat) <$> manyTill inline ender) <|> lit startchs++double_quote :: LP Inlines+double_quote =+ ( quoted' doubleQuoted (try $ string "``") (void $ try $ string "''")+ <|> quoted' doubleQuoted (string "“") (void $ char '”')+ -- the following is used by babel for localized quotes:+ <|> quoted' doubleQuoted (try $ string "\"`") (void $ try $ string "\"'")+ <|> quoted' doubleQuoted (string "\"") (void $ char '"')+ )++single_quote :: LP Inlines+single_quote =+ ( quoted' singleQuoted (string "`") (try $ char '\'' >> notFollowedBy letter)+ <|> quoted' singleQuoted (string "‘") (try $ char '’' >> notFollowedBy letter)+ )++inline :: LP Inlines+inline = (mempty <$ comment)+ <|> (space <$ sp)+ <|> inlineText+ <|> inlineCommand+ <|> inlineGroup+ <|> (char '-' *> option (str "-")+ ((char '-') *> option (str "–") (str "—" <$ char '-')))+ <|> double_quote+ <|> single_quote+ <|> (str "”" <$ try (string "''"))+ <|> (str "”" <$ char '”')+ <|> (str "’" <$ char '\'')+ <|> (str "’" <$ char '’')+ <|> (str "\160" <$ char '~')+ <|> (mathDisplay $ string "$$" *> mathChars <* string "$$")+ <|> (mathInline $ char '$' *> mathChars <* char '$')+ <|> (superscript <$> (char '^' *> tok))+ <|> (subscript <$> (char '_' *> tok))+ <|> (guardEnabled Ext_literate_haskell *> char '|' *> doLHSverb)+ <|> (str . (:[]) <$> tildeEscape)+ <|> (str . (:[]) <$> oneOf "[]")+ <|> (str . (:[]) <$> oneOf "#&") -- TODO print warning?+ -- <|> (str <$> count 1 (satisfy (\c -> c /= '\\' && c /='\n' && c /='}' && c /='{'))) -- eat random leftover characters++inlines :: LP Inlines+inlines = mconcat <$> many (notFollowedBy (char '}') *> inline)++inlineGroup :: LP Inlines+inlineGroup = do+ ils <- grouped inline+ if isNull ils+ then return mempty+ else return $ spanWith nullAttr ils+ -- we need the span so we can detitlecase bibtex entries;+ -- we need to know when something is {C}apitalized++block :: LP Blocks+block = (mempty <$ comment)+ <|> (mempty <$ ((spaceChar <|> newline) *> spaces))+ <|> environment+ <|> macro+ <|> blockCommand+ <|> paragraph+ <|> grouped block+ <|> (mempty <$ char '&') -- loose & in table environment+++blocks :: LP Blocks+blocks = mconcat <$> many block++blockCommand :: LP Blocks+blockCommand = try $ do+ name <- anyControlSeq+ guard $ name /= "begin" && name /= "end"+ star <- option "" (string "*" <* optional sp)+ let name' = name ++ star+ case M.lookup name' blockCommands of+ Just p -> p+ Nothing -> case M.lookup name blockCommands of+ Just p -> p+ Nothing -> mzero++inBrackets :: Inlines -> Inlines+inBrackets x = (str "[") <> x <> (str "]")++-- eat an optional argument and one or more arguments in braces+ignoreInlines :: String -> (String, LP Inlines)+ignoreInlines name = (name, doraw <|> (mempty <$ optargs))+ where optargs = skipopts *> skipMany (try $ optional sp *> braced)+ contseq = '\\':name+ doraw = (rawInline "latex" . (contseq ++) . snd) <$>+ (getOption readerParseRaw >>= guard >> (withRaw optargs))++ignoreBlocks :: String -> (String, LP Blocks)+ignoreBlocks name = (name, doraw <|> (mempty <$ optargs))+ where optargs = skipopts *> skipMany (try $ optional sp *> braced)+ contseq = '\\':name+ doraw = (rawBlock "latex" . (contseq ++) . snd) <$>+ (getOption readerParseRaw >>= guard >> (withRaw optargs))++blockCommands :: M.Map String (LP Blocks)+blockCommands = M.fromList $+ [ ("par", mempty <$ skipopts)+ , ("title", mempty <$ (skipopts *> tok >>= addMeta "title"))+ , ("subtitle", mempty <$ (skipopts *> tok >>= addMeta "subtitle"))+ , ("author", mempty <$ (skipopts *> authors))+ -- -- in letter class, temp. store address & sig as title, author+ , ("address", mempty <$ (skipopts *> tok >>= addMeta "address"))+ , ("signature", mempty <$ (skipopts *> authors))+ , ("date", mempty <$ (skipopts *> tok >>= addMeta "date"))+ -- sectioning+ , ("chapter", updateState (\s -> s{ stateHasChapters = True })+ *> section nullAttr 0)+ , ("chapter*", updateState (\s -> s{ stateHasChapters = True })+ *> section ("",["unnumbered"],[]) 0)+ , ("section", section nullAttr 1)+ , ("section*", section ("",["unnumbered"],[]) 1)+ , ("subsection", section nullAttr 2)+ , ("subsection*", section ("",["unnumbered"],[]) 2)+ , ("subsubsection", section nullAttr 3)+ , ("subsubsection*", section ("",["unnumbered"],[]) 3)+ , ("paragraph", section nullAttr 4)+ , ("paragraph*", section ("",["unnumbered"],[]) 4)+ , ("subparagraph", section nullAttr 5)+ , ("subparagraph*", section ("",["unnumbered"],[]) 5)+ -- beamer slides+ , ("frametitle", section nullAttr 3)+ , ("framesubtitle", section nullAttr 4)+ -- letters+ , ("opening", (para . trimInlines) <$> (skipopts *> tok))+ , ("closing", skipopts *> closing)+ --+ , ("hrule", pure horizontalRule)+ , ("rule", skipopts *> tok *> tok *> pure horizontalRule)+ , ("item", skipopts *> loose_item)+ , ("documentclass", skipopts *> braced *> preamble)+ , ("centerline", (para . trimInlines) <$> (skipopts *> tok))+ , ("caption", skipopts *> tok >>= setCaption)+ , ("PandocStartInclude", startInclude)+ , ("PandocEndInclude", endInclude)+ , ("bibliography", mempty <$ (skipopts *> braced >>=+ addMeta "bibliography" . splitBibs))+ , ("addbibresource", mempty <$ (skipopts *> braced >>=+ addMeta "bibliography" . splitBibs))+ ] ++ map ignoreBlocks+ -- these commands will be ignored unless --parse-raw is specified,+ -- in which case they will appear as raw latex blocks+ [ "newcommand", "renewcommand", "newenvironment", "renewenvironment"+ -- newcommand, etc. should be parsed by macro, but we need this+ -- here so these aren't parsed as inline commands to ignore+ , "special", "pdfannot", "pdfstringdef"+ , "bibliographystyle"+ , "maketitle", "makeindex", "makeglossary"+ , "addcontentsline", "addtocontents", "addtocounter"+ -- \ignore{} is used conventionally in literate haskell for definitions+ -- that are to be processed by the compiler but not printed.+ , "ignore"+ , "hyperdef"+ , "markboth", "markright", "markleft"+ , "hspace", "vspace"+ ]++addMeta :: ToMetaValue a => String -> a -> LP ()+addMeta field val = updateState $ \st ->+ st{ stateMeta = addMetaField field val $ stateMeta st }++splitBibs :: String -> [Inlines]+splitBibs = map (str . flip replaceExtension "bib" . trim) . splitBy (==',')++setCaption :: Inlines -> LP Blocks+setCaption ils = do+ updateState $ \st -> st{ stateCaption = Just ils }+ return mempty++resetCaption :: LP ()+resetCaption = updateState $ \st -> st{ stateCaption = Nothing }++authors :: LP ()+authors = try $ do+ char '{'+ let oneAuthor = mconcat <$>+ many1 (notFollowedBy' (controlSeq "and") >>+ (inline <|> mempty <$ blockCommand))+ -- skip e.g. \vspace{10pt}+ auths <- sepBy oneAuthor (controlSeq "and")+ char '}'+ addMeta "author" (map trimInlines auths)++section :: Attr -> Int -> LP Blocks+section (ident, classes, kvs) lvl = do+ hasChapters <- stateHasChapters `fmap` getState+ let lvl' = if hasChapters then lvl + 1 else lvl+ skipopts+ contents <- grouped inline+ lab <- option ident $ try (spaces >> controlSeq "label" >> spaces >> braced)+ attr' <- registerHeader (lab, classes, kvs) contents+ return $ headerWith attr' lvl' contents++inlineCommand :: LP Inlines+inlineCommand = try $ do+ name <- anyControlSeq+ guard $ name /= "begin" && name /= "end"+ guard $ not $ isBlockCommand name+ parseRaw <- getOption readerParseRaw+ star <- option "" (string "*")+ let name' = name ++ star+ let raw = do+ rawargs <- withRaw (skipopts *> option "" dimenarg *> many braced)+ let rawcommand = '\\' : name ++ star ++ snd rawargs+ transformed <- applyMacros' rawcommand+ if transformed /= rawcommand+ then parseFromString inlines transformed+ else if parseRaw+ then return $ rawInline "latex" rawcommand+ else return mempty+ case M.lookup name' inlineCommands of+ Just p -> p <|> raw+ Nothing -> case M.lookup name inlineCommands of+ Just p -> p <|> raw+ Nothing -> raw++unlessParseRaw :: LP ()+unlessParseRaw = getOption readerParseRaw >>= guard . not++isBlockCommand :: String -> Bool+isBlockCommand s = maybe False (const True) $ M.lookup s blockCommands++inlineCommands :: M.Map String (LP Inlines)+inlineCommands = M.fromList $+ [ ("emph", extractSpaces emph <$> tok)+ , ("textit", extractSpaces emph <$> tok)+ , ("textsl", extractSpaces emph <$> tok)+ , ("textsc", extractSpaces smallcaps <$> tok)+ , ("sout", extractSpaces strikeout <$> tok)+ , ("textsuperscript", extractSpaces superscript <$> tok)+ , ("textsubscript", extractSpaces subscript <$> tok)+ , ("textbackslash", lit "\\")+ , ("backslash", lit "\\")+ , ("slash", lit "/")+ , ("textbf", extractSpaces strong <$> tok)+ , ("textnormal", extractSpaces (spanWith ("",["nodecor"],[])) <$> tok)+ , ("ldots", lit "…")+ , ("dots", lit "…")+ , ("mdots", lit "…")+ , ("sim", lit "~")+ , ("label", unlessParseRaw >> (inBrackets <$> tok))+ , ("ref", unlessParseRaw >> (inBrackets <$> tok))+ , ("(", mathInline $ manyTill anyChar (try $ string "\\)"))+ , ("[", mathDisplay $ manyTill anyChar (try $ string "\\]"))+ , ("ensuremath", mathInline $ braced)+ , ("P", lit "¶")+ , ("S", lit "§")+ , ("$", lit "$")+ , ("%", lit "%")+ , ("&", lit "&")+ , ("#", lit "#")+ , ("_", lit "_")+ , ("{", lit "{")+ , ("}", lit "}")+ -- old TeX commands+ , ("em", extractSpaces emph <$> inlines)+ , ("it", extractSpaces emph <$> inlines)+ , ("sl", extractSpaces emph <$> inlines)+ , ("bf", extractSpaces strong <$> inlines)+ , ("rm", inlines)+ , ("itshape", extractSpaces emph <$> inlines)+ , ("slshape", extractSpaces emph <$> inlines)+ , ("scshape", extractSpaces smallcaps <$> inlines)+ , ("bfseries", extractSpaces strong <$> inlines)+ , ("/", pure mempty) -- italic correction+ , ("aa", lit "å")+ , ("AA", lit "Å")+ , ("ss", lit "ß")+ , ("o", lit "ø")+ , ("O", lit "Ø")+ , ("L", lit "Ł")+ , ("l", lit "ł")+ , ("ae", lit "æ")+ , ("AE", lit "Æ")+ , ("oe", lit "œ")+ , ("OE", lit "Œ")+ , ("pounds", lit "£")+ , ("euro", lit "€")+ , ("copyright", lit "©")+ , ("textasciicircum", lit "^")+ , ("textasciitilde", lit "~")+ , ("`", option (str "`") $ try $ tok >>= accent grave)+ , ("'", option (str "'") $ try $ tok >>= accent acute)+ , ("^", option (str "^") $ try $ tok >>= accent circ)+ , ("~", option (str "~") $ try $ tok >>= accent tilde)+ , ("\"", option (str "\"") $ try $ tok >>= accent umlaut)+ , (".", option (str ".") $ try $ tok >>= accent dot)+ , ("=", option (str "=") $ try $ tok >>= accent macron)+ , ("c", option (str "c") $ try $ tok >>= accent cedilla)+ , ("v", option (str "v") $ try $ tok >>= accent hacek)+ , ("u", option (str "u") $ try $ tok >>= accent breve)+ , ("i", lit "i")+ , ("\\", linebreak <$ (optional (bracketed inline) *> optional sp))+ , (",", pure mempty)+ , ("@", pure mempty)+ , (" ", lit "\160")+ , ("ps", pure $ str "PS." <> space)+ , ("TeX", lit "TeX")+ , ("LaTeX", lit "LaTeX")+ , ("bar", lit "|")+ , ("textless", lit "<")+ , ("textgreater", lit ">")+ , ("thanks", (note . mconcat) <$> (char '{' *> manyTill block (char '}')))+ , ("footnote", (note . mconcat) <$> (char '{' *> manyTill block (char '}')))+ , ("verb", doverb)+ , ("lstinline", doverb)+ , ("Verb", doverb)+ , ("texttt", (code . stringify . toList) <$> tok)+ , ("url", (unescapeURL <$> braced) >>= \url ->+ pure (link url "" (str url)))+ , ("href", (unescapeURL <$> braced <* optional sp) >>= \url ->+ tok >>= \lab ->+ pure (link url "" lab))+ , ("includegraphics", skipopts *> (unescapeURL <$> braced) >>= mkImage)+ , ("enquote", enquote)+ , ("cite", citation "cite" AuthorInText False)+ , ("citep", citation "citep" NormalCitation False)+ , ("citep*", citation "citep*" NormalCitation False)+ , ("citeal", citation "citeal" NormalCitation False)+ , ("citealp", citation "citealp" NormalCitation False)+ , ("citealp*", citation "citealp*" NormalCitation False)+ , ("autocite", citation "autocite" NormalCitation False)+ , ("footcite", inNote <$> citation "footcite" NormalCitation False)+ , ("parencite", citation "parencite" NormalCitation False)+ , ("supercite", citation "supercite" NormalCitation False)+ , ("footcitetext", inNote <$> citation "footcitetext" NormalCitation False)+ , ("citeyearpar", citation "citeyearpar" SuppressAuthor False)+ , ("citeyear", citation "citeyear" SuppressAuthor False)+ , ("autocite*", citation "autocite*" SuppressAuthor False)+ , ("cite*", citation "cite*" SuppressAuthor False)+ , ("parencite*", citation "parencite*" SuppressAuthor False)+ , ("textcite", citation "textcite" AuthorInText False)+ , ("citet", citation "citet" AuthorInText False)+ , ("citet*", citation "citet*" AuthorInText False)+ , ("citealt", citation "citealt" AuthorInText False)+ , ("citealt*", citation "citealt*" AuthorInText False)+ , ("textcites", citation "textcites" AuthorInText True)+ , ("cites", citation "cites" NormalCitation True)+ , ("autocites", citation "autocites" NormalCitation True)+ , ("footcites", inNote <$> citation "footcites" NormalCitation True)+ , ("parencites", citation "parencites" NormalCitation True)+ , ("supercites", citation "supercites" NormalCitation True)+ , ("footcitetexts", inNote <$> citation "footcitetexts" NormalCitation True)+ , ("Autocite", citation "Autocite" NormalCitation False)+ , ("Footcite", citation "Footcite" NormalCitation False)+ , ("Parencite", citation "Parencite" NormalCitation False)+ , ("Supercite", citation "Supercite" NormalCitation False)+ , ("Footcitetext", inNote <$> citation "Footcitetext" NormalCitation False)+ , ("Citeyearpar", citation "Citeyearpar" SuppressAuthor False)+ , ("Citeyear", citation "Citeyear" SuppressAuthor False)+ , ("Autocite*", citation "Autocite*" SuppressAuthor False)+ , ("Cite*", citation "Cite*" SuppressAuthor False)+ , ("Parencite*", citation "Parencite*" SuppressAuthor False)+ , ("Textcite", citation "Textcite" AuthorInText False)+ , ("Textcites", citation "Textcites" AuthorInText True)+ , ("Cites", citation "Cites" NormalCitation True)+ , ("Autocites", citation "Autocites" NormalCitation True)+ , ("Footcites", citation "Footcites" NormalCitation True)+ , ("Parencites", citation "Parencites" NormalCitation True)+ , ("Supercites", citation "Supercites" NormalCitation True)+ , ("Footcitetexts", inNote <$> citation "Footcitetexts" NormalCitation True)+ , ("citetext", complexNatbibCitation NormalCitation)+ , ("citeauthor", (try (tok *> optional sp *> controlSeq "citetext") *>+ complexNatbibCitation AuthorInText)+ <|> citation "citeauthor" AuthorInText False)+ , ("nocite", mempty <$ (citation "nocite" NormalCitation False >>=+ addMeta "nocite"))+ ] ++ map ignoreInlines+ -- these commands will be ignored unless --parse-raw is specified,+ -- in which case they will appear as raw latex blocks:+ [ "noindent", "index" ]++mkImage :: String -> LP Inlines+mkImage src = do+ let alt = str "image"+ case takeExtension src of+ "" -> do+ defaultExt <- getOption readerDefaultImageExtension+ return $ image (addExtension src defaultExt) "" alt+ _ -> return $ image src "" alt++inNote :: Inlines -> Inlines+inNote ils =+ note $ para $ ils <> str "."++unescapeURL :: String -> String+unescapeURL ('\\':x:xs) | isEscapable x = x:unescapeURL xs+ where isEscapable c = c `elem` "#$%&~_^\\{}"+unescapeURL (x:xs) = x:unescapeURL xs+unescapeURL [] = ""++enquote :: LP Inlines+enquote = do+ skipopts+ context <- stateQuoteContext <$> getState+ if context == InDoubleQuote+ then singleQuoted <$> withQuoteContext InSingleQuote tok+ else doubleQuoted <$> withQuoteContext InDoubleQuote tok++doverb :: LP Inlines+doverb = do+ marker <- anyChar+ code <$> manyTill (satisfy (/='\n')) (char marker)++doLHSverb :: LP Inlines+doLHSverb = codeWith ("",["haskell"],[]) <$> manyTill (satisfy (/='\n')) (char '|')++lit :: String -> LP Inlines+lit = pure . str++accent :: (Char -> String) -> Inlines -> LP Inlines+accent f ils =+ case toList ils of+ (Str (x:xs) : ys) -> return $ fromList $ (Str (f x ++ xs) : ys)+ [] -> mzero+ _ -> return ils++grave :: Char -> String+grave 'A' = "À"+grave 'E' = "È"+grave 'I' = "Ì"+grave 'O' = "Ò"+grave 'U' = "Ù"+grave 'a' = "à"+grave 'e' = "è"+grave 'i' = "ì"+grave 'o' = "ò"+grave 'u' = "ù"+grave c = [c]++acute :: Char -> String+acute 'A' = "Á"+acute 'E' = "É"+acute 'I' = "Í"+acute 'O' = "Ó"+acute 'U' = "Ú"+acute 'Y' = "Ý"+acute 'a' = "á"+acute 'e' = "é"+acute 'i' = "í"+acute 'o' = "ó"+acute 'u' = "ú"+acute 'y' = "ý"+acute 'C' = "Ć"+acute 'c' = "ć"+acute 'L' = "Ĺ"+acute 'l' = "ĺ"+acute 'N' = "Ń"+acute 'n' = "ń"+acute 'R' = "Ŕ"+acute 'r' = "ŕ"+acute 'S' = "Ś"+acute 's' = "ś"+acute 'Z' = "Ź"+acute 'z' = "ź"+acute c = [c]++circ :: Char -> String+circ 'A' = "Â"+circ 'E' = "Ê"+circ 'I' = "Î"+circ 'O' = "Ô"+circ 'U' = "Û"+circ 'a' = "â"+circ 'e' = "ê"+circ 'i' = "î"+circ 'o' = "ô"+circ 'u' = "û"+circ 'C' = "Ĉ"+circ 'c' = "ĉ"+circ 'G' = "Ĝ"+circ 'g' = "ĝ"+circ 'H' = "Ĥ"+circ 'h' = "ĥ"+circ 'J' = "Ĵ"+circ 'j' = "ĵ"+circ 'S' = "Ŝ"+circ 's' = "ŝ"+circ 'W' = "Ŵ"+circ 'w' = "ŵ"+circ 'Y' = "Ŷ"+circ 'y' = "ŷ"+circ c = [c]++tilde :: Char -> String+tilde 'A' = "Ã"+tilde 'a' = "ã"+tilde 'O' = "Õ"+tilde 'o' = "õ"+tilde 'I' = "Ĩ"+tilde 'i' = "ĩ"+tilde 'U' = "Ũ"+tilde 'u' = "ũ"+tilde 'N' = "Ñ"+tilde 'n' = "ñ"+tilde c = [c]++umlaut :: Char -> String+umlaut 'A' = "Ä"+umlaut 'E' = "Ë"+umlaut 'I' = "Ï"+umlaut 'O' = "Ö"+umlaut 'U' = "Ü"+umlaut 'a' = "ä"+umlaut 'e' = "ë"+umlaut 'i' = "ï"+umlaut 'o' = "ö"+umlaut 'u' = "ü"+umlaut c = [c]++dot :: Char -> String+dot 'C' = "Ċ"+dot 'c' = "ċ"+dot 'E' = "Ė"+dot 'e' = "ė"+dot 'G' = "Ġ"+dot 'g' = "ġ"+dot 'I' = "İ"+dot 'Z' = "Ż"+dot 'z' = "ż"+dot c = [c]++macron :: Char -> String+macron 'A' = "Ā"+macron 'E' = "Ē"+macron 'I' = "Ī"+macron 'O' = "Ō"+macron 'U' = "Ū"+macron 'a' = "ā"+macron 'e' = "ē"+macron 'i' = "ī"+macron 'o' = "ō"+macron 'u' = "ū"+macron c = [c]++cedilla :: Char -> String+cedilla 'c' = "ç"+cedilla 'C' = "Ç"+cedilla 's' = "ş"+cedilla 'S' = "Ş"+cedilla 't' = "ţ"+cedilla 'T' = "Ţ"+cedilla 'e' = "ȩ"+cedilla 'E' = "Ȩ"+cedilla 'h' = "ḩ"+cedilla 'H' = "Ḩ"+cedilla 'o' = "o̧"+cedilla 'O' = "O̧"+cedilla c = [c]++hacek :: Char -> String+hacek 'A' = "Ǎ"+hacek 'a' = "ǎ"+hacek 'C' = "Č"+hacek 'c' = "č"+hacek 'D' = "Ď"+hacek 'd' = "ď"+hacek 'E' = "Ě"+hacek 'e' = "ě"+hacek 'G' = "Ǧ"+hacek 'g' = "ǧ"+hacek 'H' = "Ȟ"+hacek 'h' = "ȟ"+hacek 'I' = "Ǐ"+hacek 'i' = "ǐ"+hacek 'j' = "ǰ"+hacek 'K' = "Ǩ"+hacek 'k' = "ǩ"+hacek 'L' = "Ľ"+hacek 'l' = "ľ"+hacek 'N' = "Ň"+hacek 'n' = "ň"+hacek 'O' = "Ǒ"+hacek 'o' = "ǒ"+hacek 'R' = "Ř"+hacek 'r' = "ř"+hacek 'S' = "Š"+hacek 's' = "š"+hacek 'T' = "Ť"+hacek 't' = "ť"+hacek 'U' = "Ǔ"+hacek 'u' = "ǔ"+hacek 'Z' = "Ž"+hacek 'z' = "ž"+hacek c = [c]++breve :: Char -> String+breve 'A' = "Ă"+breve 'a' = "ă"+breve 'E' = "Ĕ"+breve 'e' = "ĕ"+breve 'G' = "Ğ"+breve 'g' = "ğ"+breve 'I' = "Ĭ"+breve 'i' = "ĭ"+breve 'O' = "Ŏ"+breve 'o' = "ŏ"+breve 'U' = "Ŭ"+breve 'u' = "ŭ"+breve c = [c]++tok :: LP Inlines+tok = try $ grouped inline <|> inlineCommand <|> str <$> (count 1 $ inlineChar)++opt :: LP Inlines+opt = bracketed inline <* optional sp++skipopts :: LP ()+skipopts = skipMany opt++inlineText :: LP Inlines+inlineText = str <$> many1 inlineChar++inlineChar :: LP Char+inlineChar = noneOf "\\$%^_&~#{}^'`\"‘’“”-[] \t\n"++environment :: LP Blocks+environment = do+ controlSeq "begin"+ name <- braced+ case M.lookup name environments of+ Just p -> p <|> rawEnv name+ Nothing -> rawEnv name++rawEnv :: String -> LP Blocks+rawEnv name = do+ let addBegin x = "\\begin{" ++ name ++ "}" ++ x+ parseRaw <- getOption readerParseRaw+ if parseRaw+ then (rawBlock "latex" . addBegin) <$>+ (withRaw (env name blocks) >>= applyMacros' . snd)+ else env name blocks++----++type IncludeParser = ParserT [Char] [String] IO String++-- | Replace "include" commands with file contents.+handleIncludes :: String -> IO String+handleIncludes s = do+ res <- runParserT includeParser' [] "input" s+ case res of+ Right s' -> return s'+ Left e -> error $ show e++includeParser' :: IncludeParser+includeParser' =+ concat <$> many (comment' <|> escaped' <|> blob' <|> include'+ <|> startMarker' <|> endMarker'+ <|> verbCmd' <|> verbatimEnv' <|> backslash')++comment' :: IncludeParser+comment' = do+ char '%'+ xs <- manyTill anyChar newline+ return ('%':xs ++ "\n")++escaped' :: IncludeParser+escaped' = try $ string "\\%" <|> string "\\\\"++verbCmd' :: IncludeParser+verbCmd' = fmap snd <$>+ withRaw $ try $ do+ string "\\verb"+ c <- anyChar+ manyTill anyChar (char c)++verbatimEnv' :: IncludeParser+verbatimEnv' = fmap snd <$>+ withRaw $ try $ do+ string "\\begin"+ name <- braced'+ guard $ name `elem` ["verbatim", "Verbatim", "lstlisting",+ "minted", "alltt"]+ manyTill anyChar (try $ string $ "\\end{" ++ name ++ "}")++blob' :: IncludeParser+blob' = try $ many1 (noneOf "\\%")++backslash' :: IncludeParser+backslash' = string "\\"++braced' :: IncludeParser+braced' = try $ char '{' *> manyTill (satisfy (/='}')) (char '}')++include' :: IncludeParser+include' = do+ fs' <- try $ do+ char '\\'+ name <- try (string "include")+ <|> try (string "input")+ <|> string "usepackage"+ -- skip options+ skipMany $ try $ char '[' *> (manyTill anyChar (char ']'))+ fs <- (map trim . splitBy (==',')) <$> braced'+ return $ if name == "usepackage"+ then map (flip replaceExtension ".sty") fs+ else map (flip replaceExtension ".tex") fs+ pos <- getPosition+ containers <- getState+ let fn = case containers of+ (f':_) -> f'+ [] -> "input"+ -- now process each include file in order...+ rest <- getInput+ results' <- forM fs' (\f -> do+ when (f `elem` containers) $+ fail "Include file loop!"+ contents <- lift $ readTeXFile f+ return $ "\\PandocStartInclude{" ++ f ++ "}" +++ contents ++ "\\PandocEndInclude{" +++ fn ++ "}{" ++ show (sourceLine pos) ++ "}{"+ ++ show (sourceColumn pos) ++ "}")+ setInput $ concat results' ++ rest+ return ""++startMarker' :: IncludeParser+startMarker' = try $ do+ string "\\PandocStartInclude"+ fn <- braced'+ updateState (fn:)+ setPosition $ newPos fn 1 1+ return $ "\\PandocStartInclude{" ++ fn ++ "}"++endMarker' :: IncludeParser+endMarker' = try $ do+ string "\\PandocEndInclude"+ fn <- braced'+ ln <- braced'+ co <- braced'+ updateState tail+ setPosition $ newPos fn (fromMaybe 1 $ safeRead ln) (fromMaybe 1 $ safeRead co)+ return $ "\\PandocEndInclude{" ++ fn ++ "}{" ++ ln ++ "}{" +++ co ++ "}"++readTeXFile :: FilePath -> IO String+readTeXFile f = do+ texinputs <- E.catch (getEnv "TEXINPUTS") $ \(_ :: E.SomeException) ->+ return "."+ let ds = splitBy (==':') texinputs+ readFileFromDirs ds f++readFileFromDirs :: [FilePath] -> FilePath -> IO String+readFileFromDirs [] _ = return ""+readFileFromDirs (d:ds) f =+ E.catch (UTF8.readFile $ d </> f) $ \(_ :: E.SomeException) ->+ readFileFromDirs ds f++----++keyval :: LP (String, String)+keyval = try $ do+ key <- many1 alphaNum+ val <- option "" $ char '=' >> many1 alphaNum+ skipMany spaceChar+ optional (char ',')+ skipMany spaceChar+ return (key, val)+++keyvals :: LP [(String, String)]+keyvals = try $ char '[' *> manyTill keyval (char ']')++alltt :: String -> LP Blocks+alltt t = walk strToCode <$> parseFromString blocks+ (substitute " " "\\ " $ substitute "%" "\\%" $+ concat $ intersperse "\\\\\n" $ lines t)+ where strToCode (Str s) = Code nullAttr s+ strToCode x = x++rawLaTeXBlock :: Parser [Char] ParserState String+rawLaTeXBlock = snd <$> try (withRaw (environment <|> blockCommand))++rawLaTeXInline :: Parser [Char] ParserState Inline+rawLaTeXInline = do+ raw <- (snd <$> withRaw inlineCommand) <|> (snd <$> withRaw blockCommand)+ RawInline "latex" <$> applyMacros' raw++addImageCaption :: Blocks -> LP Blocks+addImageCaption = walkM go+ where go (Image attr alt (src,tit)) = do+ mbcapt <- stateCaption <$> getState+ case mbcapt of+ Just ils -> return (Image attr (toList ils) (src, "fig:"))+ Nothing -> return (Image attr alt (src,tit))+ go x = return x++addTableCaption :: Blocks -> LP Blocks+addTableCaption = walkM go+ where go (Table c als ws hs rs) = do+ mbcapt <- stateCaption <$> getState+ case mbcapt of+ Just ils -> return (Table (toList ils) als ws hs rs)+ Nothing -> return (Table c als ws hs rs)+ go x = return x++environments :: M.Map String (LP Blocks)+environments = M.fromList+ [ ("document", env "document" blocks <* skipMany anyChar)+ , ("letter", env "letter" letter_contents)+ , ("figure", env "figure" $+ resetCaption *> skipopts *> blocks >>= addImageCaption)+ , ("center", env "center" blocks)+ , ("table", env "table" $+ resetCaption *> skipopts *> blocks >>= addTableCaption)+ , ("tabular", env "tabular" simpTable)+ , ("quote", blockQuote <$> env "quote" blocks)+ , ("quotation", blockQuote <$> env "quotation" blocks)+ , ("verse", blockQuote <$> env "verse" blocks)+ , ("itemize", bulletList <$> listenv "itemize" (many item))+ , ("description", definitionList <$> listenv "description" (many descItem))+ , ("enumerate", ordered_list)+ , ("alltt", alltt =<< verbEnv "alltt")+ , ("code", guardEnabled Ext_literate_haskell *>+ (codeBlockWith ("",["sourceCode","literate","haskell"],[]) <$>+ verbEnv "code"))+ , ("verbatim", codeBlock <$> (verbEnv "verbatim"))+ , ("Verbatim", do options <- option [] keyvals+ let kvs = [ (if k == "firstnumber"+ then "startFrom"+ else k, v) | (k,v) <- options ]+ let classes = [ "numberLines" |+ lookup "numbers" options == Just "left" ]+ let attr = ("",classes,kvs)+ codeBlockWith attr <$> (verbEnv "Verbatim"))+ , ("lstlisting", do options <- option [] keyvals+ let kvs = [ (if k == "firstnumber"+ then "startFrom"+ else k, v) | (k,v) <- options ]+ let classes = [ "numberLines" |+ lookup "numbers" options == Just "left" ]+ ++ maybe [] (:[]) (lookup "language" options+ >>= fromListingsLanguage)+ let attr = (fromMaybe "" (lookup "label" options),classes,kvs)+ codeBlockWith attr <$> (verbEnv "lstlisting"))+ , ("minted", do options <- option [] keyvals+ lang <- grouped (many1 $ satisfy (/='}'))+ let kvs = [ (if k == "firstnumber"+ then "startFrom"+ else k, v) | (k,v) <- options ]+ let classes = [ lang | not (null lang) ] +++ [ "numberLines" |+ lookup "linenos" options == Just "true" ]+ let attr = ("",classes,kvs)+ codeBlockWith attr <$> (verbEnv "minted"))+ , ("obeylines", parseFromString+ (para . trimInlines . mconcat <$> many inline) =<<+ intercalate "\\\\\n" . lines <$> verbEnv "obeylines")+ , ("displaymath", mathEnv Nothing "displaymath")+ , ("equation", mathEnv Nothing "equation")+ , ("equation*", mathEnv Nothing "equation*")+ , ("gather", mathEnv (Just "gathered") "gather")+ , ("gather*", mathEnv (Just "gathered") "gather*")+ , ("multline", mathEnv (Just "gathered") "multline")+ , ("multline*", mathEnv (Just "gathered") "multline*")+ , ("eqnarray", mathEnv (Just "aligned") "eqnarray")+ , ("eqnarray*", mathEnv (Just "aligned") "eqnarray*")+ , ("align", mathEnv (Just "aligned") "align")+ , ("align*", mathEnv (Just "aligned") "align*")+ , ("alignat", mathEnv (Just "aligned") "alignat")+ , ("alignat*", mathEnv (Just "aligned") "alignat*")+ ]++letter_contents :: LP Blocks+letter_contents = do+ bs <- blocks+ st <- getState+ -- add signature (author) and address (title)+ let addr = case lookupMeta "address" (stateMeta st) of+ Just (MetaBlocks [Plain xs]) ->+ para $ trimInlines $ fromList xs+ _ -> mempty+ return $ addr <> bs -- sig added by \closing++closing :: LP Blocks+closing = do+ contents <- tok+ st <- getState+ let extractInlines (MetaBlocks [Plain ys]) = ys+ extractInlines (MetaBlocks [Para ys ]) = ys+ extractInlines _ = []+ let sigs = case lookupMeta "author" (stateMeta st) of+ Just (MetaList xs) ->+ para $ trimInlines $ fromList $+ intercalate [LineBreak] $ map extractInlines xs+ _ -> mempty+ return $ para (trimInlines contents) <> sigs++item :: LP Blocks+item = blocks *> controlSeq "item" *> skipopts *> blocks++loose_item :: LP Blocks+loose_item = do+ ctx <- stateParserContext `fmap` getState+ if ctx == ListItemState+ then mzero+ else return mempty++descItem :: LP (Inlines, [Blocks])+descItem = do+ blocks -- skip blocks before item+ controlSeq "item"+ optional sp+ ils <- opt+ bs <- blocks+ return (ils, [bs])++env :: String -> LP a -> LP a+env name p = p <*+ (try (controlSeq "end" *> braced >>= guard . (== name))+ <?> ("\\end{" ++ name ++ "}"))++listenv :: String -> LP a -> LP a+listenv name p = try $ do+ oldCtx <- stateParserContext `fmap` getState+ updateState $ \st -> st{ stateParserContext = ListItemState }+ res <- env name p+ updateState $ \st -> st{ stateParserContext = oldCtx }+ return res++mathEnv :: Maybe String -> String -> LP Blocks+mathEnv innerEnv name = para <$> mathDisplay (inner <$> verbEnv name)+ where inner x = case innerEnv of+ Nothing -> x+ Just y -> "\\begin{" ++ y ++ "}\n" ++ x +++ "\\end{" ++ y ++ "}"++verbEnv :: String -> LP String+verbEnv name = do+ skipopts+ optional blankline+ let endEnv = try $ controlSeq "end" *> braced >>= guard . (== name)+ res <- manyTill anyChar endEnv+ return $ stripTrailingNewlines res++ordered_list :: LP Blocks+ordered_list = do+ optional sp+ (_, style, delim) <- option (1, DefaultStyle, DefaultDelim) $+ try $ char '[' *> anyOrderedListMarker <* char ']'+ spaces+ optional $ try $ controlSeq "setlength" *> grouped (controlSeq "itemindent") *> braced+ spaces+ start <- option 1 $ try $ do controlSeq "setcounter"+ grouped (string "enum" *> many1 (oneOf "iv"))+ optional sp+ num <- grouped (many1 digit)+ spaces+ return $ (read num + 1 :: Int)+ bs <- listenv "enumerate" (many item)+ return $ orderedListWith (start, style, delim) bs++paragraph :: LP Blocks+paragraph = do+ x <- trimInlines . mconcat <$> many1 inline+ if x == mempty+ then return mempty+ else return $ para x++preamble :: LP Blocks+preamble = mempty <$> manyTill preambleBlock beginDoc+ where beginDoc = lookAhead $ try $ controlSeq "begin" *> string "{document}"+ preambleBlock = (void comment)+ <|> (void sp)+ <|> (void blanklines)+ <|> (void macro)+ <|> (void blockCommand)+ <|> (void anyControlSeq)+ <|> (void braced)+ <|> (void anyChar)++-------++-- citations++addPrefix :: [Inline] -> [Citation] -> [Citation]+addPrefix p (k:ks) = k {citationPrefix = p ++ citationPrefix k} : ks+addPrefix _ _ = []++addSuffix :: [Inline] -> [Citation] -> [Citation]+addSuffix s ks@(_:_) =+ let k = last ks+ in init ks ++ [k {citationSuffix = citationSuffix k ++ s}]+addSuffix _ _ = []++simpleCiteArgs :: LP [Citation]+simpleCiteArgs = try $ do+ first <- optionMaybe $ toList <$> opt+ second <- optionMaybe $ toList <$> opt+ char '{'+ optional sp+ keys <- manyTill citationLabel (char '}')+ let (pre, suf) = case (first , second ) of+ (Just s , Nothing) -> (mempty, s )+ (Just s , Just t ) -> (s , t )+ _ -> (mempty, mempty)+ conv k = Citation { citationId = k+ , citationPrefix = []+ , citationSuffix = []+ , citationMode = NormalCitation+ , citationHash = 0+ , citationNoteNum = 0+ }+ return $ addPrefix pre $ addSuffix suf $ map conv keys++citationLabel :: LP String+citationLabel = optional sp *>+ (many1 (satisfy isBibtexKeyChar)+ <* optional sp+ <* optional (char ',')+ <* optional sp)+ where isBibtexKeyChar c = isAlphaNum c || c `elem` ".:;?!`'()/*@_+=-[]*"++cites :: CitationMode -> Bool -> LP [Citation]+cites mode multi = try $ do+ cits <- if multi+ then many1 simpleCiteArgs+ else count 1 simpleCiteArgs+ let cs = concat cits+ return $ case mode of+ AuthorInText -> case cs of+ (c:rest) -> c {citationMode = mode} : rest+ [] -> []+ _ -> map (\a -> a {citationMode = mode}) cs++citation :: String -> CitationMode -> Bool -> LP Inlines+citation name mode multi = do+ (c,raw) <- withRaw $ cites mode multi+ return $ cite c (rawInline "latex" $ "\\" ++ name ++ raw)++complexNatbibCitation :: CitationMode -> LP Inlines+complexNatbibCitation mode = try $ do+ let ils = (toList . trimInlines . mconcat) <$>+ many (notFollowedBy (oneOf "\\};") >> inline)+ let parseOne = try $ do+ skipSpaces+ pref <- ils+ cit' <- inline -- expect a citation+ let citlist = toList cit'+ cits' <- case citlist of+ [Cite cs _] -> return cs+ _ -> mzero+ suff <- ils+ skipSpaces+ optional $ char ';'+ return $ addPrefix pref $ addSuffix suff $ cits'+ (c:cits, raw) <- withRaw $ grouped parseOne+ return $ cite (c{ citationMode = mode }:cits)+ (rawInline "latex" $ "\\citetext" ++ raw)++-- tables++parseAligns :: LP [Alignment]+parseAligns = try $ do+ char '{'+ let maybeBar = skipMany $ sp <|> () <$ char '|' <|> () <$ try (string "@{}")+ maybeBar+ let cAlign = AlignCenter <$ char 'c'+ let lAlign = AlignLeft <$ char 'l'+ let rAlign = AlignRight <$ char 'r'+ let parAlign = AlignLeft <$ (char 'p' >> braced)+ let alignChar = cAlign <|> lAlign <|> rAlign <|> parAlign+ aligns' <- sepEndBy alignChar maybeBar+ spaces+ char '}'+ spaces+ return aligns'++hline :: LP ()+hline = () <$ (try $ spaces >> controlSeq "hline")++lbreak :: LP ()+lbreak = () <$ (try $ spaces *> controlSeq "\\")++amp :: LP ()+amp = () <$ (try $ spaces *> char '&')++parseTableRow :: Int -- ^ number of columns+ -> LP [Blocks]+parseTableRow cols = try $ do+ let tableCellInline = notFollowedBy (amp <|> lbreak) >> inline+ let tableCell = (plain . trimInlines . mconcat) <$> many tableCellInline+ cells' <- sepBy1 tableCell amp+ let numcells = length cells'+ guard $ numcells <= cols && numcells >= 1+ guard $ cells' /= [mempty]+ -- note: a & b in a three-column table leaves an empty 3rd cell:+ let cells'' = cells' ++ replicate (cols - numcells) mempty+ spaces+ return cells''++simpTable :: LP Blocks+simpTable = try $ do+ spaces+ aligns <- parseAligns+ let cols = length aligns+ optional hline+ header' <- option [] $ try (parseTableRow cols <* lbreak <* hline)+ rows <- sepEndBy (parseTableRow cols) (lbreak <* optional hline)+ spaces+ skipMany (comment *> spaces)+ let header'' = if null header'+ then replicate cols mempty+ else header'+ lookAhead $ controlSeq "end" -- make sure we're at end+ return $ table mempty (zip aligns (repeat 0)) header'' rows++startInclude :: LP Blocks+startInclude = do+ fn <- braced+ setPosition $ newPos fn 1 1+ return mempty++endInclude :: LP Blocks+endInclude = do+ fn <- braced+ ln <- braced+ co <- braced+ setPosition $ newPos fn (fromMaybe 1 $ safeRead ln) (fromMaybe 1 $ safeRead co)+ return mempty
@@ -0,0 +1,2407 @@+{-# LANGUAGE RelaxedPolyRec #-} -- needed for inlinesBetween on GHC < 7+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>+Copyright (C) 2014 Tim T.Y. Lin <timtylin@gmail.com>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Readers.Markdown+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of markdown-formatted plain text to 'Pandoc' document.+-}+module Text.Pandoc.Readers.Markdown ( readMarkdown,+ readMarkdownWithWarnings ) where++import Data.List ( transpose, sortBy, findIndex, intersperse, intercalate )+import qualified Data.Map as M+import Data.Scientific (coefficient, base10Exponent)+import Data.Ord ( comparing )+import Data.Char ( isAlphaNum, toLower )+import Data.Maybe+import Text.Pandoc.Definition+import qualified Data.Text as T+import Data.Text (Text)+import qualified Data.Yaml as Yaml+import Data.Yaml (ParseException(..), YamlException(..), YamlMark(..))+import qualified Data.HashMap.Strict as H+import qualified Text.Pandoc.Builder as B+import qualified Text.Pandoc.UTF8 as UTF8+import qualified Data.Vector as V+import Text.Pandoc.Builder (Inlines, Blocks, trimInlines, (<>))+import Text.Pandoc.Options+import Text.Pandoc.Shared+import Text.Pandoc.XML (fromEntities)+import Text.Pandoc.Parsing hiding (tableWith)+import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )+import Text.Pandoc.Readers.HTML ( htmlTag, htmlInBalanced, isInlineTag, isBlockTag,+ isTextTag, isCommentTag )+import Text.Pandoc.Scholarly+import Data.Monoid (mconcat, mempty)+import Control.Applicative ((<$>), (<*), (*>), (<$))+import Control.Monad+import System.FilePath (takeExtension, addExtension)+import Text.HTML.TagSoup+import Text.HTML.TagSoup.Match (tagOpen)+import qualified Data.Set as Set+import Text.Printf (printf)+import Debug.Trace (trace)++type MarkdownParser = Parser [Char] ParserState++-- | Read markdown from an input string and return a Pandoc document.+readMarkdown :: ReaderOptions -- ^ Reader options+ -> String -- ^ String to parse (assuming @'\n'@ line endings)+ -> Pandoc+readMarkdown opts s =+ (readWith parseMarkdown) def{ stateOptions = opts } (s ++ "\n\n")++-- | Read markdown from an input string and return a pair of a Pandoc document+-- and a list of warnings.+readMarkdownWithWarnings :: ReaderOptions -- ^ Reader options+ -> String -- ^ String to parse (assuming @'\n'@ line endings)+ -> (Pandoc, [String])+readMarkdownWithWarnings opts s =+ (readWith parseMarkdownWithWarnings) def{ stateOptions = opts } (s ++ "\n\n")+ where parseMarkdownWithWarnings = do+ doc <- parseMarkdown+ warnings <- stateWarnings <$> getState+ return (doc, warnings)++trimInlinesF :: F Inlines -> F Inlines+trimInlinesF = liftM trimInlines++--+-- Constants and data structure definitions+--++isBulletListMarker :: Char -> Bool+isBulletListMarker '*' = True+isBulletListMarker '+' = True+isBulletListMarker '-' = True+isBulletListMarker _ = False++isHruleChar :: Char -> Bool+isHruleChar '*' = True+isHruleChar '-' = True+isHruleChar '_' = True+isHruleChar _ = False++setextHChars :: String+setextHChars = "=-"++isBlank :: Char -> Bool+isBlank ' ' = True+isBlank '\t' = True+isBlank '\n' = True+isBlank _ = False++--+-- auxiliary functions+--++isNull :: F Inlines -> Bool+isNull ils = B.isNull $ runF ils def++spnl :: Parser [Char] st ()+spnl = try $ do+ skipSpaces+ optional newline+ skipSpaces+ notFollowedBy (char '\n')++indentSpaces :: MarkdownParser String+indentSpaces = try $ do+ tabStop <- getOption readerTabStop+ count tabStop (char ' ') <|>+ string "\t" <?> "indentation"++nonindentSpaces :: MarkdownParser String+nonindentSpaces = do+ tabStop <- getOption readerTabStop+ sps <- many (char ' ')+ if length sps < tabStop+ then return sps+ else unexpected "indented line"++-- returns number of spaces parsed+skipNonindentSpaces :: MarkdownParser Int+skipNonindentSpaces = do+ tabStop <- getOption readerTabStop+ atMostSpaces (tabStop - 1) <* notFollowedBy (char ' ')++atMostSpaces :: Int -> MarkdownParser Int+atMostSpaces n+ | n > 0 = (char ' ' >> (+1) <$> atMostSpaces (n-1)) <|> return 0+ | otherwise = return 0++litChar :: MarkdownParser Char+litChar = escapedChar'+ <|> characterReference+ <|> noneOf "\n"+ <|> try (newline >> notFollowedBy blankline >> return ' ')++-- | Parse a sequence of inline elements between square brackets,+-- including inlines between balanced pairs of square brackets.+inlinesInBalancedBrackets :: MarkdownParser (F Inlines)+inlinesInBalancedBrackets = charsInBalancedBrackets >>=+ parseFromString (trimInlinesF . mconcat <$> many inline)++charsInBalancedBrackets :: MarkdownParser [Char]+charsInBalancedBrackets = do+ char '['+ result <- manyTill ( many1 (noneOf "`[]\n")+ <|> (snd <$> withRaw code)+ <|> ((\xs -> '[' : xs ++ "]") <$> charsInBalancedBrackets)+ <|> count 1 (satisfy (/='\n'))+ <|> (newline >> notFollowedBy blankline >> return "\n")+ ) (char ']')+ return $ concat result++--+-- document structure+--++titleLine :: MarkdownParser (F Inlines)+titleLine = try $ do+ char '%'+ skipSpaces+ res <- many $ (notFollowedBy newline >> inline)+ <|> try (endline >> whitespace)+ newline+ return $ trimInlinesF $ mconcat res++authorsLine :: MarkdownParser (F [Inlines])+authorsLine = try $ do+ char '%'+ skipSpaces+ authors <- sepEndBy (many (notFollowedBy (satisfy $ \c ->+ c == ';' || c == '\n') >> inline))+ (char ';' <|>+ try (newline >> notFollowedBy blankline >> spaceChar))+ newline+ return $ sequence $ filter (not . isNull) $ map (trimInlinesF . mconcat) authors++dateLine :: MarkdownParser (F Inlines)+dateLine = try $ do+ char '%'+ skipSpaces+ trimInlinesF . mconcat <$> manyTill inline newline++titleBlock :: MarkdownParser ()+titleBlock = pandocTitleBlock <|> mmdTitleBlock++pandocTitleBlock :: MarkdownParser ()+pandocTitleBlock = try $ do+ guardEnabled Ext_pandoc_title_block+ lookAhead (char '%')+ title <- option mempty titleLine+ author <- option (return []) authorsLine+ date <- option mempty dateLine+ optional blanklines+ let meta' = do title' <- title+ author' <- author+ date' <- date+ return $+ (if B.isNull title' then id else B.setMeta "title" title')+ . (if null author' then id else B.setMeta "author" author')+ . (if B.isNull date' then id else B.setMeta "date" date')+ $ nullMeta+ updateState $ \st -> st{ stateMeta' = stateMeta' st <> meta' }++yamlMetaBlock :: MarkdownParser (F Blocks)+yamlMetaBlock = try $ do+ guardEnabled Ext_yaml_metadata_block+ pos <- getPosition+ string "---"+ blankline+ notFollowedBy blankline -- if --- is followed by a blank it's an HRULE+ rawYamlLines <- manyTill anyLine stopLine+ -- by including --- and ..., we allow yaml blocks with just comments:+ let rawYaml = unlines ("---" : (rawYamlLines ++ ["..."]))+ optional blanklines+ opts <- stateOptions <$> getState+ meta' <- case Yaml.decodeEither' $ UTF8.fromString rawYaml of+ Right (Yaml.Object hashmap) -> return $ return $+ H.foldrWithKey (\k v m ->+ if ignorable k+ then m+ else if yamlStringKeys k+ then B.setMeta (T.unpack k)+ (yamlToMetaString v) m+ else B.setMeta (T.unpack k)+ (yamlToMeta opts v) m)+ nullMeta hashmap+ Right Yaml.Null -> return $ return nullMeta+ Right _ -> do+ addWarning (Just pos) "YAML header is not an object"+ return $ return nullMeta+ Left err' -> do+ case err' of+ InvalidYaml (Just YamlParseException{+ yamlProblem = problem+ , yamlContext = _ctxt+ , yamlProblemMark = Yaml.YamlMark {+ yamlLine = yline+ , yamlColumn = ycol+ }}) ->+ addWarning (Just $ setSourceLine+ (setSourceColumn pos+ (sourceColumn pos + ycol))+ (sourceLine pos + 1 + yline))+ $ "Could not parse YAML header: " +++ problem+ _ -> addWarning (Just pos)+ $ "Could not parse YAML header: " +++ show err'+ return $ return nullMeta+ updateState $ \st -> st{ stateMeta' = stateMeta' st <> meta' }+ return mempty++-- ignore fields ending with _+ignorable :: Text -> Bool+ignorable t = (T.pack "_") `T.isSuffixOf` t++toMetaValue :: ReaderOptions -> Text -> MetaValue+toMetaValue opts x =+ case readMarkdown opts (T.unpack x) of+ Pandoc _ [Plain xs] -> MetaInlines xs+ Pandoc _ [Para xs]+ | endsWithNewline x -> MetaBlocks [Para xs]+ | otherwise -> MetaInlines xs+ Pandoc _ bs -> MetaBlocks bs+ where endsWithNewline t = (T.pack "\n") `T.isSuffixOf` t++yamlToMeta :: ReaderOptions -> Yaml.Value -> MetaValue+yamlToMeta opts (Yaml.String t) = toMetaValue opts t+yamlToMeta _ (Yaml.Number n)+ -- avoid decimal points for numbers that don't need them:+ | base10Exponent n >= 0 = MetaString $ show+ $ coefficient n * (10 ^ base10Exponent n)+ | otherwise = MetaString $ show n+yamlToMeta _ (Yaml.Bool b) = MetaBool b+yamlToMeta opts (Yaml.Array xs) = B.toMetaValue $ map (yamlToMeta opts)+ $ V.toList xs+yamlToMeta opts (Yaml.Object o) = MetaMap $ H.foldrWithKey (\k v m ->+ if ignorable k+ then m+ else M.insert (T.unpack k)+ (yamlToMeta opts v) m)+ M.empty o+yamlToMeta _ _ = MetaString ""++-- Useful for things like bibliography filenames, will always treat as+-- either a String, or Lists (of Lists..) of Strings+yamlToMetaString :: Yaml.Value -> MetaValue+yamlToMetaString (Yaml.String t) = MetaString (T.unpack t)+yamlToMetaString (Yaml.Array xs) = B.toMetaValue $+ map yamlToMetaString $+ V.toList xs+yamlToMetaString _ = MetaString ""++-- List of meta keys to treat as pure strings+yamlStringKeys :: Text -> Bool+yamlStringKeys t = (T.unpack t) `elem`+ [ "bibliography"+ , "math-macros"+ , "csl"+ , "geometry"+ , "biblio-style"+ , "natbib-options"+ , "biblatex-options"+ , "latex-before-documentclass-includes"+ , "latex-before-packages-includes"+ , "latex-after-packages-includes"+ , "latex-after-body-includes"+ , "latex-after-document-includes"+ , "latex-header-includes"+ , "html-header-includes"+ ]++stopLine :: MarkdownParser ()+stopLine = try $ (string "---" <|> string "...") >> blankline >> return ()++mmdTitleBlock :: MarkdownParser ()+mmdTitleBlock = try $ do+ guardEnabled Ext_mmd_title_block+ kvPairs <- many1 kvPair+ blanklines+ updateState $ \st -> st{ stateMeta' = stateMeta' st <>+ return (Meta $ M.fromList kvPairs) }++kvPair :: MarkdownParser (String, MetaValue)+kvPair = try $ do+ key <- many1Till (alphaNum <|> oneOf "_- ") (char ':')+ val <- manyTill anyChar+ (try $ newline >> lookAhead (blankline <|> nonspaceChar))+ let key' = concat $ words $ map toLower key+ let val' = MetaBlocks $ B.toList $ B.plain $ B.text $ trim val+ return (key',val')++parseMarkdown :: MarkdownParser Pandoc+parseMarkdown = do+ -- markdown allows raw HTML+ updateState $ \state -> state { stateOptions =+ let oldOpts = stateOptions state in+ oldOpts{ readerParseRaw = True } }+ optional titleBlock+ blocks <- parseBlocks+ st <- getState+ let meta = runF (stateMeta' st) st+ meta' <- addScholarlyMeta meta+ let Pandoc _ bs = B.doc $ runF blocks st+ return $ Pandoc meta' bs++addScholarlyMeta :: Meta -> MarkdownParser Meta+addScholarlyMeta meta = do+ st <- getState+ exts <- getOption readerExtensions+ let setMacros = if (not $ null $ stateMathDefs st)+ then B.setMeta "latexMacrosForMath" (MetaString $ stateMathDefs st)+ else id+ let setMathIds = if (not $ null $ idsForMath $ stateXRefIdents st)+ then B.setMeta "identifiersForMath"+ (map (\x -> MetaString x) $ idsForMath $ stateXRefIdents st)+ else id+ case (Set.member Ext_scholarly_markdown exts) of+ True -> return $ setMacros . setMathIds $ meta+ False -> return meta++addWarning :: Maybe SourcePos -> String -> MarkdownParser ()+addWarning mbpos msg =+ updateState $ \st -> st{+ stateWarnings = (msg ++ maybe "" (\pos -> " " ++ show pos) mbpos) :+ stateWarnings st }++referenceKey :: MarkdownParser (F Blocks)+referenceKey = try $ do+ pos <- getPosition+ skipNonindentSpaces+ (_,raw) <- reference+ char ':'+ skipSpaces >> optional newline >> skipSpaces >> notFollowedBy (char '[')+ let sourceURL = liftM unwords $ many $ try $ do+ skipMany spaceChar+ notFollowedBy' referenceTitle+ notFollowedBy' (() <$ reference)+ many1 $ notFollowedBy space >> litChar+ let betweenAngles = try $ char '<' >> manyTill litChar (char '>')+ src <- try betweenAngles <|> sourceURL+ tit <- option "" referenceTitle+ -- currently we just ignore MMD-style link/image attributes+ _kvs <- option [] $ guardEnabled Ext_link_attributes+ >> many (try $ spnl >> keyValAttr)+ blanklines+ let target = (escapeURI $ trimr src, tit)+ st <- getState+ let oldkeys = stateKeys st+ let key = toKey raw+ case M.lookup key oldkeys of+ Just _ -> addWarning (Just pos) $ "Duplicate link reference `" ++ raw ++ "'"+ Nothing -> return ()+ updateState $ \s -> s { stateKeys = M.insert key target oldkeys }+ return $ return mempty++referenceTitle :: MarkdownParser String+referenceTitle = try $ do+ skipSpaces >> optional newline >> skipSpaces+ quotedTitle '"' <|> quotedTitle '\'' <|> charsInBalanced '(' ')' litChar++-- A link title in quotes+quotedTitle :: Char -> MarkdownParser String+quotedTitle c = try $ do+ char c+ notFollowedBy spaces+ let pEnder = try $ char c >> notFollowedBy (satisfy isAlphaNum)+ let regChunk = many1 (noneOf ['\\','\n','&',c]) <|> count 1 litChar+ let nestedChunk = (\x -> [c] ++ x ++ [c]) <$> quotedTitle c+ unwords . words . concat <$> manyTill (nestedChunk <|> regChunk) pEnder++-- | PHP Markdown Extra style abbreviation key. Currently+-- we just skip them, since Pandoc doesn't have an element for+-- an abbreviation.+abbrevKey :: MarkdownParser (F Blocks)+abbrevKey = do+ guardEnabled Ext_abbreviations+ try $ do+ char '*'+ reference+ char ':'+ skipMany (satisfy (/= '\n'))+ blanklines+ return $ return mempty++noteMarker :: MarkdownParser String+noteMarker = string "[^" >> many1Till (satisfy $ not . isBlank) (char ']')++rawLine :: MarkdownParser String+rawLine = try $ do+ notFollowedBy blankline+ notFollowedBy' $ try $ skipNonindentSpaces >> noteMarker+ optional indentSpaces+ anyLine++rawLines :: MarkdownParser String+rawLines = do+ first <- anyLine+ rest <- many rawLine+ return $ unlines (first:rest)++noteBlock :: MarkdownParser (F Blocks)+noteBlock = try $ do+ pos <- getPosition+ skipNonindentSpaces+ ref <- noteMarker+ char ':'+ optional blankline+ optional indentSpaces+ first <- rawLines+ rest <- many $ try $ blanklines >> indentSpaces >> rawLines+ let raw = unlines (first:rest) ++ "\n"+ optional blanklines+ parsed <- parseFromString parseBlocks raw+ let newnote = (ref, parsed)+ oldnotes <- stateNotes' <$> getState+ case lookup ref oldnotes of+ Just _ -> addWarning (Just pos) $ "Duplicate note reference `" ++ ref ++ "'"+ Nothing -> return ()+ updateState $ \s -> s { stateNotes' = newnote : oldnotes }+ return mempty++--+-- parsing blocks+--++parseBlocks :: MarkdownParser (F Blocks)+parseBlocks = mconcat <$> manyTill block eof++block :: MarkdownParser (F Blocks)+block = do+ tr <- getOption readerTrace+ pos <- getPosition+ res <- choice [ mempty <$ blanklines+ , scholarlyFigure -- scholmd floats include code blocks+ , codeBlockFenced+ , yamlMetaBlock+ , guardEnabled Ext_latex_macros *> (macro >>= return . return)+ -- note: bulletList needs to be before header because of+ -- the possibility of empty list items: -+ , bulletList+ , scholarlyAbstract+ , header+ , lhsCodeBlock+ , rawTeXBlock+ , divHtml+ , htmlBlock+ , table+ , lineBlock+ , codeBlockIndented+ , blockQuote+ , hrule+ , orderedList+ , definitionList+ , noteBlock+ , referenceKey+ , abbrevKey+ , para+ , plain+ ] <?> "block"+ when tr $ do+ st <- getState+ trace (printf "line %d: %s" (sourceLine pos)+ (take 60 $ show $ B.toList $ runF res st)) (return ())+ return res++--+-- header blocks+--++header :: MarkdownParser (F Blocks)+header = setextHeader <|> atxHeader <?> "header"++atxHeader :: MarkdownParser (F Blocks)+atxHeader = try $ do+ level <- many1 (char '#') >>= return . length+ notFollowedBy $ guardEnabled Ext_fancy_lists >>+ (char '.' <|> char ')') -- this would be a list+ skipSpaces+ text <- trimInlinesF . mconcat <$> many (notFollowedBy atxClosing >> inline)+ attr <- atxClosing+ attr' <- registerHeader attr (runF text defaultParserState)+ return $ B.headerWith attr' level <$> text++atxClosing :: MarkdownParser Attr+atxClosing = try $ do+ attr' <- option nullAttr+ (guardEnabled Ext_mmd_header_identifiers >> mmdHeaderIdentifier)+ skipMany (char '#')+ skipSpaces+ attr <- option attr'+ (guardEnabled Ext_header_attributes >> attributes)+ blanklines+ return attr++setextHeaderEnd :: MarkdownParser Attr+setextHeaderEnd = try $ do+ attr <- option nullAttr+ $ (guardEnabled Ext_mmd_header_identifiers >> mmdHeaderIdentifier)+ <|> (guardEnabled Ext_header_attributes >> attributes)+ blanklines+ return attr++mmdHeaderIdentifier :: MarkdownParser Attr+mmdHeaderIdentifier = do+ ident <- stripFirstAndLast . snd <$> reference+ skipSpaces+ return (ident,[],[])++setextHeader :: MarkdownParser (F Blocks)+setextHeader = try $ do+ -- This lookahead prevents us from wasting time parsing Inlines+ -- unless necessary -- it gives a significant performance boost.+ lookAhead $ anyLine >> many1 (oneOf setextHChars) >> blankline+ text <- trimInlinesF . mconcat <$> many1 (notFollowedBy setextHeaderEnd >> inline)+ attr <- setextHeaderEnd+ underlineChar <- oneOf setextHChars+ many (char underlineChar)+ blanklines+ let level = (fromMaybe 0 $ findIndex (== underlineChar) setextHChars) + 1+ attr' <- registerHeader attr (runF text defaultParserState)+ return $ B.headerWith attr' level <$> text++--+-- hrule block+--++hrule :: Parser [Char] st (F Blocks)+hrule = try $ do+ skipSpaces+ start <- satisfy isHruleChar+ count 2 (skipSpaces >> char start)+ skipMany (spaceChar <|> char start)+ newline+ optional blanklines+ return $ return B.horizontalRule++--+-- code blocks+--++indentedLine :: MarkdownParser String+indentedLine = indentSpaces >> anyLine >>= return . (++ "\n")++blockDelimiter :: (Char -> Bool)+ -> Maybe Int+ -> Parser [Char] st Int+blockDelimiter f len = try $ do+ c <- lookAhead (satisfy f)+ case len of+ Just l -> count l (char c) >> many (char c) >> return l+ Nothing -> count 3 (char c) >> many (char c) >>=+ return . (+ 3) . length++attributes :: MarkdownParser Attr+attributes = try $ do+ char '{'+ spnl+ attrs <- many (attribute <* spnl)+ char '}'+ return $ foldl (\x f -> f x) nullAttr attrs++attribute :: MarkdownParser (Attr -> Attr)+attribute = identifierAttr <|> classAttr <|> keyValAttr <|> specialAttr++identifier :: MarkdownParser String+identifier = do+ first <- letter+ rest <- many $ alphaNum <|> oneOf "-_:."+ return (first:rest)++identifierAttr :: MarkdownParser (Attr -> Attr)+identifierAttr = try $ do+ char '#'+ result <- identifier+ return $ \(_,cs,kvs) -> (result,cs,kvs)++classAttr :: MarkdownParser (Attr -> Attr)+classAttr = try $ do+ char '.'+ result <- identifier+ return $ \(id',cs,kvs) -> (id',cs ++ [result],kvs)++keyValAttr :: MarkdownParser (Attr -> Attr)+keyValAttr = try $ do+ key <- identifier+ char '='+ val <- enclosed (char '"') (char '"') litChar+ <|> enclosed (char '\'') (char '\'') litChar+ <|> many (escapedChar' <|> noneOf " \t\n\r}")+ return $ \(id',cs,kvs) -> (id',cs,kvs ++ [(key,val)])++specialAttr :: MarkdownParser (Attr -> Attr)+specialAttr = do+ char '-'+ return $ \(id',cs,kvs) -> (id',cs ++ ["unnumbered"],kvs)++codeBlockFenced :: MarkdownParser (F Blocks)+codeBlockFenced = try $ do+ (attr, contents) <- codeBlockFenced'+ blanklines+ return $ return $ B.codeBlockWith attr contents++-- Does not parse blanklines afterward+codeBlockFenced' :: MarkdownParser (Attr, String)+codeBlockFenced' = try $ do+ c <- try (guardEnabled Ext_fenced_code_blocks >> lookAhead (char '~'))+ <|> (guardEnabled Ext_backtick_code_blocks >> lookAhead (char '`'))+ size <- blockDelimiter (== c) Nothing+ skipMany spaceChar+ attr <- option ([],[],[]) $+ try (guardEnabled Ext_fenced_code_attributes >> attributes)+ <|> ((\x -> ("",[toLanguageId x],[])) <$> many1 nonspaceChar)+ guard $ not (classIsMath attr)+ blankline+ contents <- manyTill anyLine (blockDelimiter (== c) (Just size))+ blankline+ return (attr, intercalate "\n" contents)++-- correctly handle github language identifiers+toLanguageId :: String -> String+toLanguageId = map toLower . go+ where go "c++" = "cpp"+ go "objective-c" = "objectivec"+ go x = x++codeBlockIndented :: MarkdownParser (F Blocks)+codeBlockIndented = do+ (attr, contents) <- codeBlockIndented'+ optional blanklines+ return $ return $ B.codeBlockWith attr contents++-- Does not parse blanklines afterward+codeBlockIndented' :: MarkdownParser (Attr, String)+codeBlockIndented' = do+ contents <- many1 (indentedLine <|>+ try (do b <- blanklines+ l <- indentedLine+ return $ b ++ l))+ classes <- getOption readerIndentedCodeClasses+ return (("", classes, []), stripTrailingNewlines $ concat contents)++lhsCodeBlock :: MarkdownParser (F Blocks)+lhsCodeBlock = do+ guardEnabled Ext_literate_haskell+ (return . B.codeBlockWith ("",["sourceCode","literate","haskell"],[]) <$>+ (lhsCodeBlockBird <|> lhsCodeBlockLaTeX))+ <|> (return . B.codeBlockWith ("",["sourceCode","haskell"],[]) <$>+ lhsCodeBlockInverseBird)++lhsCodeBlockLaTeX :: MarkdownParser String+lhsCodeBlockLaTeX = try $ do+ string "\\begin{code}"+ manyTill spaceChar newline+ contents <- many1Till anyChar (try $ string "\\end{code}")+ blanklines+ return $ stripTrailingNewlines contents++lhsCodeBlockBird :: MarkdownParser String+lhsCodeBlockBird = lhsCodeBlockBirdWith '>'++lhsCodeBlockInverseBird :: MarkdownParser String+lhsCodeBlockInverseBird = lhsCodeBlockBirdWith '<'++lhsCodeBlockBirdWith :: Char -> MarkdownParser String+lhsCodeBlockBirdWith c = try $ do+ pos <- getPosition+ when (sourceColumn pos /= 1) $ fail "Not in first column"+ lns <- many1 $ birdTrackLine c+ -- if (as is normal) there is always a space after >, drop it+ let lns' = if all (\ln -> null ln || take 1 ln == " ") lns+ then map (drop 1) lns+ else lns+ blanklines+ return $ intercalate "\n" lns'++birdTrackLine :: Char -> Parser [Char] st String+birdTrackLine c = try $ do+ char c+ -- allow html tags on left margin:+ when (c == '<') $ notFollowedBy letter+ anyLine++--+-- block quotes+--++emailBlockQuoteStart :: MarkdownParser Char+emailBlockQuoteStart = try $ skipNonindentSpaces >> char '>' <* optional (char ' ')++emailBlockQuote :: MarkdownParser [String]+emailBlockQuote = try $ do+ emailBlockQuoteStart+ let emailLine = many $ nonEndline <|> try+ (endline >> notFollowedBy emailBlockQuoteStart >>+ return '\n')+ let emailSep = try (newline >> emailBlockQuoteStart)+ first <- emailLine+ rest <- many $ try $ emailSep >> emailLine+ let raw = first:rest+ newline <|> (eof >> return '\n')+ optional blanklines+ return raw++blockQuote :: MarkdownParser (F Blocks)+blockQuote = do+ raw <- emailBlockQuote+ -- parse the extracted block, which may contain various block elements:+ contents <- parseFromString parseBlocks $ (intercalate "\n" raw) ++ "\n\n"+ return $ B.blockQuote <$> contents++--+-- list blocks+--++bulletListStart :: MarkdownParser ()+bulletListStart = try $ do+ optional newline -- if preceded by a Plain block in a list context+ startpos <- sourceColumn <$> getPosition+ skipNonindentSpaces+ notFollowedBy' (() <$ hrule) -- because hrules start out just like lists+ satisfy isBulletListMarker+ endpos <- sourceColumn <$> getPosition+ tabStop <- getOption readerTabStop+ lookAhead (newline <|> spaceChar)+ () <$ atMostSpaces (tabStop - (endpos - startpos))++anyOrderedListStart :: MarkdownParser (Int, ListNumberStyle, ListNumberDelim)+anyOrderedListStart = try $ do+ optional newline -- if preceded by a Plain block in a list context+ startpos <- sourceColumn <$> getPosition+ skipNonindentSpaces+ notFollowedBy $ string "p." >> spaceChar >> digit -- page number+ res <- do guardDisabled Ext_fancy_lists+ many1 digit+ char '.'+ return (1, DefaultStyle, DefaultDelim)+ <|> do (num, style, delim) <- anyOrderedListMarker+ -- if it could be an abbreviated first name,+ -- insist on more than one space+ when (delim == Period && (style == UpperAlpha ||+ (style == UpperRoman &&+ num `elem` [1, 5, 10, 50, 100, 500, 1000]))) $+ () <$ spaceChar+ return (num, style, delim)+ endpos <- sourceColumn <$> getPosition+ tabStop <- getOption readerTabStop+ lookAhead (newline <|> spaceChar)+ atMostSpaces (tabStop - (endpos - startpos))+ return res++listStart :: MarkdownParser ()+listStart = bulletListStart <|> (anyOrderedListStart >> return ())++listLine :: MarkdownParser String+listLine = try $ do+ notFollowedBy' (do indentSpaces+ many spaceChar+ listStart)+ notFollowedByHtmlCloser+ optional (() <$ indentSpaces)+ listLineCommon++listLineCommon :: MarkdownParser String+listLineCommon = concat <$> manyTill+ ( many1 (satisfy $ \c -> c /= '\n' && c /= '<')+ <|> liftM snd (htmlTag isCommentTag)+ <|> count 1 anyChar+ ) newline++-- parse raw text for one list item, excluding start marker and continuations+rawListItem :: MarkdownParser a+ -> MarkdownParser String+rawListItem start = try $ do+ start+ first <- listLineCommon+ rest <- many (notFollowedBy listStart >> notFollowedBy blankline >> listLine)+ blanks <- many blankline+ return $ unlines (first:rest) ++ blanks++-- continuation of a list item - indented and separated by blankline+-- or (in compact lists) endline.+-- note: nested lists are parsed as continuations+listContinuation :: MarkdownParser String+listContinuation = try $ do+ lookAhead indentSpaces+ result <- many1 listContinuationLine+ blanks <- many blankline+ return $ concat result ++ blanks++notFollowedByHtmlCloser :: MarkdownParser ()+notFollowedByHtmlCloser = do+ inHtmlBlock <- stateInHtmlBlock <$> getState+ case inHtmlBlock of+ Just t -> notFollowedBy' $ htmlTag (~== TagClose t)+ Nothing -> return ()++listContinuationLine :: MarkdownParser String+listContinuationLine = try $ do+ notFollowedBy blankline+ notFollowedBy' listStart+ notFollowedByHtmlCloser+ optional indentSpaces+ result <- anyLine+ return $ result ++ "\n"++listItem :: MarkdownParser a+ -> MarkdownParser (F Blocks)+listItem start = try $ do+ first <- rawListItem start+ continuations <- many listContinuation+ -- parsing with ListItemState forces markers at beginning of lines to+ -- count as list item markers, even if not separated by blank space.+ -- see definition of "endline"+ state <- getState+ let oldContext = stateParserContext state+ setState $ state {stateParserContext = ListItemState}+ -- parse the extracted block, which may contain various block elements:+ let raw = concat (first:continuations)+ contents <- parseFromString parseBlocks raw+ updateState (\st -> st {stateParserContext = oldContext})+ return contents++orderedList :: MarkdownParser (F Blocks)+orderedList = try $ do+ (start, style, delim) <- lookAhead anyOrderedListStart+ unless (style `elem` [DefaultStyle, Decimal, Example] &&+ delim `elem` [DefaultDelim, Period]) $+ guardEnabled Ext_fancy_lists+ when (style == Example) $ guardEnabled Ext_example_lists+ items <- fmap sequence $ many1 $ listItem+ ( try $ do+ optional newline -- if preceded by Plain block in a list+ startpos <- sourceColumn <$> getPosition+ skipNonindentSpaces+ res <- orderedListMarker style delim+ endpos <- sourceColumn <$> getPosition+ tabStop <- getOption readerTabStop+ lookAhead (newline <|> spaceChar)+ atMostSpaces (tabStop - (endpos - startpos))+ return res )+ start' <- option 1 $ guardEnabled Ext_startnum >> return start+ return $ B.orderedListWith (start', style, delim) <$> fmap compactify' items++bulletList :: MarkdownParser (F Blocks)+bulletList = do+ items <- fmap sequence $ many1 $ listItem bulletListStart+ return $ B.bulletList <$> fmap compactify' items++-- definition lists++defListMarker :: MarkdownParser ()+defListMarker = do+ sps <- nonindentSpaces+ char ':' <|> char '~'+ tabStop <- getOption readerTabStop+ let remaining = tabStop - (length sps + 1)+ if remaining > 0+ then count remaining (char ' ') <|> string "\t"+ else mzero+ return ()++definitionListItem :: Bool -> MarkdownParser (F (Inlines, [Blocks]))+definitionListItem compact = try $ do+ rawLine' <- anyLine+ raw <- many1 $ defRawBlock compact+ term <- parseFromString (trimInlinesF . mconcat <$> many inline) rawLine'+ contents <- mapM (parseFromString parseBlocks) raw+ optional blanklines+ return $ liftM2 (,) term (sequence contents)++defRawBlock :: Bool -> MarkdownParser String+defRawBlock compact = try $ do+ hasBlank <- option False $ blankline >> return True+ defListMarker+ firstline <- anyLine+ let dline = try+ ( do notFollowedBy blankline+ if compact -- laziness not compatible with compact+ then () <$ indentSpaces+ else (() <$ indentSpaces)+ <|> notFollowedBy defListMarker+ anyLine )+ rawlines <- many dline+ cont <- liftM concat $ many $ try $ do+ trailing <- option "" blanklines+ ln <- indentSpaces >> notFollowedBy blankline >> anyLine+ lns <- many dline+ return $ trailing ++ unlines (ln:lns)+ return $ trimr (firstline ++ "\n" ++ unlines rawlines ++ cont) +++ if hasBlank || not (null cont) then "\n\n" else ""++definitionList :: MarkdownParser (F Blocks)+definitionList = try $ do+ lookAhead (anyLine >> optional blankline >> defListMarker)+ compactDefinitionList <|> normalDefinitionList++compactDefinitionList :: MarkdownParser (F Blocks)+compactDefinitionList = do+ guardEnabled Ext_compact_definition_lists+ items <- fmap sequence $ many1 $ definitionListItem True+ return $ B.definitionList <$> fmap compactify'DL items++normalDefinitionList :: MarkdownParser (F Blocks)+normalDefinitionList = do+ guardEnabled Ext_definition_lists+ items <- fmap sequence $ many1 $ definitionListItem False+ return $ B.definitionList <$> items++--+-- paragraph block+--++para :: MarkdownParser (F Blocks)+para = try $ do+ exts <- getOption readerExtensions+ -- the only time Scholarly displayMath doesn't need to begin with newline is at the start of a para+ maybeDisplayMath <- optionMaybe $+ guardEnabled Ext_scholarly_markdown >> scholarlyDisplayMath+ result <- case maybeDisplayMath of+ Just dispMath -> try $ do+ moreInlines <- option mempty (many1 inline)+ return $ trimInlinesF $ dispMath <> (mconcat moreInlines)+ Nothing -> trimInlinesF . mconcat <$> many1 inline+ option (B.plain <$> result)+ $ try $ do+ newline+ (blanklines >> return mempty)+ <|> (guardDisabled Ext_blank_before_blockquote >> () <$ lookAhead blockQuote)+ <|> (guardEnabled Ext_backtick_code_blocks >> () <$ lookAhead codeBlockFenced)+ <|> (guardDisabled Ext_blank_before_header >> () <$ lookAhead header)+ <|> (guardEnabled Ext_lists_without_preceding_blankline >>+ () <$ lookAhead listStart)+ <|> do guardEnabled Ext_native_divs+ inHtmlBlock <- stateInHtmlBlock <$> getState+ case inHtmlBlock of+ Just "div" -> () <$+ lookAhead (htmlTag (~== TagClose "div"))+ _ -> mzero+ return $ do+ result' <- result+ case B.toList result' of+ [Image attr alt (src,tit)]+ | Ext_implicit_figures `Set.member` exts ->+ -- the fig: at beginning of title indicates a figure+ return $ B.para $ B.singleton+ $ Image attr alt (src,'f':'i':'g':':':tit)+ _ -> return $ B.para result'++plain :: MarkdownParser (F Blocks)+plain = fmap B.plain . trimInlinesF . mconcat <$> many1 inline++--+-- raw html+--++htmlElement :: MarkdownParser String+htmlElement = rawVerbatimBlock+ <|> strictHtmlBlock+ <|> liftM snd (htmlTag isBlockTag)++htmlBlock :: MarkdownParser (F Blocks)+htmlBlock = do+ guardEnabled Ext_raw_html+ try (do+ (TagOpen t attrs) <- lookAhead $ fst <$> htmlTag isBlockTag+ (guard (t `elem` ["pre","style","script"]) >>+ (return . B.rawBlock "html") <$> rawVerbatimBlock)+ <|> (do guardEnabled Ext_markdown_attribute+ oldMarkdownAttribute <- stateMarkdownAttribute <$> getState+ markdownAttribute <-+ case lookup "markdown" attrs of+ Just "0" -> False <$ updateState (\st -> st{+ stateMarkdownAttribute = False })+ Just _ -> True <$ updateState (\st -> st{+ stateMarkdownAttribute = True })+ Nothing -> return oldMarkdownAttribute+ res <- if markdownAttribute+ then rawHtmlBlocks+ else htmlBlock'+ updateState $ \st -> st{ stateMarkdownAttribute =+ oldMarkdownAttribute }+ return res)+ <|> (guardEnabled Ext_markdown_in_html_blocks >> rawHtmlBlocks))+ <|> htmlBlock'++htmlBlock' :: MarkdownParser (F Blocks)+htmlBlock' = try $ do+ first <- htmlElement+ skipMany spaceChar+ optional blanklines+ return $ return $ B.rawBlock "html" first++strictHtmlBlock :: MarkdownParser String+strictHtmlBlock = htmlInBalanced (not . isInlineTag)++rawVerbatimBlock :: MarkdownParser String+rawVerbatimBlock = try $ do+ (TagOpen tag _, open) <- htmlTag (tagOpen (flip elem+ ["pre", "style", "script"])+ (const True))+ contents <- manyTill anyChar (htmlTag (~== TagClose tag))+ return $ open ++ contents ++ renderTags' [TagClose tag]++rawTeXBlock :: MarkdownParser (F Blocks)+rawTeXBlock = do+ guardEnabled Ext_raw_tex+ result <- (B.rawBlock "latex" . concat <$>+ rawLaTeXBlock `sepEndBy1` blankline)+ <|> (B.rawBlock "context" . concat <$>+ rawConTeXtEnvironment `sepEndBy1` blankline)+ spaces+ return $ return result++rawHtmlBlocks :: MarkdownParser (F Blocks)+rawHtmlBlocks = do+ (TagOpen tagtype _, raw) <- htmlTag isBlockTag+ -- try to find closing tag+ -- we set stateInHtmlBlock so that closing tags that can be either block or+ -- inline will not be parsed as inline tags+ oldInHtmlBlock <- stateInHtmlBlock <$> getState+ updateState $ \st -> st{ stateInHtmlBlock = Just tagtype }+ let closer = htmlTag (\x -> x ~== TagClose tagtype)+ contents <- mconcat <$> many (notFollowedBy' closer >> block)+ result <-+ (closer >>= \(_, rawcloser) -> return (+ return (B.rawBlock "html" $ stripMarkdownAttribute raw) <>+ contents <>+ return (B.rawBlock "html" rawcloser)))+ <|> return (return (B.rawBlock "html" raw) <> contents)+ updateState $ \st -> st{ stateInHtmlBlock = oldInHtmlBlock }+ return result++-- remove markdown="1" attribute+stripMarkdownAttribute :: String -> String+stripMarkdownAttribute s = renderTags' $ map filterAttrib $ parseTags s+ where filterAttrib (TagOpen t as) = TagOpen t+ [(k,v) | (k,v) <- as, k /= "markdown"]+ filterAttrib x = x++--+-- line block+--++lineBlock :: MarkdownParser (F Blocks)+lineBlock = try $ do+ guardEnabled Ext_line_blocks+ lines' <- lineBlockLines >>=+ mapM (parseFromString (trimInlinesF . mconcat <$> many inline))+ return $ B.para <$> (mconcat $ intersperse (return B.linebreak) lines')++--+-- Tables+--++-- Parse a dashed line with optional trailing spaces; return its length+-- and the length including trailing space.+dashedLine :: Char+ -> Parser [Char] st (Int, Int)+dashedLine ch = do+ dashes <- many1 (char ch)+ sp <- many spaceChar+ return $ (length dashes, length $ dashes ++ sp)++-- Parse a table header with dashed lines of '-' preceded by+-- one (or zero) line of text.+simpleTableHeader :: Bool -- ^ Headerless table+ -> MarkdownParser (F [Blocks], [Alignment], [Int])+simpleTableHeader headless = try $ do+ rawContent <- if headless+ then return ""+ else anyLine+ initSp <- nonindentSpaces+ dashes <- many1 (dashedLine '-')+ newline+ let (lengths, lines') = unzip dashes+ let indices = scanl (+) (length initSp) lines'+ -- If no header, calculate alignment on basis of first row of text+ rawHeads <- liftM (tail . splitStringByIndices (init indices)) $+ if headless+ then lookAhead anyLine+ else return rawContent+ let aligns = zipWith alignType (map (\a -> [a]) rawHeads) lengths+ let rawHeads' = if headless+ then replicate (length dashes) ""+ else rawHeads+ heads <- fmap sequence+ $ mapM (parseFromString (mconcat <$> many plain))+ $ map trim rawHeads'+ return (heads, aligns, indices)++-- Returns an alignment type for a table, based on a list of strings+-- (the rows of the column header) and a number (the length of the+-- dashed line under the rows.+alignType :: [String]+ -> Int+ -> Alignment+alignType [] _ = AlignDefault+alignType strLst len =+ let nonempties = filter (not . null) $ map trimr strLst+ (leftSpace, rightSpace) =+ case sortBy (comparing length) nonempties of+ (x:_) -> (head x `elem` " \t", length x < len)+ [] -> (False, False)+ in case (leftSpace, rightSpace) of+ (True, False) -> AlignRight+ (False, True) -> AlignLeft+ (True, True) -> AlignCenter+ (False, False) -> AlignDefault++-- Parse a table footer - dashed lines followed by blank line.+tableFooter :: MarkdownParser String+tableFooter = try $ skipNonindentSpaces >> many1 (dashedLine '-') >> blanklines++-- Parse a table separator - dashed line.+tableSep :: MarkdownParser Char+tableSep = try $ skipNonindentSpaces >> many1 (dashedLine '-') >> char '\n'++-- Parse a raw line and split it into chunks by indices.+rawTableLine :: [Int]+ -> MarkdownParser [String]+rawTableLine indices = do+ notFollowedBy' (blanklines <|> tableFooter)+ line <- many1Till anyChar newline+ return $ map trim $ tail $+ splitStringByIndices (init indices) line++-- Parse a table line and return a list of lists of blocks (columns).+tableLine :: [Int]+ -> MarkdownParser (F [Blocks])+tableLine indices = rawTableLine indices >>=+ fmap sequence . mapM (parseFromString (mconcat <$> many plain))++-- Parse a multiline table row and return a list of blocks (columns).+multilineRow :: [Int]+ -> MarkdownParser (F [Blocks])+multilineRow indices = do+ colLines <- many1 (rawTableLine indices)+ let cols = map unlines $ transpose colLines+ fmap sequence $ mapM (parseFromString (mconcat <$> many plain)) cols++-- Parses a table caption: inlines beginning with 'Table:'+-- and followed by blank lines.+tableCaption :: MarkdownParser (F Inlines)+tableCaption = try $ do+ guardEnabled Ext_table_captions+ skipNonindentSpaces+ string ":" <|> string "Table:"+ trimInlinesF . mconcat <$> many1 inline <* blanklines++-- Parse a simple table with '---' header and one line per row.+simpleTable :: Bool -- ^ Headerless table+ -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])+simpleTable headless = do+ (aligns, _widths, heads', lines') <-+ tableWith (simpleTableHeader headless) tableLine+ (return ())+ (if headless then tableFooter else tableFooter <|> blanklines)+ -- Simple tables get 0s for relative column widths (i.e., use default)+ return (aligns, replicate (length aligns) 0, heads', lines')++-- Parse a multiline table: starts with row of '-' on top, then header+-- (which may be multiline), then the rows,+-- which may be multiline, separated by blank lines, and+-- ending with a footer (dashed line followed by blank line).+multilineTable :: Bool -- ^ Headerless table+ -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])+multilineTable headless =+ tableWith (multilineTableHeader headless) multilineRow blanklines tableFooter++multilineTableHeader :: Bool -- ^ Headerless table+ -> MarkdownParser (F [Blocks], [Alignment], [Int])+multilineTableHeader headless = try $ do+ unless headless $+ tableSep >> notFollowedBy blankline+ rawContent <- if headless+ then return $ repeat ""+ else many1 $ notFollowedBy tableSep >> anyLine+ initSp <- nonindentSpaces+ dashes <- many1 (dashedLine '-')+ newline+ let (lengths, lines') = unzip dashes+ let indices = scanl (+) (length initSp) lines'+ rawHeadsList <- if headless+ then liftM (map (:[]) . tail .+ splitStringByIndices (init indices)) $ lookAhead anyLine+ else return $ transpose $ map+ (tail . splitStringByIndices (init indices))+ rawContent+ let aligns = zipWith alignType rawHeadsList lengths+ let rawHeads = if headless+ then replicate (length dashes) ""+ else map (unlines . map trim) rawHeadsList+ heads <- fmap sequence $+ mapM (parseFromString (mconcat <$> many plain)) $+ map trim rawHeads+ return (heads, aligns, indices)++-- Parse a grid table: starts with row of '-' on top, then header+-- (which may be grid), then the rows,+-- which may be grid, separated by blank lines, and+-- ending with a footer (dashed line followed by blank line).+gridTable :: Bool -- ^ Headerless table+ -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])+gridTable headless =+ tableWith (gridTableHeader headless) gridTableRow+ (gridTableSep '-') gridTableFooter++gridTableSplitLine :: [Int] -> String -> [String]+gridTableSplitLine indices line = map removeFinalBar $ tail $+ splitStringByIndices (init indices) $ trimr line++gridPart :: Char -> Parser [Char] st (Int, Int)+gridPart ch = do+ dashes <- many1 (char ch)+ char '+'+ return (length dashes, length dashes + 1)++gridDashedLines :: Char -> Parser [Char] st [(Int,Int)]+gridDashedLines ch = try $ char '+' >> many1 (gridPart ch) <* blankline++removeFinalBar :: String -> String+removeFinalBar =+ reverse . dropWhile (`elem` " \t") . dropWhile (=='|') . reverse++-- | Separator between rows of grid table.+gridTableSep :: Char -> MarkdownParser Char+gridTableSep ch = try $ gridDashedLines ch >> return '\n'++-- | Parse header for a grid table.+gridTableHeader :: Bool -- ^ Headerless table+ -> MarkdownParser (F [Blocks], [Alignment], [Int])+gridTableHeader headless = try $ do+ optional blanklines+ dashes <- gridDashedLines '-'+ rawContent <- if headless+ then return $ repeat ""+ else many1+ (notFollowedBy (gridTableSep '=') >> char '|' >>+ many1Till anyChar newline)+ if headless+ then return ()+ else gridTableSep '=' >> return ()+ let lines' = map snd dashes+ let indices = scanl (+) 0 lines'+ let aligns = replicate (length lines') AlignDefault+ -- RST does not have a notion of alignments+ let rawHeads = if headless+ then replicate (length dashes) ""+ else map (unlines . map trim) $ transpose+ $ map (gridTableSplitLine indices) rawContent+ heads <- fmap sequence $ mapM (parseFromString parseBlocks . trim) rawHeads+ return (heads, aligns, indices)++gridTableRawLine :: [Int] -> MarkdownParser [String]+gridTableRawLine indices = do+ char '|'+ line <- many1Till anyChar newline+ return (gridTableSplitLine indices line)++-- | Parse row of grid table.+gridTableRow :: [Int]+ -> MarkdownParser (F [Blocks])+gridTableRow indices = do+ colLines <- many1 (gridTableRawLine indices)+ let cols = map ((++ "\n") . unlines . removeOneLeadingSpace) $+ transpose colLines+ fmap compactify' <$> fmap sequence (mapM (parseFromString parseBlocks) cols)++removeOneLeadingSpace :: [String] -> [String]+removeOneLeadingSpace xs =+ if all startsWithSpace xs+ then map (drop 1) xs+ else xs+ where startsWithSpace "" = True+ startsWithSpace (y:_) = y == ' '++-- | Parse footer for a grid table.+gridTableFooter :: MarkdownParser [Char]+gridTableFooter = blanklines++pipeBreak :: MarkdownParser [Alignment]+pipeBreak = try $ do+ nonindentSpaces+ openPipe <- (True <$ char '|') <|> return False+ first <- pipeTableHeaderPart+ rest <- many $ sepPipe *> pipeTableHeaderPart+ -- surrounding pipes needed for a one-column table:+ guard $ not (null rest && not openPipe)+ optional (char '|')+ blankline+ return (first:rest)++pipeTable :: MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])+pipeTable = try $ do+ (heads,aligns) <- try ( pipeBreak >>= \als ->+ return (return $ replicate (length als) mempty, als))+ <|> ( pipeTableRow >>= \row -> pipeBreak >>= \als ->++ return (row, als) )+ lines' <- sequence <$> many1 pipeTableRow+ let widths = replicate (length aligns) 0.0+ return $ (aligns, widths, heads, lines')++sepPipe :: MarkdownParser ()+sepPipe = try $ do+ char '|' <|> char '+'+ notFollowedBy blankline++-- parse a row, also returning probable alignments for org-table cells+pipeTableRow :: MarkdownParser (F [Blocks])+pipeTableRow = do+ nonindentSpaces+ openPipe <- (True <$ char '|') <|> return False+ let cell = mconcat <$>+ many (notFollowedBy (blankline <|> char '|') >> inline)+ first <- cell+ rest <- many $ sepPipe *> cell+ -- surrounding pipes needed for a one-column table:+ guard $ not (null rest && not openPipe)+ optional (char '|')+ blankline+ let cells = sequence (first:rest)+ return $ do+ cells' <- cells+ return $ map+ (\ils ->+ case trimInlines ils of+ ils' | B.isNull ils' -> mempty+ | otherwise -> B.plain $ ils') cells'++pipeTableHeaderPart :: Parser [Char] st Alignment+pipeTableHeaderPart = try $ do+ skipMany spaceChar+ left <- optionMaybe (char ':')+ many1 (char '-')+ right <- optionMaybe (char ':')+ skipMany spaceChar+ return $+ case (left,right) of+ (Nothing,Nothing) -> AlignDefault+ (Just _,Nothing) -> AlignLeft+ (Nothing,Just _) -> AlignRight+ (Just _,Just _) -> AlignCenter++-- Succeed only if current line contains a pipe.+scanForPipe :: Parser [Char] st ()+scanForPipe = do+ inp <- getInput+ case break (\c -> c == '\n' || c == '|') inp of+ (_,'|':_) -> return ()+ _ -> mzero++-- | Parse a table using 'headerParser', 'rowParser',+-- 'lineParser', and 'footerParser'. Variant of the version in+-- Text.Pandoc.Parsing.+tableWith :: MarkdownParser (F [Blocks], [Alignment], [Int])+ -> ([Int] -> MarkdownParser (F [Blocks]))+ -> MarkdownParser sep+ -> MarkdownParser end+ -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])+tableWith headerParser rowParser lineParser footerParser = try $ do+ (heads, aligns, indices) <- headerParser+ lines' <- fmap sequence $ rowParser indices `sepEndBy1` lineParser+ footerParser+ numColumns <- getOption readerColumns+ let widths = if (indices == [])+ then replicate (length aligns) 0.0+ else widthsFromIndices numColumns indices+ return $ (aligns, widths, heads, lines')++table :: MarkdownParser (F Blocks)+table = try $ do+ frontCaption <- option Nothing (Just <$> tableCaption)+ (aligns, widths, heads, lns) <-+ try (guardEnabled Ext_pipe_tables >> scanForPipe >> pipeTable) <|>+ try (guardEnabled Ext_multiline_tables >>+ multilineTable False) <|>+ try (guardEnabled Ext_simple_tables >>+ (simpleTable True <|> simpleTable False)) <|>+ try (guardEnabled Ext_multiline_tables >>+ multilineTable True) <|>+ try (guardEnabled Ext_grid_tables >>+ (gridTable False <|> gridTable True)) <?> "table"+ optional blanklines+ caption <- case frontCaption of+ Nothing -> option (return mempty) tableCaption+ Just c -> return c+ return $ do+ caption' <- caption+ heads' <- heads+ lns' <- lns+ return $ B.table caption' (zip aligns widths) heads' lns'++--+-- inline+--++inline :: MarkdownParser (F Inlines)+inline = choice [ scholarlyMath -- before endline and whitespace to detect el+ , whitespace+ , bareURL+ , str+ , endline+ , code+ , strongOrEmph+ , note+ , scholarlyXRef -- before links to avoid it being parsed+ , cite+ , link+ , image+ , math+ , strikeout+ , subscript+ , superscript+ , inlineNote -- after superscript because of ^[link](/foo)^+ , autoLink+ , spanHtml+ , rawHtmlInline+ , escapedChar+ , rawLaTeXInline'+ , exampleRef+ , smart+ , return . B.singleton <$> charRef+ , symbol+ , ltSign+ ] <?> "inline"++escapedChar' :: MarkdownParser Char+escapedChar' = try $ do+ char '\\'+ (guardEnabled Ext_all_symbols_escapable >> satisfy (not . isAlphaNum))+ <|> oneOf "\\`*_{}[]()>#+-.!~\""++escapedChar :: MarkdownParser (F Inlines)+escapedChar = do+ result <- escapedChar'+ case result of+ ' ' -> return $ return $ B.str "\160" -- "\ " is a nonbreaking space+ '\n' -> guardEnabled Ext_escaped_line_breaks >>+ return (return B.linebreak) -- "\[newline]" is a linebreak+ _ -> return $ return $ B.str [result]++ltSign :: MarkdownParser (F Inlines)+ltSign = do+ guardDisabled Ext_raw_html+ <|> (notFollowedByHtmlCloser >> notFollowedBy' (htmlTag isBlockTag))+ char '<'+ return $ return $ B.str "<"++exampleRef :: MarkdownParser (F Inlines)+exampleRef = try $ do+ guardEnabled Ext_example_lists+ char '@'+ lab <- many1 (alphaNum <|> oneOf "-_")+ return $ do+ st <- askF+ return $ case M.lookup lab (stateExamples st) of+ Just n -> B.str (show n)+ Nothing -> B.str ('@':lab)++symbol :: MarkdownParser (F Inlines)+symbol = do+ result <- noneOf "<\\\n\t "+ <|> try (do lookAhead $ char '\\'+ notFollowedBy' (() <$ rawTeXBlock)+ char '\\')+ return $ return $ B.str [result]++-- parses inline code, between n `s and n `s+-- but ignores exactly 2 `s AND NOT followed by whitespace if Ext_scholarly_markdown+-- ignores beginning and trailing spaces except in Scholarly Lineblocks+code :: MarkdownParser (F Inlines)+code = try $ do+ starts <- many1 (char '`')+ codeSkipSpace+ result <- many1Till (many1 (noneOf "`\n") <|> many1 (char '`') <|>+ (char '\n' >> notFollowedBy' blankline >> return " "))+ (try (codeSkipSpace >> count (length starts) (char '`') >>+ notFollowedBy (char '`')))+ attr <- option ([],[],[]) (try $ guardEnabled Ext_inline_code_attributes >>+ optional whitespace >> attributes)+ resultStr <- codeTrim $ concat result+ return $ return $ B.codeWith attr resultStr++codeSkipSpace :: MarkdownParser ()+codeSkipSpace = do+ st <- getState+ case stateKeepSpacing st of+ True -> return ()+ False -> skipSpaces++codeTrim :: [Char] -> MarkdownParser [Char]+codeTrim codeStr = do+ st <- getState+ case stateKeepSpacing st of+ True -> return codeStr+ False -> return $ trim codeStr++-- Parses plain inline or display math without additional attributes+math :: MarkdownParser (F Inlines)+math = (return . B.displayMath <$> (mathDisplay >>= applyMacros'))+ <|> (return . B.math <$> (mathInline >>= applyMacros'))++-- Parses material enclosed in *s, **s, _s, or __s.+-- Designed to avoid backtracking.+enclosure :: Char+ -> MarkdownParser (F Inlines)+enclosure c = do+ -- we can't start an enclosure with _ if after a string and+ -- the intraword_underscores extension is enabled:+ guardDisabled Ext_intraword_underscores+ <|> guard (c == '*')+ <|> (guard =<< notAfterString)+ cs <- many1 (char c)+ (return (B.str cs) <>) <$> whitespace+ <|> do+ case length cs of+ 3 -> three c+ 2 -> two c mempty+ 1 -> one c mempty+ _ -> return (return $ B.str cs)++ender :: Char -> Int -> MarkdownParser ()+ender c n = try $ do+ count n (char c)+ guard (c == '*')+ <|> guardDisabled Ext_intraword_underscores+ <|> notFollowedBy alphaNum++-- Parse inlines til you hit one c or a sequence of two cs.+-- If one c, emit emph and then parse two.+-- If two cs, emit strong and then parse one.+-- Otherwise, emit ccc then the results.+three :: Char -> MarkdownParser (F Inlines)+three c = do+ contents <- mconcat <$> many (notFollowedBy (ender c 1) >> inline)+ (ender c 3 >> return ((B.strong . B.emph) <$> contents))+ <|> (ender c 2 >> one c (B.strong <$> contents))+ <|> (ender c 1 >> two c (B.emph <$> contents))+ <|> return (return (B.str [c,c,c]) <> contents)++-- Parse inlines til you hit two c's, and emit strong.+-- If you never do hit two cs, emit ** plus inlines parsed.+two :: Char -> F Inlines -> MarkdownParser (F Inlines)+two c prefix' = do+ contents <- mconcat <$> many (try $ notFollowedBy (ender c 2) >> inline)+ (ender c 2 >> return (B.strong <$> (prefix' <> contents)))+ <|> return (return (B.str [c,c]) <> (prefix' <> contents))++-- Parse inlines til you hit a c, and emit emph.+-- If you never hit a c, emit * plus inlines parsed.+one :: Char -> F Inlines -> MarkdownParser (F Inlines)+one c prefix' = do+ contents <- mconcat <$> many ( (notFollowedBy (ender c 1) >> inline)+ <|> try (string [c,c] >>+ notFollowedBy (ender c 1) >>+ two c mempty) )+ (ender c 1 >> return (B.emph <$> (prefix' <> contents)))+ <|> return (return (B.str [c]) <> (prefix' <> contents))++strongOrEmph :: MarkdownParser (F Inlines)+strongOrEmph = enclosure '*' <|> enclosure '_'++-- | Parses a list of inlines between start and end delimiters.+inlinesBetween :: (Show b)+ => MarkdownParser a+ -> MarkdownParser b+ -> MarkdownParser (F Inlines)+inlinesBetween start end =+ (trimInlinesF . mconcat) <$> try (start >> many1Till inner end)+ where inner = innerSpace <|> (notFollowedBy' (() <$ whitespace) >> inline)+ innerSpace = try $ whitespace <* notFollowedBy' end++strikeout :: MarkdownParser (F Inlines)+strikeout = fmap B.strikeout <$>+ (guardEnabled Ext_strikeout >> inlinesBetween strikeStart strikeEnd)+ where strikeStart = string "~~" >> lookAhead nonspaceChar+ >> notFollowedBy (char '~')+ strikeEnd = try $ string "~~"++superscript :: MarkdownParser (F Inlines)+superscript = fmap B.superscript <$> try (do+ guardEnabled Ext_superscript+ char '^'+ mconcat <$> many1Till (notFollowedBy spaceChar >> inline) (char '^'))++subscript :: MarkdownParser (F Inlines)+subscript = fmap B.subscript <$> try (do+ guardEnabled Ext_subscript+ char '~'+ mconcat <$> many1Till (notFollowedBy spaceChar >> inline) (char '~'))++whitespace :: MarkdownParser (F Inlines)+whitespace = spaceChar >> return <$> (lb <|> nbsp <|> regsp) <?> "whitespace"+ where lb = try (spaceChar >> skipMany spaceChar >> endline >> return B.linebreak)+ regsp = try (skipMany spaceChar >> return B.space)+ nbsp = try $ do+ st <- getState+ guard (stateKeepSpacing st)+ spList <- many spaceChar+ return $ B.str $ replicate ((length spList) + 1) '\160'++nonEndline :: Parser [Char] st Char+nonEndline = satisfy (/='\n')++str :: MarkdownParser (F Inlines)+str = do+ result <- many1 alphaNum+ updateLastStrPos+ let spacesToNbr = map (\c -> if c == ' ' then '\160' else c)+ isSmart <- getOption readerSmart+ if isSmart+ then case likelyAbbrev result of+ [] -> return $ return $ B.str result+ xs -> choice (map (\x ->+ try (string x >> oneOf " \n" >>+ lookAhead alphaNum >>+ return (return $ B.str+ $ result ++ spacesToNbr x ++ "\160"))) xs)+ <|> (return $ return $ B.str result)+ else return $ return $ B.str result++-- | if the string matches the beginning of an abbreviation (before+-- the first period, return strings that would finish the abbreviation.+likelyAbbrev :: String -> [String]+likelyAbbrev x =+ let abbrevs = [ "Mr.", "Mrs.", "Ms.", "Capt.", "Dr.", "Prof.",+ "Gen.", "Gov.", "e.g.", "i.e.", "Sgt.", "St.",+ "vol.", "vs.", "Sen.", "Rep.", "Pres.", "Hon.",+ "Rev.", "Ph.D.", "M.D.", "M.A.", "p.", "pp.",+ "ch.", "sec.", "cf.", "cp."]+ abbrPairs = map (break (=='.')) abbrevs+ in map snd $ filter (\(y,_) -> y == x) abbrPairs++-- an endline character that can be treated as a space, not a structural break+endline :: MarkdownParser (F Inlines)+endline = try $ do+ newline+ notFollowedBy blankline+ -- parse potential list-starts differently if in a list:+ st <- getState+ when (stateParserContext st == ListItemState) $ notFollowedBy listStart+ guardDisabled Ext_lists_without_preceding_blankline <|> notFollowedBy listStart+ guardEnabled Ext_blank_before_blockquote <|> notFollowedBy emailBlockQuoteStart+ guardEnabled Ext_blank_before_header <|> notFollowedBy (char '#') -- atx header+ guardDisabled Ext_backtick_code_blocks <|>+ notFollowedBy (() <$ (lookAhead (char '`') >> codeBlockFenced))+ notFollowedByHtmlCloser+ (eof >> return mempty)+ <|> (guardEnabled Ext_hard_line_breaks >> return (return B.linebreak))+ <|> (guardEnabled Ext_ignore_line_breaks >> return mempty)+ <|> (return $ return B.space)++--+-- links+--++-- a reference label for a link+reference :: MarkdownParser (F Inlines, String)+reference = do notFollowedBy' (string "[^") -- footnote reference+ withRaw $ trimInlinesF <$> inlinesInBalancedBrackets++parenthesizedChars :: MarkdownParser [Char]+parenthesizedChars = do+ result <- charsInBalanced '(' ')' litChar+ return $ '(' : result ++ ")"++-- source for a link, with optional title+source :: MarkdownParser (String, String)+source = do+ char '('+ skipSpaces+ let urlChunk =+ try parenthesizedChars+ <|> (notFollowedBy (oneOf " )") >> (count 1 litChar))+ <|> try (many1 spaceChar <* notFollowedBy (oneOf "\"')"))+ let sourceURL = (unwords . words . concat) <$> many urlChunk+ let betweenAngles = try $+ char '<' >> manyTill litChar (char '>')+ src <- try betweenAngles <|> sourceURL+ tit <- option "" $ try $ spnl >> linkTitle+ skipSpaces+ char ')'+ return (escapeURI $ trimr src, tit)++linkTitle :: MarkdownParser String+linkTitle = quotedTitle '"' <|> quotedTitle '\''++link :: MarkdownParser (F Inlines)+link = try $ do+ st <- getState+ guard $ stateAllowLinks st+ setState $ st{ stateAllowLinks = False }+ (lab,raw) <- reference+ setState $ st{ stateAllowLinks = True }+ let constructor _ = B.link+ regLink constructor lab <|> referenceLink constructor (lab,raw)++regLink :: (Attr -> String -> String -> Inlines -> Inlines)+ -> F Inlines -> MarkdownParser (F Inlines)+regLink constructor lab = try $ do+ (src, tit) <- source+ attr <- option nullAttr attributes+ return $ constructor attr src tit <$> lab++-- a link like [this][ref] or [this][] or [this]+referenceLink :: (Attr -> String -> String -> Inlines -> Inlines)+ -> (F Inlines, String) -> MarkdownParser (F Inlines)+referenceLink constructor (lab, raw) = do+ sp <- (True <$ lookAhead (char ' ')) <|> return False+ (ref,raw') <- try+ (skipSpaces >> optional (newline >> skipSpaces) >> reference)+ <|> return (mempty, "")+ attr <- option nullAttr attributes+ let labIsRef = raw' == "" || raw' == "[]"+ let key = toKey $ if labIsRef then raw else raw'+ parsedRaw <- parseFromString (mconcat <$> many inline) raw'+ fallback <- parseFromString (mconcat <$> many inline) $ dropBrackets raw+ implicitHeaderRefs <- option False $+ True <$ guardEnabled Ext_implicit_header_references+ let makeFallback = do+ parsedRaw' <- parsedRaw+ fallback' <- fallback+ return $ B.str "[" <> fallback' <> B.str "]" <>+ (if sp && not (null raw) then B.space else mempty) <>+ parsedRaw'+ return $ do+ keys <- asksF stateKeys+ case M.lookup key keys of+ Nothing -> do+ headers <- asksF stateHeaders+ ref' <- if labIsRef then lab else ref+ if implicitHeaderRefs+ then case M.lookup ref' headers of+ Just ident -> constructor attr ('#':ident) "" <$> lab+ Nothing -> makeFallback+ else makeFallback+ Just (src,tit) -> constructor attr src tit <$> lab++dropBrackets :: String -> String+dropBrackets = reverse . dropRB . reverse . dropLB+ where dropRB (']':xs) = xs+ dropRB xs = xs+ dropLB ('[':xs) = xs+ dropLB xs = xs++bareURL :: MarkdownParser (F Inlines)+bareURL = try $ do+ guardEnabled Ext_autolink_bare_uris+ (orig, src) <- uri <|> emailAddress+ notFollowedBy $ try $ spaces >> htmlTag (~== TagClose "a")+ return $ return $ B.link src "" (B.str orig)++autoLink :: MarkdownParser (F Inlines)+autoLink = try $ do+ char '<'+ (orig, src) <- uri <|> emailAddress+ -- in rare cases, something may remain after the uri parser+ -- is finished, because the uri parser tries to avoid parsing+ -- final punctuation. for example: in `<http://hi---there>`,+ -- the URI parser will stop before the dashes.+ extra <- fromEntities <$> manyTill nonspaceChar (char '>')+ return $ return $ B.link (src ++ escapeURI extra) "" (B.str $ orig ++ extra)++image :: MarkdownParser (F Inlines)+image = try $ do+ char '!'+ (lab,raw) <- reference+ defaultExt <- getOption readerDefaultImageExtension+ let builder = B.imageWith+ let constructor attr src = case takeExtension src of+ "" -> builder attr (addExtension src defaultExt)+ _ -> builder attr src+ regLink constructor lab <|> referenceLink constructor (lab,raw)++note :: MarkdownParser (F Inlines)+note = try $ do+ guardEnabled Ext_footnotes+ ref <- noteMarker+ return $ do+ notes <- asksF stateNotes'+ case lookup ref notes of+ Nothing -> return $ B.str $ "[^" ++ ref ++ "]"+ Just contents -> do+ st <- askF+ -- process the note in a context that doesn't resolve+ -- notes, to avoid infinite looping with notes inside+ -- notes:+ let contents' = runF contents st{ stateNotes' = [] }+ return $ B.note contents'++inlineNote :: MarkdownParser (F Inlines)+inlineNote = try $ do+ guardEnabled Ext_inline_notes+ char '^'+ contents <- inlinesInBalancedBrackets+ return $ B.note . B.para <$> contents++rawLaTeXInline' :: MarkdownParser (F Inlines)+rawLaTeXInline' = try $ do+ guardEnabled Ext_raw_tex+ lookAhead $ char '\\' >> notFollowedBy' (string "start") -- context env+ RawInline _ s <- rawLaTeXInline+ return $ return $ B.rawInline "tex" s+ -- "tex" because it might be context or latex++rawConTeXtEnvironment :: Parser [Char] st String+rawConTeXtEnvironment = try $ do+ string "\\start"+ completion <- inBrackets (letter <|> digit <|> spaceChar)+ <|> (many1 letter)+ contents <- manyTill (rawConTeXtEnvironment <|> (count 1 anyChar))+ (try $ string "\\stop" >> string completion)+ return $ "\\start" ++ completion ++ concat contents ++ "\\stop" ++ completion++inBrackets :: (Parser [Char] st Char) -> Parser [Char] st String+inBrackets parser = do+ char '['+ contents <- many parser+ char ']'+ return $ "[" ++ contents ++ "]"++spanHtml :: MarkdownParser (F Inlines)+spanHtml = try $ do+ guardEnabled Ext_native_spans+ (TagOpen _ attrs, _) <- htmlTag (~== TagOpen "span" [])+ contents <- mconcat <$> manyTill inline (htmlTag (~== TagClose "span"))+ let ident = fromMaybe "" $ lookup "id" attrs+ let classes = maybe [] words $ lookup "class" attrs+ let keyvals = [(k,v) | (k,v) <- attrs, k /= "id" && k /= "class"]+ case lookup "style" keyvals of+ Just s | null ident && null classes &&+ map toLower (filter (`notElem` " \t;") s) ==+ "font-variant:small-caps"+ -> return $ B.smallcaps <$> contents+ _ -> return $ B.spanWith (ident, classes, keyvals) <$> contents++divHtml :: MarkdownParser (F Blocks)+divHtml = try $ do+ guardEnabled Ext_native_divs+ (TagOpen _ attrs, rawtag) <- htmlTag (~== TagOpen "div" [])+ -- we set stateInHtmlBlock so that closing tags that can be either block or+ -- inline will not be parsed as inline tags+ oldInHtmlBlock <- stateInHtmlBlock <$> getState+ updateState $ \st -> st{ stateInHtmlBlock = Just "div" }+ bls <- option "" (blankline >> option "" blanklines)+ contents <- mconcat <$>+ many (notFollowedBy' (htmlTag (~== TagClose "div")) >> block)+ closed <- option False (True <$ htmlTag (~== TagClose "div"))+ if closed+ then do+ updateState $ \st -> st{ stateInHtmlBlock = oldInHtmlBlock }+ let ident = fromMaybe "" $ lookup "id" attrs+ let classes = maybe [] words $ lookup "class" attrs+ let keyvals = [(k,v) | (k,v) <- attrs, k /= "id" && k /= "class"]+ return $ B.divWith (ident, classes, keyvals) <$> contents+ else -- avoid backtracing+ return $ return (B.rawBlock "html" (rawtag <> bls)) <> contents++rawHtmlInline :: MarkdownParser (F Inlines)+rawHtmlInline = do+ guardEnabled Ext_raw_html+ inHtmlBlock <- stateInHtmlBlock <$> getState+ let isCloseBlockTag t = case inHtmlBlock of+ Just t' -> t ~== TagClose t'+ Nothing -> False+ mdInHtml <- option False $+ ( guardEnabled Ext_markdown_in_html_blocks+ <|> guardEnabled Ext_markdown_attribute+ ) >> return True+ (_,result) <- htmlTag $ if mdInHtml+ then (\x -> isInlineTag x &&+ not (isCloseBlockTag x))+ else not . isTextTag+ return $ return $ B.rawInline "html" result++-- Citations++cite :: MarkdownParser (F Inlines)+cite = do+ guardEnabled Ext_citations+ citations <- textualCite+ <|> do (cs, raw) <- withRaw normalCite+ return $ (flip B.cite (B.text raw)) <$> cs+ return citations++textualCite :: MarkdownParser (F Inlines)+textualCite = try $ do+ (_, key) <- citeKey+ let first = Citation{ citationId = key+ , citationPrefix = []+ , citationSuffix = []+ , citationMode = AuthorInText+ , citationNoteNum = 0+ , citationHash = 0+ }+ mbrest <- option Nothing $ try $ spnl >> Just <$> withRaw normalCite+ case mbrest of+ Just (rest, raw) ->+ return $ (flip B.cite (B.text $ '@':key ++ " " ++ raw) . (first:))+ <$> rest+ Nothing ->+ (do (cs, raw) <- withRaw $ bareloc first+ return $ (flip B.cite (B.text $ '@':key ++ " " ++ raw)) <$> cs)+ <|> return (do st <- askF+ return $ case M.lookup key (stateExamples st) of+ Just n -> B.str (show n)+ _ -> B.cite [first] $ B.str $ '@':key)++bareloc :: Citation -> MarkdownParser (F [Citation])+bareloc c = try $ do+ spnl+ char '['+ suff <- suffix+ rest <- option (return []) $ try $ char ';' >> citeList+ spnl+ char ']'+ return $ do+ suff' <- suff+ rest' <- rest+ return $ c{ citationSuffix = B.toList suff' } : rest'++normalCite :: MarkdownParser (F [Citation])+normalCite = try $ do+ char '['+ spnl+ citations <- citeList+ spnl+ char ']'+ return citations++suffix :: MarkdownParser (F Inlines)+suffix = try $ do+ hasSpace <- option False (notFollowedBy nonspaceChar >> return True)+ spnl+ rest <- trimInlinesF . mconcat <$> many (notFollowedBy (oneOf ";]") >> inline)+ return $ if hasSpace+ then (B.space <>) <$> rest+ else rest++prefix :: MarkdownParser (F Inlines)+prefix = trimInlinesF . mconcat <$>+ manyTill inline (char ']' <|> liftM (const ']') (lookAhead citeKey))++citeList :: MarkdownParser (F [Citation])+citeList = fmap sequence $ sepBy1 citation (try $ char ';' >> spnl)++citation :: MarkdownParser (F Citation)+citation = try $ do+ pref <- prefix+ (suppress_author, key) <- citeKey+ suff <- suffix+ return $ do+ x <- pref+ y <- suff+ return $ Citation{ citationId = key+ , citationPrefix = B.toList x+ , citationSuffix = B.toList y+ , citationMode = if suppress_author+ then SuppressAuthor+ else NormalCitation+ , citationNoteNum = 0+ , citationHash = 0+ }++smart :: MarkdownParser (F Inlines)+smart = do+ getOption readerSmart >>= guard+ doubleQuoted <|> singleQuoted <|>+ choice (map (return <$>) [apostrophe, dash, ellipses])++singleQuoted :: MarkdownParser (F Inlines)+singleQuoted = try $ do+ singleQuoteStart+ withQuoteContext InSingleQuote $+ fmap B.singleQuoted . trimInlinesF . mconcat <$>+ many1Till inline singleQuoteEnd++-- doubleQuoted will handle regular double-quoted sections, as well+-- as dialogues with an open double-quote without a close double-quote+-- in the same paragraph.+doubleQuoted :: MarkdownParser (F Inlines)+doubleQuoted = try $ do+ doubleQuoteStart+ contents <- mconcat <$> many (try $ notFollowedBy doubleQuoteEnd >> inline)+ (withQuoteContext InDoubleQuote $ doubleQuoteEnd >> return+ (fmap B.doubleQuoted . trimInlinesF $ contents))+ <|> (return $ return (B.str "\8220") <> contents)++--+-- Scholarly Markdown extensions+--++ensureScholarlyMarkdown :: MarkdownParser ()+ensureScholarlyMarkdown = guardEnabled Ext_scholarly_markdown++inBraces :: MarkdownParser String -> MarkdownParser String+inBraces parser = try $ do+ char '{'+ content <- parser+ char '}'+ return content++many1InSeparateLines :: MarkdownParser a -> MarkdownParser [a]+many1InSeparateLines parser = try $ do+ first <- parser+ rest <- many $ try (blankline >> parser)+ return (first:rest)++--+-- Scholarly Markdown math extensions+--++scholarlyMath :: MarkdownParser (F Inlines)+scholarlyMath = ensureScholarlyMarkdown >>+ (scholarlyInlineMath <|> scholarlyDisplayMath')++-- InlineMath delimted by double backticks+scholarlyInlineMath :: MarkdownParser (F Inlines)+scholarlyInlineMath = return . B.math <$>+ mathInlineWith' (exactly 2 '`') (exactly 2 '`')++-- DisplayMath as defined by Scholarly Markdown:+-- Single equations appear in a fenced code block with class prepended by 'math'+-- or delimited by double dollar-signs on their own lines.+-- Multiple equations not separated by a standalone blankline will be collapsed+-- into a single gather or align structure.+scholarlyDisplayMath :: MarkdownParser (F Inlines)+scholarlyDisplayMath = try $ do+ eqnList <- many1InSeparateLines (fencedCodeEquation <|> doubleDollarEquation)+ mapM_ addMathDefsToState eqnList+ -- filter out all the mathdefs+ let eqnList' = filter (not . classIsMathDef . fst) eqnList+ -- it's possible that we consumed all the eqns as definitions+ let processedEqn = case eqnList' of+ [] -> Nothing+ singleEqn:[] -> Just (processSingleEqn singleEqn)+ _ -> Just (processMultiEqn eqnList')+ case processedEqn of+ Just (eqn, idList) -> do+ state <- getState+ let xrefIds = stateXRefIdents state+ let newXrefIds = xrefIds{ idsForMath = idsForMath xrefIds ++ idList }+ updateState $ \s -> s{ stateXRefIdents = newXrefIds }+ return $ return $ uncurry B.displayMathWith eqn+ Nothing -> return $ return mempty++-- ensures that displayMath are delimited by blanklines+scholarlyDisplayMath' :: MarkdownParser (F Inlines)+scholarlyDisplayMath' = try $ do+ blankline+ optional blankline -- allow another blank line without starting new block+ dispmath <- scholarlyDisplayMath+ -- consume at most one blankline immediately following,+ -- which prevents starting a new block element while allowing blankline+ try (lookAhead (count 2 blankline) >> blankline) <|> lookAhead blankline+ return $ (B.space <>) <$> dispmath++-- DisplayMath with attributes inside a fenced code block+-- only match if class of fenced code block starts with math+fencedCodeEquation :: MarkdownParser AttributedMath+fencedCodeEquation = try $ do+ c <- try (guardEnabled Ext_fenced_code_blocks >> lookAhead (char '~'))+ <|> (guardEnabled Ext_backtick_code_blocks >> lookAhead (char '`'))+ size <- blockDelimiter (== c) Nothing+ skipSpaces+ attr <- option nullAttr $+ try (guardEnabled Ext_fenced_code_attributes >> attributes)+ <|> do+ cls <- identifier+ label <- option [] $+ try (optional blankline >> skipSpaces >> char '#' >> identifier)+ <|> try (skipSpaces >> inBraces (char '#' >> identifier))+ return (label,[cls],[])+ guard $ classIsMath attr+ blankline+ contents <- manyTill anyLine (blockDelimiter (== c) (Just size))+ return (attr, intercalate "\n" contents)++-- DisplayMath delimited by double dollar signs+-- only match if class of fenced code block starts with math+doubleDollarEquation :: MarkdownParser AttributedMath+doubleDollarEquation = try $ do+ let delimitr = exactly 2 '$'+ delimitr+ skipSpaces+ attr <- do+ cls <- option "math" $ try identifier+ label <- option [] $+ try (optional blankline >> skipSpaces >> char '#' >> identifier)+ <|> try (skipSpaces >> inBraces (char '#' >> identifier))+ return (label,[cls],[])+ guard $ classIsMath attr+ blanklines+ contents <- manyTill anyLine delimitr+ return (attr, intercalate "\n" contents)++addMathDefsToState :: AttributedMath -> MarkdownParser ()+addMathDefsToState (attr, mathDef) = do+ when (classIsMathDef attr) $ updateState+ (\s -> s{ stateMathDefs = stateMathDefs s ++ mathDef ++ "\n" })+ return ()++--+-- Scholarly Markdown figures+--++scholarlyFigure :: MarkdownParser (F Blocks)+scholarlyFigure = try $ do+ ensureScholarlyMarkdown+ many1 (char '#')+ notFollowedBy $ guardEnabled Ext_fancy_lists >>+ (char '.' <|> char ')') -- this would be a list+ skipSpaces+ figKeyword <- many1 alphaNum <* char ':'+ attr <- figureAttribute+ blankline >> optional blankline+ (figType, attr', content) <- figureContent (map toLower figKeyword) attr+ caption <- option mempty figureCaption+ blanklines+ return $ liftM2 (B.figure figType attr' noPrepContent) content caption++-- Figure attributes are defined by a Attr block at the very end of the+-- @'Figure:'@ header line. The parser should ignore all characters between+-- @'Figure:'@ and the final Attr block.+figureAttribute :: MarkdownParser Attr+figureAttribute = do+ manyTill anyChar $ lookAhead (try (optional attributes >> blankline))+ attr <- option nullAttr attributes+ return attr++-- Figure captions consist of a single inline block/paragraph, are separated by+-- a blank line from the figure content, and must begin with non-indented+-- @'Caption:'@. Alternatively, the @'Caption:'@ is optional if the caption+-- starts on the line immediately after the figure content without a blank line.+-- As a shortcut, the word @'Caption'@ is optional, a @':'@ symbol alone is enough.+figureCaption :: MarkdownParser (F Inlines)+figureCaption =+ let figureCaptionIdentifier = try (char ':') <|> try (stringAnyCase "caption" >> char ':')+ figureCaptionStart = try (notFollowedBy blankline >> skipNonindentSpaces+ >> optional figureCaptionIdentifier >> return ())+ <|> try (blankline >> skipNonindentSpaces+ >> figureCaptionIdentifier >> return ())+ in figureCaptionStart >> (trimInlinesF . mconcat <$> many1 inline)++-- Contents of a figure, chosen based on keyword+figureContent :: String -> Attr -> MarkdownParser (FigureType, Attr, F Blocks)+figureContent "figure" = figureWithImages+figureContent "table" = figureWithTable+figureContent "algorithm" = figureWithLineBlock+figureContent "textbox" = figureWithLineBlock+figureContent "listing" = figureWithCodeBlock+figureContent "code" = figureWithCodeBlock+figureContent _ = \_ -> mzero++-- A floating figure containing a grid of images (subfigures), needs special+-- parsing code because each subfigure has its own identifier and attribute+figureWithImages :: Attr -> MarkdownParser (FigureType, Attr, F Blocks)+figureWithImages attr = try $ do+ subfigRows <- many1 scholarlySubfigureRow+ let allIds = concatMap snd subfigRows+ let figClass = if length allIds == 1 then "singleFigure"+ else "multiFigure"+ state <- getState+ -- image figures need special handling for identifier to numeric label+ -- conversion, because of more compliocated rules involving subfigures+ let xrefIds = stateXRefIdents state+ -- need to display a numerical id if there is need to refer to subfigs+ -- unless forcibly disabled by class ".nonumber"+ let needId = ( any (/= "") allIds || getIdentifier attr /= "" )+ && not (hasClass "nonumber" attr)+ -- this identifier is only used in the list of reference ids for numbering+ let myIdentifier+ | needId && getIdentifier attr == "" = "#"+ | not (hasClass "nonumber" attr) = getIdentifier attr+ | otherwise = ""+ let myNumLabel = if needId+ then length (filter (/= "") $ idsForFigure xrefIds) + 1+ else 0 -- will never be displayed anyways+ let newXrefIds = xrefIds{ idsForFigure = idsForFigure xrefIds ++ [myIdentifier],+ idsForSubfigure = idsForSubfigure xrefIds ++ [(allIds, myNumLabel)] }+ updateState $ \s -> s{ stateXRefIdents = newXrefIds }+ let attrActions = [ insertClass figClass+ , insertReplaceKeyVal ("subfigIds", show allIds)+ , insertReplaceKeyValIf needId ("numLabel", show myNumLabel)+ ]+ let subfigRowsOnlyImages = map fst subfigRows+ let imgContent = liftM B.imageGrid (sequence subfigRowsOnlyImages)+ let attrUpdater = \a -> foldr ($) a attrActions+ return (ImageFigure, attrUpdater attr, imgContent)++-- A floating figure containing a single table+figureWithTable :: Attr -> MarkdownParser (FigureType, Attr, F Blocks)+figureWithTable attr = try $ do+ tabl <- table'+ state <- getState+ let tblIdSetter = \ids idList -> ids{idsForTables = idList}+ let (attrSetLabel, stAddId) = figureIdToNumLabelHandler attr state idsForTables tblIdSetter+ updateState stAddId+ let attrUpdater = \a -> foldr ($) a [attrSetLabel]+ return (TableFigure, attrUpdater attr, tabl)++-- A floating figure containing a rST-type line block+figureWithLineBlock :: Attr -> MarkdownParser (FigureType, Attr, F Blocks)+figureWithLineBlock attr = try $ do+ lineBlks <- many1 lineBlock'+ state <- getState+ let algIdSetter = \ids idList -> ids{idsForAlgorithms = idList}+ let (attrSetLabel, stAddId) = figureIdToNumLabelHandler attr state idsForAlgorithms algIdSetter+ updateState stAddId+ let attrUpdater = \a -> foldr ($) a [attrSetLabel]+ return (LineBlockFigure, attrUpdater attr, mconcat lineBlks)++-- A floating figure containing a pre-formatted code block+figureWithCodeBlock :: Attr -> MarkdownParser (FigureType, Attr, F Blocks)+figureWithCodeBlock attr = try $ do+ (codeAttr, codeContent) <- codeBlockFenced' <|> codeBlockIndented'+ state <- getState+ let lstIdSetter = \ids idList -> ids{idsForCodeBlocks = idList}+ let (attrSetLabel, stAddId) = figureIdToNumLabelHandler attr state idsForCodeBlocks lstIdSetter+ updateState stAddId+ let attrUpdater = \a -> foldr ($) a [attrSetLabel]+ let codeblock = B.codeBlockWith codeAttr codeContent+ return (ListingFigure, attrUpdater attr, return codeblock)++--+-- Helper parsers for various types of Figure contents+--++-- Utility for parsing a single row of images (subfigures) and extracting+-- their identifiers from the optional Image Attr blocks+scholarlySubfigureRow :: MarkdownParser (F Inlines, [String])+scholarlySubfigureRow = try $ do+ subfigs <- many1InSeparateLines image+ optional $ try (skipSpaces >> char '\\')+ blankline+ let ids = [ (getIdentifier . getImageAttr) $+ head $ B.toList $ runF x defaultParserState | x <- subfigs ]+ return (mconcat subfigs, ids)++-- | A version of lineBlockLines that doesn't consume all subsequent blanklines+lineBlockLines' :: MarkdownParser [String]+lineBlockLines' = try $ do+ lines' <- many1 lineBlockLine+ skipMany $ try (char '|' >> blankline)+ return lines'++-- | A version of lineBlock that doesn't consume all subsequent blanklines+-- | and also converts all spaces to non-breaking (some demands this)+lineBlock' :: MarkdownParser (F Blocks)+lineBlock' = try $ do+ guardEnabled Ext_line_blocks+ st <- getState+ let currSpacingSt = stateKeepSpacing st+ setState $ st{ stateKeepSpacing = True }+ lines' <- lineBlockLines' >>=+ mapM (parseFromString (trimInlinesF . mconcat <$> many inline))+ setState $ st{ stateKeepSpacing = currSpacingSt }+ return $ B.para <$> mconcat (intersperse (return B.linebreak) lines')++-- version of table that doesn't parse caption+table' :: MarkdownParser (F Blocks)+table' = try $ do+ (aligns, widths, heads, lns) <-+ try (guardEnabled Ext_pipe_tables >> scanForPipe >> pipeTable) <|>+ try (guardEnabled Ext_multiline_tables >>+ multilineTable False) <|>+ try (guardEnabled Ext_simple_tables >>+ (simpleTable True <|> simpleTable False)) <|>+ try (guardEnabled Ext_multiline_tables >>+ multilineTable True) <|>+ try (guardEnabled Ext_grid_tables >>+ (gridTable False <|> gridTable True)) <?> "table"+ return $ do+ heads' <- heads+ lns' <- lns+ return $ B.table mempty (zip aligns widths) heads' lns'++--+-- Scholarly Markdown numerical cross-references+--++scholarlyXRef :: MarkdownParser (F Inlines)+scholarlyXRef = ensureScholarlyMarkdown >>+ (scholarlyPlainXRef <|> scholarlyParensXRef)++scholarlyPlainXRef :: MarkdownParser (F Inlines)+scholarlyPlainXRef = try $ do+ label <- string "[#" >> identifier <* char ']'+ return $ do+ xRefs <- asksF stateXRefIdents+ let defNumLabel = [Str $ getNumericalLabel label xRefs]+ let refStyle = NumberedReference label PlainNumRef defNumLabel+ return $ B.numRef refStyle $ "[#" ++ label ++ "]"++scholarlyParensXRef :: MarkdownParser (F Inlines)+scholarlyParensXRef = try $ do+ label <- string "(#" >> identifier <* char ')'+ return $ do+ xRefs <- asksF stateXRefIdents+ let defNumLabel = [Str $ getNumericalLabel label xRefs]+ let refStyle = NumberedReference label ParenthesesNumRef defNumLabel+ return $ B.numRef refStyle $ "(#" ++ label ++ ")"++--+-- Scholarly Markdown statements+--++-- scholarlyStatements :: MarkdownParser (F Blocks)+-- scholarlyStatements = try $ do+-- start <- satisfy isHruleChar+-- count 2 (char start)+-- newline+-- level <- many1 (char '#') >>= return . length+-- notFollowedBy $ guardEnabled Ext_fancy_lists >>+-- (char '.' <|> char ')') -- this would be a list+-- skipSpaces+-- return mempty++--+-- Abstract+--++-- Parses one paragraph as abstract, no more and no less, then+-- set as metadata+scholarlyAbstract :: MarkdownParser (F Blocks)+scholarlyAbstract = try $ do+ ensureScholarlyMarkdown+ many1 (char '#')+ notFollowedBy $ guardEnabled Ext_fancy_lists >>+ (char '.' <|> char ')') -- this would be a list+ skipSpaces+ string "Abstract:" >> blanklines+ abstract <- para+ let meta' = do+ abstract' <- abstract+ return $ B.setMeta "abstract" abstract' nullMeta+ updateState $ \st -> st{ stateMeta' = stateMeta' st <> meta' }+ return $ return mempty
@@ -0,0 +1,76 @@+{-+Copyright (C) 2011-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Readers.Native+ Copyright : Copyright (C) 2011-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of a string representation of a pandoc type (@Pandoc@,+@[Block]@, @Block@, @[Inline]@, or @Inline@) to a @Pandoc@ document.+-}+module Text.Pandoc.Readers.Native ( readNative ) where++import Text.Pandoc.Definition+import Text.Pandoc.Shared (safeRead)++-- | Read native formatted text and return a Pandoc document.+-- The input may be a full pandoc document, a block list, a block,+-- an inline list, or an inline. Thus, for example,+--+-- > Str "hi"+--+-- will be treated as if it were+--+-- > Pandoc nullMeta [Plain [Str "hi"]]+--+readNative :: String -- ^ String to parse (assuming @'\n'@ line endings)+ -> Pandoc+readNative s =+ case safeRead s of+ Just d -> d+ Nothing -> Pandoc nullMeta $ readBlocks s++readBlocks :: String -> [Block]+readBlocks s =+ case safeRead s of+ Just d -> d+ Nothing -> [readBlock s]++readBlock :: String -> Block+readBlock s =+ case safeRead s of+ Just d -> d+ Nothing -> Plain $ readInlines s++readInlines :: String -> [Inline]+readInlines s =+ case safeRead s of+ Just d -> d+ Nothing -> [readInline s]++readInline :: String -> Inline+readInline s =+ case safeRead s of+ Just d -> d+ Nothing -> error "Cannot parse document"+
@@ -0,0 +1,48 @@+{-+Copyright (C) 2007-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Readers.TeXMath+ Copyright : Copyright (C) 2007-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of TeX math to a list of 'Pandoc' inline elements.+-}+module Text.Pandoc.Readers.TeXMath ( texMathToInlines ) where++import Text.Pandoc.Definition+import Text.TeXMath++-- | Converts a raw TeX math formula to a list of 'Pandoc' inlines.+-- Defaults to raw formula between @$@ or @$$@ characters if entire formula+-- can't be converted.+texMathToInlines :: MathType+ -> String -- ^ String to parse (assumes @'\n'@ line endings)+ -> [Inline]+texMathToInlines mt inp =+ case writePandoc dt `fmap` readTeX inp of+ Right (Just ils) -> ils+ _ -> [Str (delim ++ inp ++ delim)]+ where (dt, delim) = case mt of+ (DisplayMath _) -> (DisplayBlock, "$$")+ InlineMath -> (DisplayInline, "$")+
@@ -0,0 +1,283 @@+{-+Copyright (C) 2014 Tim T.Y. Lin <timtylin@gmail.com>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Scholarly+ Copyright : Copyright (C) 2014 Tim T.Y. Lin+ License : GNU GPL, version 2 or above++ Maintainer : Tim T.Y. Lin <timtylin@gmail.com>+ Stability : alpha+ Portability : portable++Utility functions for Scholarly Markdown extensions.+-}+module Text.Pandoc.Scholarly (classIsMath,+ classIsMathDef,+ processSingleEqn,+ processMultiEqn,+ dispMathToLaTeX,+ figureIdToNumLabelHandler,+ AttributedMath,+ getImageAttr,+ getIdentifier,+ getClasses,+ hasClass,+ getKeyVals,+ lookupKey,+ setIdentifier,+ insertClass,+ insertIfNoneKeyVal,+ insertReplaceKeyVal,+ insertReplaceKeyValIf,+ extractMetaStringList,+ extractMetaString+ )+where++import Data.List ( intercalate )+import Text.Pandoc.Definition+import Text.Pandoc.Shared+import Text.Pandoc.Parsing hiding (tableWith)+import Control.Arrow+import Control.Monad (void)+import qualified Data.Map as M++type AttributedMath = (Attr, String)++-- true only if some element of classes start with "math"+classIsMath :: Attr -> Bool+classIsMath (_,classes,_) = any (`elem` ["math", "math_def", "math_plain"]) classes++classIsMathDef :: Attr -> Bool+classIsMathDef (_,classes,_) = "math_def" `elem` classes++--+-- Attribute manipulation functions+--++insertClass :: String -> Attr -> Attr+insertClass className attr@(ident, classes, keyval)+ | className `notElem` classes = (ident, className:classes, keyval)+ | otherwise = attr++insertWithKeyVal :: (String -> String -> String) -- ^ new, old, final value+ -> (String, String) -- ^ (key, new value)+ -> Attr+ -> Attr+insertWithKeyVal f (key, val) (ident, classes, keyval) =+ let newKeyValMap = M.insertWith f key val $ M.fromList keyval+ in (ident, classes, M.toList newKeyValMap)++insertIfNoneKeyVal :: (String, String) -> Attr -> Attr+insertIfNoneKeyVal = insertWithKeyVal (\_ x -> x)++insertReplaceKeyVal :: (String, String) -> Attr -> Attr+insertReplaceKeyVal = insertWithKeyVal const++insertReplaceKeyValIf :: Bool -> (String, String) -> Attr -> Attr+insertReplaceKeyValIf True kv attr = insertReplaceKeyVal kv attr+insertReplaceKeyValIf False _ attr = attr++getClasses :: Attr -> [String]+getClasses (_, classes, _) = classes++hasClass :: String -> Attr -> Bool+hasClass cls (_, classes, _) = cls `elem` classes++getIdentifier :: Attr -> String+getIdentifier (identifier, _, _) = identifier++setIdentifier :: String -> Attr -> Attr+setIdentifier identifier (_, classes, keyval) = (identifier, classes, keyval)++getKeyVals :: Attr -> [(String, String)]+getKeyVals (_, _, keyVals) = keyVals++lookupKey :: String -> Attr -> Maybe String+lookupKey key (_, _, keyval) = M.lookup key $ M.fromList keyval++getImageAttr :: Inline -> Attr+getImageAttr (Image attr _ _) = attr+getImageAttr _ = nullAttr++--+-- Writer state helpers (useful for cross-references)+--++extractMetaStringList :: Maybe MetaValue -> [String]+extractMetaStringList (Just (MetaList lst)) = map extractMetaString lst+extractMetaStringList (Just (MetaString str)) = [str]+extractMetaStringList _ = []++extractMetaString :: MetaValue -> String+extractMetaString (MetaString str) = str+extractMetaString _ = ""++---+--- Parser functions for Scholarly DisplayMath+---++-- Currently does the following:+-- 1) automatically wrap in @aligned@ or @split@ envionrment if needed+-- 2) if attribute has id, append @\label{id}@ to code+-- 3) Returns also the label string in an list+processSingleEqn :: AttributedMath -> (AttributedMath, [String])+processSingleEqn eqn =+ let processors = [ensureLabeled "\n", -- ensureNonumber is handled by writer+ ensureMultilineEnv]+ label = (getIdentifier . fst) eqn+ in (foldr ($) eqn processors, [label])++-- Currently does the following:+-- 1) trim whitespace from all equation codes+-- 2) if attribute has id, append @\label{id}@ to code+-- 3) if attribute has no id, append @\nonumber@ to code+-- 4) concatenate all equations into one code chunk delimited by @'\\'@+-- 5) assign @align@ or @gather@ class as needed+-- 6) gather all equation labels as list and output to @labelList@ key+processMultiEqn :: [AttributedMath] -> (AttributedMath, [String])+processMultiEqn eqnList =+ let processors = [ensureNonumber " ",+ ensureLabeled " ",+ id *** trim]+ processedEqnList = foldr map eqnList processors+ labels = map (getIdentifier . fst) eqnList+ in (concatMultiEquations processedEqnList, labels)++-- Automatically surround with split env if naked token @'\\'@ detected,+-- or aligned env if both naked token @'\\'@ and @'&'@ detected.+-- Skipped classes: [math_plain]+ensureMultilineEnv :: AttributedMath -> AttributedMath+ensureMultilineEnv eqn@(attr, content)+ | "math_plain" `elem` getClasses attr = eqn+ | hasTeXLinebreak content = if hasTeXAlignment content+ then (attr, wrapInLatexEnv "aligned" content)+ else (attr, wrapInLatexEnv "split" content)+ | otherwise = eqn++-- if attribute has no id, append @\nonumber@ to code+ensureNonumber :: String -> AttributedMath -> AttributedMath+ensureNonumber terminal eqn@(attr, content) =+ case attr of+ ("",_ ,_) -> (attr, "\\nonumber" ++ terminal ++ content)+ _ -> eqn++-- if attribute has id, append @\label{id}@ to code+-- (does not ensure no duplicate labels)+ensureLabeled :: String -> AttributedMath -> AttributedMath+ensureLabeled terminal eqn@(attr, content) =+ case attr of+ ("",_ ,_) -> eqn+ (label, _, _) -> (attr, "\\label{" ++ label ++ "}" ++ terminal ++ content)++-- scans first equation for alignment characters,+-- assign @align@ or @gather@ accordingly,+-- then concatenate all lines into one multi-equation displayMath,+-- gathering the idents of all equations into one large list+concatMultiEquations :: [AttributedMath] -> AttributedMath+concatMultiEquations eqnList =+ let eqnContents = map snd eqnList+ multiClass = if hasTeXAlignment (head eqnContents)+ then "align"+ else "gather"+ in ( ("", ["math",multiClass], [("labelList",show (map (getIdentifier.fst) eqnList))]),+ intercalate "\\\\\n" eqnContents )++wrapInLatexEnv :: String -> String -> String+wrapInLatexEnv envName content = intercalate "\n"+ ["\\begin{" ++ envName ++ "}", content, "\\end{" ++ envName ++ "}"]++-- Scan for occurance of @'\\'@ in non-commented parts,+-- not within "split" or "aligned" environment+hasTeXLinebreak :: String -> Bool+hasTeXLinebreak content =+ case parse (skipMany (try ignoreLinebreak+ <|> try (char '\\' >> notFollowedBy (char '\\') >> return [])+ <|> try (noneOf "\\" >> return []))+ >> void (string "\\\\")) [] content of+ Left _ -> False+ Right _ -> True++-- Scan for occurance of non-escaped @'&'@ in non-commented parts+-- not within "split" or "aligned" environment+hasTeXAlignment :: String -> Bool+hasTeXAlignment content =+ case parse (skipMany (try ignoreLinebreak+ <|> try (string "\\&")+ <|> try (noneOf "&" >> return []))+ >> void (char '&')) [] content of+ Left _ -> False+ Right _ -> True++skipTeXComment :: Parser String st String+skipTeXComment = try $ do+ char '%'+ manyTill anyChar $ try $ newline <|> (eof >> return '\n')+ return []++skipTexEnvironment :: String -> Parser String st String+skipTexEnvironment envName = try $ do+ string ("\\begin{" ++ envName ++ "}")+ manyTill anyChar $ try $ string ("\\end{" ++ envName ++ "}")+ return []++ignoreLinebreak :: Parser String st String+ignoreLinebreak = try (string "\\%")+ <|> skipTeXComment+ <|> skipTexEnvironment "split"+ <|> skipTexEnvironment "aligned"+ <|> skipTexEnvironment "alignedat"+ <|> skipTexEnvironment "cases"++--+-- Writer functions for Scholarly DisplayMath+--++dispMathToLaTeX :: Attr -> String -> String+dispMathToLaTeX (label, classes, _) mathCode+ | "align" `elem` classes = wrapInLatexEnv "align" mathCode+ | "gather" `elem` classes = wrapInLatexEnv "gather" mathCode+ | "math_def" `elem` classes = mathCode+ | otherwise = case label of+ "" -> wrapInLatexEnv "equation*" mathCode+ _ -> wrapInLatexEnv "equation" mathCode++--+-- Utility functions for Figures+--++-- Specifies how Ids for Scholarly Figures map to numeric labels, and how they+-- are updated in the list of identifiers+figureIdToNumLabelHandler :: Attr+ -> ParserState+ -> (XRefIdentifiers -> [String])+ -> (XRefIdentifiers -> [String] -> XRefIdentifiers)+ -> (Attr -> Attr, ParserState -> ParserState)+figureIdToNumLabelHandler attr state idListGetter idListSetter =+ let xrefIds = stateXRefIdents state+ -- numbering can be forcibly disabled by class ".nonumber"+ needId = not (hasClass "nonumber" attr) && getIdentifier attr /= ""+ myIdentifier = getIdentifier attr+ myNumLabel = if needId+ then length (filter (/= "") $ idListGetter xrefIds) + 1+ else 0 -- will never be displayed anyways+ newXrefIds = idListSetter xrefIds (idListGetter xrefIds ++ [myIdentifier])+ stateUpdater = \s -> s{ stateXRefIdents = newXrefIds }+ attrUpdater = insertReplaceKeyValIf needId ("numLabel", show myNumLabel)+ in (attrUpdater, stateUpdater)
@@ -0,0 +1,139 @@+{-# LANGUAGE OverloadedStrings #-}+{-+Copyright (C) 2011-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.SelfContained+ Copyright : Copyright (C) 2011-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Functions for converting an HTML file into one that can be viewed+offline, by incorporating linked images, CSS, and scripts into+the HTML using data URIs.+-}+module Text.Pandoc.SelfContained ( makeSelfContained ) where+import Text.HTML.TagSoup+import Network.URI (isURI, escapeURIString, URI(..), parseURI)+import Data.ByteString.Base64+import qualified Data.ByteString.Char8 as B+import Data.ByteString (ByteString)+import System.FilePath (takeExtension, takeDirectory, (</>))+import Data.Char (toLower, isAscii, isAlphaNum)+import Codec.Compression.GZip as Gzip+import qualified Data.ByteString.Lazy as L+import Text.Pandoc.Shared (renderTags', err, fetchItem')+import Text.Pandoc.MediaBag (MediaBag)+import Text.Pandoc.MIME (MimeType)+import Text.Pandoc.UTF8 (toString, fromString)+import Text.Pandoc.Options (WriterOptions(..))++isOk :: Char -> Bool+isOk c = isAscii c && isAlphaNum c++convertTag :: MediaBag -> Maybe String -> Tag String -> IO (Tag String)+convertTag media sourceURL t@(TagOpen tagname as)+ | tagname `elem`+ ["img", "embed", "video", "input", "audio", "source", "track"] = do+ as' <- mapM processAttribute as+ return $ TagOpen tagname as'+ where processAttribute (x,y) =+ if x == "src" || x == "href" || x == "poster"+ then do+ (raw, mime) <- getRaw media sourceURL (fromAttrib "type" t) y+ let enc = "data:" ++ mime ++ ";base64," ++ toString (encode raw)+ return (x, enc)+ else return (x,y)+convertTag media sourceURL t@(TagOpen "script" as) =+ case fromAttrib "src" t of+ [] -> return t+ src -> do+ (raw, mime) <- getRaw media sourceURL (fromAttrib "type" t) src+ let enc = "data:" ++ mime ++ "," ++ escapeURIString isOk (toString raw)+ return $ TagOpen "script" (("src",enc) : [(x,y) | (x,y) <- as, x /= "src"])+convertTag media sourceURL t@(TagOpen "link" as) =+ case fromAttrib "href" t of+ [] -> return t+ src -> do+ (raw, mime) <- getRaw media sourceURL (fromAttrib "type" t) src+ let enc = "data:" ++ mime ++ "," ++ escapeURIString isOk (toString raw)+ return $ TagOpen "link" (("href",enc) : [(x,y) | (x,y) <- as, x /= "href"])+convertTag _ _ t = return t++-- NOTE: This is really crude, it doesn't respect CSS comments.+cssURLs :: MediaBag -> Maybe String -> FilePath -> ByteString+ -> IO ByteString+cssURLs media sourceURL d orig =+ case B.breakSubstring "url(" orig of+ (x,y) | B.null y -> return orig+ | otherwise -> do+ let (u,v) = B.breakSubstring ")" $ B.drop 4 y+ let url = toString+ $ case B.take 1 u of+ "\"" -> B.takeWhile (/='"') $ B.drop 1 u+ "'" -> B.takeWhile (/='\'') $ B.drop 1 u+ _ -> u+ let url' = if isURI url+ then url+ else d </> url+ (raw, mime) <- getRaw media sourceURL "" url'+ rest <- cssURLs media sourceURL d v+ let enc = "data:" `B.append` fromString mime `B.append`+ ";base64," `B.append` (encode raw)+ return $ x `B.append` "url(" `B.append` enc `B.append` rest++getRaw :: MediaBag -> Maybe String -> MimeType -> String+ -> IO (ByteString, MimeType)+getRaw media sourceURL mimetype src = do+ let ext = map toLower $ takeExtension src+ fetchResult <- fetchItem' media sourceURL src+ (raw, respMime) <- case fetchResult of+ Left msg -> err 67 $ "Could not fetch " ++ src +++ "\n" ++ show msg+ Right x -> return x+ let raw' = if ext == ".gz"+ then B.concat $ L.toChunks $ Gzip.decompress $ L.fromChunks+ $ [raw]+ else raw+ let mime = case (mimetype, respMime) of+ ("",Nothing) -> error+ $ "Could not determine mime type for `" ++ src ++ "'"+ (x, Nothing) -> x+ (_, Just x ) -> x+ let cssSourceURL = case parseURI src of+ Just u+ | uriScheme u `elem` ["http:","https:"] ->+ Just $ show u{ uriPath = "",+ uriQuery = "",+ uriFragment = "" }+ _ -> Nothing+ result <- if mime == "text/css"+ then cssURLs media cssSourceURL (takeDirectory src) raw'+ else return raw'+ return (result, mime)++-- | Convert HTML into self-contained HTML, incorporating images,+-- scripts, and CSS using data: URIs.+makeSelfContained :: WriterOptions -> String -> IO String+makeSelfContained opts inp = do+ let tags = parseTags inp+ out' <- mapM (convertTag (writerMediaBag opts) (writerSourceURL opts)) tags+ return $ renderTags' out'
@@ -0,0 +1,913 @@+{-# LANGUAGE DeriveDataTypeable, CPP, MultiParamTypeClasses,+ FlexibleContexts, ScopedTypeVariables, PatternGuards,+ ViewPatterns #-}+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>+Copyright (C) 2014 Tim T.Y. Lin <timtylin@gmail.com>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Shared+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Utility functions and definitions used by the various Pandoc modules.+-}+module Text.Pandoc.Shared (+ -- * List processing+ splitBy,+ splitByIndices,+ splitStringByIndices,+ substitute,+ ordNub,+ -- * Text processing+ backslashEscapes,+ escapeStringUsing,+ stripTrailingNewlines,+ trim,+ triml,+ trimr,+ stripFirstAndLast,+ camelCaseToHyphenated,+ toRomanNumeral,+ escapeURI,+ tabFilter,+ -- * Date/time+ normalizeDate,+ -- * Pandoc block and inline list processing+ orderedListMarkers,+ normalizeSpaces,+ extractSpaces,+ normalize,+ normalizeInlines,+ normalizeBlocks,+ removeFormatting,+ stringify,+ capitalize,+ compactify,+ compactify',+ compactify'DL,+ Element (..),+ hierarchicalize,+ uniqueIdent,+ alphEnum,+ isHeaderBlock,+ headerShift,+ isTightList,+ addMetaField,+ makeMeta,+ -- * TagSoup HTML handling+ renderTags',+ -- * File handling+ inDirectory,+ readDataFile,+ readDataFileUTF8,+ fetchItem,+ fetchItem',+ openURL,+ collapseFilePath,+ -- * Error handling+ err,+ warn,+ -- * Safe read+ safeRead,+ -- * Temp directory+ withTempDir+ ) where++import Text.Pandoc.Definition+import Text.Pandoc.Walk+import Text.Pandoc.MediaBag (MediaBag, lookupMedia)+import Text.Pandoc.Builder (Inlines, Blocks, ToMetaValue(..))+import qualified Text.Pandoc.Builder as B+import qualified Text.Pandoc.UTF8 as UTF8+import System.Environment (getProgName)+import System.Exit (exitWith, ExitCode(..))+import Data.Char ( toLower, isLower, isUpper, isAlpha,+ isLetter, isDigit, isSpace, ord, chr )+import Data.List ( find, stripPrefix, intercalate )+import qualified Data.Map as M+import Network.URI ( escapeURIString, isURI, nonStrictRelativeTo,+ unEscapeString, parseURIReference, isAllowedInURI )+import qualified Data.Set as Set+import System.Directory+import System.FilePath (joinPath, splitDirectories, pathSeparator, isPathSeparator)+import Text.Pandoc.MIME (MimeType, getMimeType)+import System.FilePath ( (</>), takeExtension, dropExtension)+import Data.Generics (Typeable, Data)+import qualified Control.Monad.State as S+import qualified Control.Exception as E+import Control.Monad (msum, unless)+import Text.Pandoc.Pretty (charWidth)+import System.Locale (defaultTimeLocale)+import Data.Time+import System.IO (stderr)+import System.IO.Temp+import Text.HTML.TagSoup (renderTagsOptions, RenderOptions(..), Tag(..),+ renderOptions)+import qualified Data.ByteString as BS+import qualified Data.ByteString.Char8 as B8+import Text.Pandoc.Compat.Monoid+import Data.ByteString.Base64 (decodeLenient)+import Data.Sequence (ViewR(..), ViewL(..), viewl, viewr)+import qualified Data.Text as T (toUpper, pack, unpack)+import Data.ByteString.Lazy (toChunks)++#ifdef EMBED_DATA_FILES+import Text.Pandoc.Data (dataFiles)+#else+import Paths_scholdoc (getDataFileName)+#endif+#ifdef HTTP_CLIENT+import Network.HTTP.Client (httpLbs, parseUrl, withManager,+ responseBody, responseHeaders,+ Request(port,host))+import Network.HTTP.Client.Internal (addProxy)+import Network.HTTP.Client.TLS (tlsManagerSettings)+import System.Environment (getEnv)+import Network.HTTP.Types.Header ( hContentType)+import Network (withSocketsDo)+#else+import Network.URI (parseURI)+import Network.HTTP (findHeader, rspBody,+ RequestMethod(..), HeaderName(..), mkRequest)+import Network.Browser (browse, setAllowRedirects, setOutHandler, request)+#endif++--+-- List processing+--++-- | Split list by groups of one or more sep.+splitBy :: (a -> Bool) -> [a] -> [[a]]+splitBy _ [] = []+splitBy isSep lst =+ let (first, rest) = break isSep lst+ rest' = dropWhile isSep rest+ in first:(splitBy isSep rest')++splitByIndices :: [Int] -> [a] -> [[a]]+splitByIndices [] lst = [lst]+splitByIndices (x:xs) lst = first:(splitByIndices (map (\y -> y - x) xs) rest)+ where (first, rest) = splitAt x lst++-- | Split string into chunks divided at specified indices.+splitStringByIndices :: [Int] -> [Char] -> [[Char]]+splitStringByIndices [] lst = [lst]+splitStringByIndices (x:xs) lst =+ let (first, rest) = splitAt' x lst in+ first : (splitStringByIndices (map (\y -> y - x) xs) rest)++splitAt' :: Int -> [Char] -> ([Char],[Char])+splitAt' _ [] = ([],[])+splitAt' n xs | n <= 0 = ([],xs)+splitAt' n (x:xs) = (x:ys,zs)+ where (ys,zs) = splitAt' (n - charWidth x) xs++-- | Replace each occurrence of one sublist in a list with another.+substitute :: (Eq a) => [a] -> [a] -> [a] -> [a]+substitute _ _ [] = []+substitute [] _ xs = xs+substitute target replacement lst@(x:xs) =+ case stripPrefix target lst of+ Just lst' -> replacement ++ substitute target replacement lst'+ Nothing -> x : substitute target replacement xs++ordNub :: (Ord a) => [a] -> [a]+ordNub l = go Set.empty l+ where+ go _ [] = []+ go s (x:xs) = if x `Set.member` s then go s xs+ else x : go (Set.insert x s) xs++--+-- Text processing+--++-- | Returns an association list of backslash escapes for the+-- designated characters.+backslashEscapes :: [Char] -- ^ list of special characters to escape+ -> [(Char, String)]+backslashEscapes = map (\ch -> (ch, ['\\',ch]))++-- | Escape a string of characters, using an association list of+-- characters and strings.+escapeStringUsing :: [(Char, String)] -> String -> String+escapeStringUsing _ [] = ""+escapeStringUsing escapeTable (x:xs) =+ case (lookup x escapeTable) of+ Just str -> str ++ rest+ Nothing -> x:rest+ where rest = escapeStringUsing escapeTable xs++-- | Strip trailing newlines from string.+stripTrailingNewlines :: String -> String+stripTrailingNewlines = reverse . dropWhile (== '\n') . reverse++-- | Remove leading and trailing space (including newlines) from string.+trim :: String -> String+trim = triml . trimr++-- | Remove leading space (including newlines) from string.+triml :: String -> String+triml = dropWhile (`elem` " \r\n\t")++-- | Remove trailing space (including newlines) from string.+trimr :: String -> String+trimr = reverse . triml . reverse++-- | Strip leading and trailing characters from string+stripFirstAndLast :: String -> String+stripFirstAndLast str =+ drop 1 $ take ((length str) - 1) str++-- | Change CamelCase word to hyphenated lowercase (e.g., camel-case).+camelCaseToHyphenated :: String -> String+camelCaseToHyphenated [] = ""+camelCaseToHyphenated (a:b:rest) | isLower a && isUpper b =+ a:'-':(toLower b):(camelCaseToHyphenated rest)+camelCaseToHyphenated (a:rest) = (toLower a):(camelCaseToHyphenated rest)++-- | Convert number < 4000 to uppercase roman numeral.+toRomanNumeral :: Int -> String+toRomanNumeral x =+ if x >= 4000 || x < 0+ then "?"+ else case x of+ _ | x >= 1000 -> "M" ++ toRomanNumeral (x - 1000)+ _ | x >= 900 -> "CM" ++ toRomanNumeral (x - 900)+ _ | x >= 500 -> "D" ++ toRomanNumeral (x - 500)+ _ | x >= 400 -> "CD" ++ toRomanNumeral (x - 400)+ _ | x >= 100 -> "C" ++ toRomanNumeral (x - 100)+ _ | x >= 90 -> "XC" ++ toRomanNumeral (x - 90)+ _ | x >= 50 -> "L" ++ toRomanNumeral (x - 50)+ _ | x >= 40 -> "XL" ++ toRomanNumeral (x - 40)+ _ | x >= 10 -> "X" ++ toRomanNumeral (x - 10)+ _ | x == 9 -> "IX"+ _ | x >= 5 -> "V" ++ toRomanNumeral (x - 5)+ _ | x == 4 -> "IV"+ _ | x >= 1 -> "I" ++ toRomanNumeral (x - 1)+ _ -> ""++-- | Escape whitespace in URI.+escapeURI :: String -> String+escapeURI = escapeURIString (not . isSpace)++-- | Convert tabs to spaces and filter out DOS line endings.+-- Tabs will be preserved if tab stop is set to 0.+tabFilter :: Int -- ^ Tab stop+ -> String -- ^ Input+ -> String+tabFilter tabStop =+ let go _ [] = ""+ go _ ('\n':xs) = '\n' : go tabStop xs+ go _ ('\r':'\n':xs) = '\n' : go tabStop xs+ go _ ('\r':xs) = '\n' : go tabStop xs+ go spsToNextStop ('\t':xs) =+ if tabStop == 0+ then '\t' : go tabStop xs+ else replicate spsToNextStop ' ' ++ go tabStop xs+ go 1 (x:xs) =+ x : go tabStop xs+ go spsToNextStop (x:xs) =+ x : go (spsToNextStop - 1) xs+ in go tabStop++--+-- Date/time+--++-- | Parse a date and convert (if possible) to "YYYY-MM-DD" format.+normalizeDate :: String -> Maybe String+normalizeDate s = fmap (formatTime defaultTimeLocale "%F")+ (msum $ map (\fs -> parsetimeWith fs s) formats :: Maybe Day)+ where parsetimeWith = parseTime defaultTimeLocale+ formats = ["%x","%m/%d/%Y", "%D","%F", "%d %b %Y",+ "%d %B %Y", "%b. %d, %Y", "%B %d, %Y", "%Y"]++--+-- Pandoc block and inline list processing+--++-- | Generate infinite lazy list of markers for an ordered list,+-- depending on list attributes.+orderedListMarkers :: (Int, ListNumberStyle, ListNumberDelim) -> [String]+orderedListMarkers (start, numstyle, numdelim) =+ let singleton c = [c]+ nums = case numstyle of+ DefaultStyle -> map show [start..]+ Example -> map show [start..]+ Decimal -> map show [start..]+ UpperAlpha -> drop (start - 1) $ cycle $+ map singleton ['A'..'Z']+ LowerAlpha -> drop (start - 1) $ cycle $+ map singleton ['a'..'z']+ UpperRoman -> map toRomanNumeral [start..]+ LowerRoman -> map (map toLower . toRomanNumeral) [start..]+ inDelim str = case numdelim of+ DefaultDelim -> str ++ "."+ Period -> str ++ "."+ OneParen -> str ++ ")"+ TwoParens -> "(" ++ str ++ ")"+ in map inDelim nums++-- | Normalize a list of inline elements: remove leading and trailing+-- @Space@ elements, collapse double @Space@s into singles, and+-- remove empty Str elements.+normalizeSpaces :: [Inline] -> [Inline]+normalizeSpaces = cleanup . dropWhile isSpaceOrEmpty+ where cleanup [] = []+ cleanup (Space:rest) = case dropWhile isSpaceOrEmpty rest of+ [] -> []+ (x:xs) -> Space : x : cleanup xs+ cleanup ((Str ""):rest) = cleanup rest+ cleanup (x:rest) = x : cleanup rest++isSpaceOrEmpty :: Inline -> Bool+isSpaceOrEmpty Space = True+isSpaceOrEmpty (Str "") = True+isSpaceOrEmpty _ = False++-- | Extract the leading and trailing spaces from inside an inline element+-- and place them outside the element.++extractSpaces :: (Inlines -> Inlines) -> Inlines -> Inlines+extractSpaces f is =+ let contents = B.unMany is+ left = case viewl contents of+ (Space :< _) -> B.space+ _ -> mempty+ right = case viewr contents of+ (_ :> Space) -> B.space+ _ -> mempty in+ (left <> f (B.trimInlines . B.Many $ contents) <> right)++-- | Normalize @Pandoc@ document, consolidating doubled 'Space's,+-- combining adjacent 'Str's and 'Emph's, remove 'Null's and+-- empty elements, etc.+normalize :: Pandoc -> Pandoc+normalize (Pandoc (Meta meta) blocks) =+ Pandoc (Meta $ M.map go meta) (normalizeBlocks blocks)+ where go (MetaInlines xs) = MetaInlines $ normalizeInlines xs+ go (MetaBlocks xs) = MetaBlocks $ normalizeBlocks xs+ go (MetaList ms) = MetaList $ map go ms+ go (MetaMap m) = MetaMap $ M.map go m+ go x = x++normalizeBlocks :: [Block] -> [Block]+normalizeBlocks (Null : xs) = normalizeBlocks xs+normalizeBlocks (Div attr bs : xs) =+ Div attr (normalizeBlocks bs) : normalizeBlocks xs+normalizeBlocks (BlockQuote bs : xs) =+ case normalizeBlocks bs of+ [] -> normalizeBlocks xs+ bs' -> BlockQuote bs' : normalizeBlocks xs+normalizeBlocks (BulletList [] : xs) = normalizeBlocks xs+normalizeBlocks (BulletList items : xs) =+ BulletList (map normalizeBlocks items) : normalizeBlocks xs+normalizeBlocks (OrderedList _ [] : xs) = normalizeBlocks xs+normalizeBlocks (OrderedList attr items : xs) =+ OrderedList attr (map normalizeBlocks items) : normalizeBlocks xs+normalizeBlocks (DefinitionList [] : xs) = normalizeBlocks xs+normalizeBlocks (DefinitionList items : xs) =+ DefinitionList (map go items) : normalizeBlocks xs+ where go (ils, bs) = (normalizeInlines ils, map normalizeBlocks bs)+normalizeBlocks (RawBlock _ "" : xs) = normalizeBlocks xs+normalizeBlocks (RawBlock f x : xs) =+ case normalizeBlocks xs of+ (RawBlock f' x' : rest) | f' == f ->+ RawBlock f (x ++ ('\n':x')) : rest+ rest -> RawBlock f x : rest+normalizeBlocks (Para ils : xs) =+ case normalizeInlines ils of+ [] -> normalizeBlocks xs+ ils' -> Para ils' : normalizeBlocks xs+normalizeBlocks (Plain ils : xs) =+ case normalizeInlines ils of+ [] -> normalizeBlocks xs+ ils' -> Plain ils' : normalizeBlocks xs+normalizeBlocks (Header lev attr ils : xs) =+ Header lev attr (normalizeInlines ils) : normalizeBlocks xs+normalizeBlocks (Table capt aligns widths hdrs rows : xs) =+ Table (normalizeInlines capt) aligns widths+ (map normalizeBlocks hdrs) (map (map normalizeBlocks) rows)+ : normalizeBlocks xs+normalizeBlocks (ImageGrid imgs : xs) =+ ImageGrid (map normalizeInlines imgs) : normalizeBlocks xs+normalizeBlocks (Figure typ attr content pc capt : xs) =+ Figure typ attr (normalizeBlocks content) pc (normalizeInlines capt)+ : normalizeBlocks xs+normalizeBlocks (x:xs) = x : normalizeBlocks xs+normalizeBlocks [] = []++normalizeInlines :: [Inline] -> [Inline]+normalizeInlines (Str x : ys) =+ case concat (x : map fromStr strs) of+ "" -> rest+ n -> Str n : rest+ where+ (strs, rest) = span isStr $ normalizeInlines ys+ isStr (Str _) = True+ isStr _ = False+ fromStr (Str z) = z+ fromStr _ = error "normalizeInlines - fromStr - not a Str"+normalizeInlines (Space : ys) =+ if null rest+ then []+ else Space : rest+ where isSp Space = True+ isSp _ = False+ rest = dropWhile isSp $ normalizeInlines ys+normalizeInlines (Emph xs : zs) =+ case normalizeInlines zs of+ (Emph ys : rest) -> normalizeInlines $+ Emph (normalizeInlines $ xs ++ ys) : rest+ rest -> case normalizeInlines xs of+ [] -> rest+ xs' -> Emph xs' : rest+normalizeInlines (Strong xs : zs) =+ case normalizeInlines zs of+ (Strong ys : rest) -> normalizeInlines $+ Strong (normalizeInlines $ xs ++ ys) : rest+ rest -> case normalizeInlines xs of+ [] -> rest+ xs' -> Strong xs' : rest+normalizeInlines (Subscript xs : zs) =+ case normalizeInlines zs of+ (Subscript ys : rest) -> normalizeInlines $+ Subscript (normalizeInlines $ xs ++ ys) : rest+ rest -> case normalizeInlines xs of+ [] -> rest+ xs' -> Subscript xs' : rest+normalizeInlines (Superscript xs : zs) =+ case normalizeInlines zs of+ (Superscript ys : rest) -> normalizeInlines $+ Superscript (normalizeInlines $ xs ++ ys) : rest+ rest -> case normalizeInlines xs of+ [] -> rest+ xs' -> Superscript xs' : rest+normalizeInlines (SmallCaps xs : zs) =+ case normalizeInlines zs of+ (SmallCaps ys : rest) -> normalizeInlines $+ SmallCaps (normalizeInlines $ xs ++ ys) : rest+ rest -> case normalizeInlines xs of+ [] -> rest+ xs' -> SmallCaps xs' : rest+normalizeInlines (Strikeout xs : zs) =+ case normalizeInlines zs of+ (Strikeout ys : rest) -> normalizeInlines $+ Strikeout (normalizeInlines $ xs ++ ys) : rest+ rest -> case normalizeInlines xs of+ [] -> rest+ xs' -> Strikeout xs' : rest+normalizeInlines (RawInline _ [] : ys) = normalizeInlines ys+normalizeInlines (RawInline f xs : zs) =+ case normalizeInlines zs of+ (RawInline f' ys : rest) | f == f' -> normalizeInlines $+ RawInline f (xs ++ ys) : rest+ rest -> RawInline f xs : rest+normalizeInlines (Code _ "" : ys) = normalizeInlines ys+normalizeInlines (Code attr xs : zs) =+ case normalizeInlines zs of+ (Code attr' ys : rest) | attr == attr' -> normalizeInlines $+ Code attr (xs ++ ys) : rest+ rest -> Code attr xs : rest+-- allow empty spans, they may carry identifiers etc.+-- normalizeInlines (Span _ [] : ys) = normalizeInlines ys+normalizeInlines (Span attr xs : zs) =+ case normalizeInlines zs of+ (Span attr' ys : rest) | attr == attr' -> normalizeInlines $+ Span attr (normalizeInlines $ xs ++ ys) : rest+ rest -> Span attr (normalizeInlines xs) : rest+normalizeInlines (Note bs : ys) = Note (normalizeBlocks bs) :+ normalizeInlines ys+normalizeInlines (Quoted qt ils : ys) =+ Quoted qt (normalizeInlines ils) : normalizeInlines ys+normalizeInlines (Link ils t : ys) =+ Link (normalizeInlines ils) t : normalizeInlines ys+normalizeInlines (Image attr ils t : ys) =+ Image attr (normalizeInlines ils) t : normalizeInlines ys+normalizeInlines (Cite cs ils : ys) =+ Cite cs (normalizeInlines ils) : normalizeInlines ys+normalizeInlines (x : xs) = x : normalizeInlines xs+normalizeInlines [] = []++-- | Extract inlines, removing formatting.+removeFormatting :: Walkable Inline a => a -> [Inline]+removeFormatting = query go . walk deNote+ where go :: Inline -> [Inline]+ go (Str xs) = [Str xs]+ go Space = [Space]+ go (Code _ x) = [Str x]+ go (Math _ x) = [Str x]+ go LineBreak = [Space]+ go _ = []+ deNote (Note _) = Str ""+ deNote x = x++-- | Convert pandoc structure to a string with formatting removed.+-- Footnotes are skipped (since we don't want their contents in link+-- labels).+stringify :: Walkable Inline a => a -> String+stringify = query go . walk deNote+ where go :: Inline -> [Char]+ go Space = " "+ go (Str x) = x+ go (Code _ x) = x+ go (Math _ x) = x+ go LineBreak = " "+ go _ = ""+ deNote (Note _) = Str ""+ deNote x = x++-- | Bring all regular text in a pandoc structure to uppercase.+--+-- This function correctly handles cases where a lowercase character doesn't+-- match to a single uppercase character – e.g. “Straße” would be converted+-- to “STRASSE”, not “STRAßE”.+capitalize :: Walkable Inline a => a -> a+capitalize = walk go+ where go :: Inline -> Inline+ go (Str s) = Str (T.unpack $ T.toUpper $ T.pack s)+ go x = x++-- | Change final list item from @Para@ to @Plain@ if the list contains+-- no other @Para@ blocks.+compactify :: [[Block]] -- ^ List of list items (each a list of blocks)+ -> [[Block]]+compactify [] = []+compactify items =+ case (init items, last items) of+ (_,[]) -> items+ (others, final) ->+ case last final of+ Para a -> case (filter isPara $ concat items) of+ -- if this is only Para, change to Plain+ [_] -> others ++ [init final ++ [Plain a]]+ _ -> items+ _ -> items++-- | Change final list item from @Para@ to @Plain@ if the list contains+-- no other @Para@ blocks. Like compactify, but operates on @Blocks@ rather+-- than @[Block]@.+compactify' :: [Blocks] -- ^ List of list items (each a list of blocks)+ -> [Blocks]+compactify' [] = []+compactify' items =+ let (others, final) = (init items, last items)+ in case reverse (B.toList final) of+ (Para a:xs) -> case [Para x | Para x <- concatMap B.toList items] of+ -- if this is only Para, change to Plain+ [_] -> others ++ [B.fromList (reverse $ Plain a : xs)]+ _ -> items+ _ -> items++-- | Like @compactify'@, but acts on items of definition lists.+compactify'DL :: [(Inlines, [Blocks])] -> [(Inlines, [Blocks])]+compactify'DL items =+ let defs = concatMap snd items+ in case reverse (concatMap B.toList defs) of+ (Para x:xs)+ | not (any isPara xs) ->+ let (t,ds) = last items+ lastDef = B.toList $ last ds+ ds' = init ds +++ if null lastDef+ then [B.fromList lastDef]+ else [B.fromList $ init lastDef ++ [Plain x]]+ in init items ++ [(t, ds')]+ | otherwise -> items+ _ -> items++isPara :: Block -> Bool+isPara (Para _) = True+isPara _ = False++-- | Data structure for defining hierarchical Pandoc documents+data Element = Blk Block+ | Sec Int [Int] Attr [Inline] [Element]+ -- lvl num attributes label contents+ deriving (Eq, Read, Show, Typeable, Data)++instance Walkable Inline Element where+ walk f (Blk x) = Blk (walk f x)+ walk f (Sec lev nums attr ils elts) = Sec lev nums attr (walk f ils) (walk f elts)+ walkM f (Blk x) = Blk `fmap` walkM f x+ walkM f (Sec lev nums attr ils elts) = do+ ils' <- walkM f ils+ elts' <- walkM f elts+ return $ Sec lev nums attr ils' elts'+ query f (Blk x) = query f x+ query f (Sec _ _ _ ils elts) = query f ils <> query f elts++instance Walkable Block Element where+ walk f (Blk x) = Blk (walk f x)+ walk f (Sec lev nums attr ils elts) = Sec lev nums attr (walk f ils) (walk f elts)+ walkM f (Blk x) = Blk `fmap` walkM f x+ walkM f (Sec lev nums attr ils elts) = do+ ils' <- walkM f ils+ elts' <- walkM f elts+ return $ Sec lev nums attr ils' elts'+ query f (Blk x) = query f x+ query f (Sec _ _ _ ils elts) = query f ils <> query f elts+++-- | Convert Pandoc inline list to plain text identifier. HTML+-- identifiers must start with a letter, and may contain only+-- letters, digits, and the characters _-.+inlineListToIdentifier :: [Inline] -> String+inlineListToIdentifier =+ dropWhile (not . isAlpha) . intercalate "-" . words .+ map (nbspToSp . toLower) .+ filter (\c -> isLetter c || isDigit c || c `elem` "_-. ") .+ stringify+ where nbspToSp '\160' = ' '+ nbspToSp x = x++-- | Convert list of Pandoc blocks into (hierarchical) list of Elements+hierarchicalize :: [Block] -> [Element]+hierarchicalize blocks = S.evalState (hierarchicalizeWithIds blocks) []++hierarchicalizeWithIds :: [Block] -> S.State [Int] [Element]+hierarchicalizeWithIds [] = return []+hierarchicalizeWithIds ((Header level attr@(_,classes,_) title'):xs) = do+ lastnum <- S.get+ let lastnum' = take level lastnum+ let newnum = case length lastnum' of+ x | "unnumbered" `elem` classes -> []+ | x >= level -> init lastnum' ++ [last lastnum' + 1]+ | otherwise -> lastnum +++ replicate (level - length lastnum - 1) 0 ++ [1]+ unless (null newnum) $ S.put newnum+ let (sectionContents, rest) = break (headerLtEq level) xs+ sectionContents' <- hierarchicalizeWithIds sectionContents+ rest' <- hierarchicalizeWithIds rest+ return $ Sec level newnum attr title' sectionContents' : rest'+hierarchicalizeWithIds (x:rest) = do+ rest' <- hierarchicalizeWithIds rest+ return $ (Blk x) : rest'++headerLtEq :: Int -> Block -> Bool+headerLtEq level (Header l _ _) = l <= level+headerLtEq _ _ = False++-- | Generate a unique identifier from a list of inlines.+-- Second argument is a list of already used identifiers.+uniqueIdent :: [Inline] -> [String] -> String+uniqueIdent title' usedIdents =+ let baseIdent = case inlineListToIdentifier title' of+ "" -> "section"+ x -> x+ numIdent n = baseIdent ++ "-" ++ show n+ in if baseIdent `elem` usedIdents+ then case find (\x -> numIdent x `notElem` usedIdents) ([1..60000] :: [Int]) of+ Just x -> numIdent x+ Nothing -> baseIdent -- if we have more than 60,000, allow repeats+ else baseIdent++-- | gives 1 -> a, 2 -> b, etc...+alphEnum :: Int -> String+alphEnum n = [chr (ord 'a' + n - 1)]++-- | True if block is a Header block.+isHeaderBlock :: Block -> Bool+isHeaderBlock (Header _ _ _) = True+isHeaderBlock _ = False++-- | Shift header levels up or down.+headerShift :: Int -> Pandoc -> Pandoc+headerShift n = walk shift+ where shift :: Block -> Block+ shift (Header level attr inner) = Header (level + n) attr inner+ shift x = x++-- | Detect if a list is tight.+isTightList :: [[Block]] -> Bool+isTightList = all firstIsPlain+ where firstIsPlain (Plain _ : _) = True+ firstIsPlain _ = False++-- | Set a field of a 'Meta' object. If the field already has a value,+-- convert it into a list with the new value appended to the old value(s).+addMetaField :: ToMetaValue a+ => String+ -> a+ -> Meta+ -> Meta+addMetaField key val (Meta meta) =+ Meta $ M.insertWith combine key (toMetaValue val) meta+ where combine newval (MetaList xs) = MetaList (xs ++ tolist newval)+ combine newval x = MetaList [x, newval]+ tolist (MetaList ys) = ys+ tolist y = [y]++-- | Create 'Meta' from old-style title, authors, date. This is+-- provided to ease the transition from the old API.+makeMeta :: [Inline] -> [[Inline]] -> [Inline] -> Meta+makeMeta title authors date =+ addMetaField "title" (B.fromList title)+ $ addMetaField "author" (map B.fromList authors)+ $ addMetaField "date" (B.fromList date)+ $ nullMeta++--+-- TagSoup HTML handling+--++-- | Render HTML tags.+renderTags' :: [Tag String] -> String+renderTags' = renderTagsOptions+ renderOptions{ optMinimize = matchTags ["hr", "br", "img",+ "meta", "link"]+ , optRawTag = matchTags ["script", "style"] }+ where matchTags = \tags -> flip elem tags . map toLower++--+-- File handling+--++-- | Perform an IO action in a directory, returning to starting directory.+inDirectory :: FilePath -> IO a -> IO a+inDirectory path action = E.bracket+ getCurrentDirectory+ setCurrentDirectory+ (const $ setCurrentDirectory path >> action)++readDefaultDataFile :: FilePath -> IO BS.ByteString+readDefaultDataFile fname =+#ifdef EMBED_DATA_FILES+ case lookup (makeCanonical fname) dataFiles of+ Nothing -> err 97 $ "Could not find data file " ++ fname+ Just contents -> return contents+ where makeCanonical = joinPath . transformPathParts . splitDirectories+ transformPathParts = reverse . foldl go []+ go as "." = as+ go (_:as) ".." = as+ go as x = x : as+#else+ getDataFileName ("data" </> fname) >>= checkExistence >>= BS.readFile+ where checkExistence fn = do+ exists <- doesFileExist fn+ if exists+ then return fn+ else err 97 ("Could not find data file " ++ fname)+#endif++-- | Read file from specified user data directory or, if not found there, from+-- Cabal data directory.+readDataFile :: Maybe FilePath -> FilePath -> IO BS.ByteString+readDataFile Nothing fname = readDefaultDataFile fname+readDataFile (Just userDir) fname = do+ exists <- doesFileExist (userDir </> fname)+ if exists+ then BS.readFile (userDir </> fname)+ else readDefaultDataFile fname++-- | Same as 'readDataFile' but returns a String instead of a ByteString.+readDataFileUTF8 :: Maybe FilePath -> FilePath -> IO String+readDataFileUTF8 userDir fname =+ UTF8.toString `fmap` readDataFile userDir fname++-- | Fetch an image or other item from the local filesystem or the net.+-- Returns raw content and maybe mime type.+fetchItem :: Maybe String -> String+ -> IO (Either E.SomeException (BS.ByteString, Maybe MimeType))+fetchItem sourceURL s =+ case (sourceURL >>= parseURIReference . ensureEscaped, ensureEscaped s) of+ (_, s') | isURI s' -> openURL s'+ (Just u, s') -> -- try fetching from relative path at source+ case parseURIReference s' of+ Just u' -> openURL $ show $ u' `nonStrictRelativeTo` u+ Nothing -> openURL s' -- will throw error+ (Nothing, _) -> E.try readLocalFile -- get from local file system+ where readLocalFile = do+ cont <- BS.readFile fp+ return (cont, mime)+ dropFragmentAndQuery = takeWhile (\c -> c /= '?' && c /= '#')+ fp = unEscapeString $ dropFragmentAndQuery s+ mime = case takeExtension fp of+ ".gz" -> getMimeType $ dropExtension fp+ x -> getMimeType x+ ensureEscaped x@(_:':':'\\':_) = x -- likely windows path+ ensureEscaped x = escapeURIString isAllowedInURI x++-- | Like 'fetchItem', but also looks for items in a 'MediaBag'.+fetchItem' :: MediaBag -> Maybe String -> String+ -> IO (Either E.SomeException (BS.ByteString, Maybe MimeType))+fetchItem' media sourceURL s = do+ case lookupMedia s media of+ Nothing -> fetchItem sourceURL s+ Just (mime, bs) -> return $ Right (BS.concat $ toChunks bs, Just mime)++-- | Read from a URL and return raw data and maybe mime type.+openURL :: String -> IO (Either E.SomeException (BS.ByteString, Maybe MimeType))+openURL u+ | Just u' <- stripPrefix "data:" u =+ let mime = takeWhile (/=',') u'+ contents = B8.pack $ unEscapeString $ drop 1 $ dropWhile (/=',') u'+ in return $ Right (decodeLenient contents, Just mime)+#ifdef HTTP_CLIENT+ | otherwise = withSocketsDo $ E.try $ do+ req <- parseUrl u+ (proxy :: Either E.SomeException String) <- E.try $ getEnv "http_proxy"+ let req' = case proxy of+ Left _ -> req+ Right pr -> case parseUrl pr of+ Just r -> addProxy (host r) (port r) req+ Nothing -> req+ resp <- withManager tlsManagerSettings $ httpLbs req'+ return (BS.concat $ toChunks $ responseBody resp,+ UTF8.toString `fmap` lookup hContentType (responseHeaders resp))+#else+ | otherwise = E.try $ getBodyAndMimeType `fmap` browse+ (do S.liftIO $ UTF8.hPutStrLn stderr $ "Fetching " ++ u ++ "..."+ setOutHandler $ const (return ())+ setAllowRedirects True+ request (getRequest' u'))+ where getBodyAndMimeType (_, r) = (rspBody r, findHeader HdrContentType r)+ getRequest' uriString = case parseURI uriString of+ Nothing -> error ("Not a valid URL: " +++ uriString)+ Just v -> mkRequest GET v+ u' = escapeURIString (/= '|') u -- pipes are rejected by Network.URI+#endif++--+-- Error reporting+--++err :: Int -> String -> IO a+err exitCode msg = do+ name <- getProgName+ UTF8.hPutStrLn stderr $ name ++ ": " ++ msg+ exitWith $ ExitFailure exitCode+ return undefined++warn :: String -> IO ()+warn msg = do+ name <- getProgName+ UTF8.hPutStrLn stderr $ name ++ ": " ++ msg++-- | Remove intermediate "." and ".." directories from a path.+--+-- > collapseFilePath "./foo" == "foo"+-- > collapseFilePath "/bar/../baz" == "/baz"+-- > collapseFilePath "/../baz" == "/../baz"+-- > collapseFilePath "parent/foo/baz/../bar" == "parent/foo/bar"+-- > collapseFilePath "parent/foo/baz/../../bar" == "parent/bar"+-- > collapseFilePath "parent/foo/.." == "parent"+-- > collapseFilePath "/parent/foo/../../bar" == "/bar"+collapseFilePath :: FilePath -> FilePath+collapseFilePath = joinPath . reverse . foldl go [] . splitDirectories+ where+ go rs "." = rs+ go r@(p:rs) ".." = case p of+ ".." -> ("..":r)+ (checkPathSeperator -> Just True) -> ("..":r)+ _ -> rs+ go _ (checkPathSeperator -> Just True) = [[pathSeparator]]+ go rs x = x:rs+ isSingleton [] = Nothing+ isSingleton [x] = Just x+ isSingleton _ = Nothing+ checkPathSeperator = fmap isPathSeparator . isSingleton++--+-- Safe read+--++safeRead :: (Monad m, Read a) => String -> m a+safeRead s = case reads s of+ (d,x):_+ | all isSpace x -> return d+ _ -> fail $ "Could not read `" ++ s ++ "'"++--+-- Temp directory+--++withTempDir :: String -> (FilePath -> IO a) -> IO a+withTempDir =+#ifdef _WINDOWS+ withTempDirectory "."+#else+ withSystemTempDirectory+#endif
@@ -0,0 +1,63 @@+{-+Copyright (C) 2012-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Slides+ Copyright : Copyright (C) 2012-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Utility functions for splitting documents into slides for slide+show formats (dzslides, revealjs, s5, slidy, slideous, beamer).+-}+module Text.Pandoc.Slides ( getSlideLevel, prepSlides ) where+import Text.Pandoc.Definition++-- | Find level of header that starts slides (defined as the least header+-- level that occurs before a non-header/non-hrule in the blocks).+getSlideLevel :: [Block] -> Int+getSlideLevel = go 6+ where go least (Header n _ _ : x : xs)+ | n < least && nonHOrHR x = go n xs+ | otherwise = go least (x:xs)+ go least (_ : xs) = go least xs+ go least [] = least+ nonHOrHR (Header _ _ _) = False+ nonHOrHR (HorizontalRule) = False+ nonHOrHR _ = True++-- | Prepare a block list to be passed to hierarchicalize.+prepSlides :: Int -> [Block] -> [Block]+prepSlides slideLevel = ensureStartWithH . splitHrule . extractRefsHeader+ where splitHrule (HorizontalRule : Header n attr xs : ys)+ | n == slideLevel = Header slideLevel attr xs : splitHrule ys+ splitHrule (HorizontalRule : xs) = Header slideLevel nullAttr [Str "\0"] :+ splitHrule xs+ splitHrule (x : xs) = x : splitHrule xs+ splitHrule [] = []+ extractRefsHeader bs =+ case reverse bs of+ (Div ("",["references"],[]) (Header n attrs xs : ys) : zs)+ -> reverse zs ++ (Header n attrs xs : [Div ("",["references"],[]) ys])+ _ -> bs+ ensureStartWithH bs@(Header n _ _:_)+ | n <= slideLevel = bs+ ensureStartWithH bs = Header slideLevel nullAttr [Str "\0"] : bs
@@ -0,0 +1,328 @@+{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, CPP,+ OverloadedStrings, GeneralizedNewtypeDeriving #-}+{-+Copyright (C) 2009-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Templates+ Copyright : Copyright (C) 2009-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++A simple templating system with variable substitution and conditionals.+The following program illustrates its use:++> {-# LANGUAGE OverloadedStrings #-}+> import Data.Text+> import Data.Aeson+> import Text.Pandoc.Templates+>+> data Employee = Employee { firstName :: String+> , lastName :: String+> , salary :: Maybe Int }+> instance ToJSON Employee where+> toJSON e = object [ "name" .= object [ "first" .= firstName e+> , "last" .= lastName e ]+> , "salary" .= salary e ]+>+> employees :: [Employee]+> employees = [ Employee "John" "Doe" Nothing+> , Employee "Omar" "Smith" (Just 30000)+> , Employee "Sara" "Chen" (Just 60000) ]+>+> template :: Template+> template = either error id $ compileTemplate+> "$for(employee)$Hi, $employee.name.first$. $if(employee.salary)$You make $employee.salary$.$else$No salary data.$endif$$sep$\n$endfor$"+>+> main = putStrLn $ renderTemplate template $ object ["employee" .= employees ]++A slot for an interpolated variable is a variable name surrounded+by dollar signs. To include a literal @$@ in your template, use+@$$@. Variable names must begin with a letter and can contain letters,+numbers, @_@, @-@, and @.@.++The values of variables are determined by a JSON object that is+passed as a parameter to @renderTemplate@. So, for example,+@title@ will return the value of the @title@ field, and+@employee.salary@ will return the value of the @salary@ field+of the object that is the value of the @employee@ field.++The value of a variable will be indented to the same level as the+variable.++A conditional begins with @$if(variable_name)$@ and ends with @$endif$@.+It may optionally contain an @$else$@ section. The if section is+used if @variable_name@ has a non-null value, otherwise the else section+is used.++Conditional keywords should not be indented, or unexpected spacing+problems may occur.++The @$for$@ keyword can be used to iterate over an array. If+the value of the associated variable is not an array, a single+iteration will be performed on its value.++You may optionally specify separators using @$sep$@, as in the+example above.++-}++module Text.Pandoc.Templates ( renderTemplate+ , renderTemplate'+ , TemplateTarget(..)+ , varListToJSON+ , compileTemplate+ , Template+ , getDefaultTemplate ) where++import Data.Char (isAlphaNum)+import Control.Monad (guard, when)+import Data.Aeson (ToJSON(..), Value(..))+import qualified Text.Parsec as P+import Text.Parsec.Text (Parser)+import Control.Applicative+import qualified Data.Text as T+import Data.Text (Text)+import Data.Text.Encoding (encodeUtf8)+import Text.Pandoc.Compat.Monoid ((<>), Monoid(..))+import Data.List (intersperse)+import System.FilePath ((</>), (<.>))+import qualified Data.Map as M+import qualified Data.HashMap.Strict as H+import Data.Foldable (toList)+import qualified Control.Exception.Extensible as E (try, IOException)+#if MIN_VERSION_blaze_html(0,5,0)+import Text.Blaze.Html (Html)+import Text.Blaze.Internal (preEscapedText)+#else+import Text.Blaze (preEscapedText, Html)+#endif+import Data.ByteString.Lazy (ByteString, fromChunks)+import Text.Pandoc.Shared (readDataFileUTF8, ordNub)+import Data.Vector ((!?))++-- | Get default template for the specified writer.+getDefaultTemplate :: (Maybe FilePath) -- ^ User data directory to search first+ -> String -- ^ Name of writer+ -> IO (Either E.IOException String)+getDefaultTemplate user writer = do+ let format = takeWhile (`notElem` "+-") writer -- strip off extensions+ case format of+ "native" -> return $ Right ""+ "json" -> return $ Right ""+ "docx" -> return $ Right ""+ "odt" -> getDefaultTemplate user "opendocument"+ "markdown_strict" -> getDefaultTemplate user "markdown"+ "multimarkdown" -> getDefaultTemplate user "markdown"+ "markdown_github" -> getDefaultTemplate user "markdown"+ "markdown_mmd" -> getDefaultTemplate user "markdown"+ "markdown_phpextra" -> getDefaultTemplate user "markdown"+ _ -> let fname = "templates" </> "default" <.> format+ in E.try $ readDataFileUTF8 user fname++newtype Template = Template { unTemplate :: Value -> Text }+ deriving Monoid++type Variable = [Text]++class TemplateTarget a where+ toTarget :: Text -> a++instance TemplateTarget Text where+ toTarget = id++instance TemplateTarget String where+ toTarget = T.unpack++instance TemplateTarget ByteString where+ toTarget = fromChunks . (:[]) . encodeUtf8++instance TemplateTarget Html where+ toTarget = preEscapedText++varListToJSON :: [(String, String)] -> Value+varListToJSON assoc = toJSON $ M.fromList assoc'+ where assoc' = [(T.pack k, toVal [T.pack z | (y,z) <- assoc,+ not (null z),+ y == k])+ | k <- ordNub $ map fst assoc ]+ toVal [x] = toJSON x+ toVal [] = Null+ toVal xs = toJSON xs++renderTemplate :: (ToJSON a, TemplateTarget b) => Template -> a -> b+renderTemplate (Template f) context = toTarget $ f $ toJSON context++compileTemplate :: Text -> Either String Template+compileTemplate template =+ case P.parse (pTemplate <* P.eof) "template" template of+ Left e -> Left (show e)+ Right x -> Right x++-- | Like 'renderTemplate', but compiles the template first,+-- raising an error if compilation fails.+renderTemplate' :: (ToJSON a, TemplateTarget b) => String -> a -> b+renderTemplate' template =+ renderTemplate (either error id $ compileTemplate $ T.pack template)++var :: Variable -> Template+var = Template . resolveVar++resolveVar :: Variable -> Value -> Text+resolveVar var' val =+ case multiLookup var' val of+ Just (Array vec) -> maybe mempty (resolveVar []) $ vec !? 0+ Just (String t) -> T.stripEnd t+ Just (Number n) -> T.pack $ show n+ Just (Bool True) -> "true"+ Just (Object _) -> "true"+ Just _ -> mempty+ Nothing -> mempty++multiLookup :: [Text] -> Value -> Maybe Value+multiLookup [] x = Just x+multiLookup (v:vs) (Object o) = H.lookup v o >>= multiLookup vs+multiLookup _ _ = Nothing++lit :: Text -> Template+lit = Template . const++cond :: Variable -> Template -> Template -> Template+cond var' (Template ifyes) (Template ifno) = Template $ \val ->+ case resolveVar var' val of+ "" -> ifno val+ _ -> ifyes val++iter :: Variable -> Template -> Template -> Template+iter var' template sep = Template $ \val -> unTemplate+ (case multiLookup var' val of+ Just (Array vec) -> mconcat $ intersperse sep+ $ map (setVar template var')+ $ toList vec+ Just x -> cond var' (setVar template var' x) mempty+ Nothing -> mempty) val++setVar :: Template -> Variable -> Value -> Template+setVar (Template f) var' val = Template $ f . replaceVar var' val++replaceVar :: Variable -> Value -> Value -> Value+replaceVar [] new _ = new+replaceVar (v:vs) new (Object o) =+ Object $ H.adjust (\x -> replaceVar vs new x) v o+replaceVar _ _ old = old++--- parsing++pTemplate :: Parser Template+pTemplate = do+ sp <- P.option mempty pInitialSpace+ rest <- mconcat <$> many (pConditional <|>+ pFor <|>+ pNewline <|>+ pVar <|>+ pLit <|>+ pEscapedDollar)+ return $ sp <> rest++takeWhile1 :: (Char -> Bool) -> Parser Text+takeWhile1 f = T.pack <$> P.many1 (P.satisfy f)++pLit :: Parser Template+pLit = lit <$> takeWhile1 (\x -> x /='$' && x /= '\n')++pNewline :: Parser Template+pNewline = do+ P.char '\n'+ sp <- P.option mempty pInitialSpace+ return $ lit "\n" <> sp++pInitialSpace :: Parser Template+pInitialSpace = do+ sps <- takeWhile1 (==' ')+ let indentVar = if T.null sps+ then id+ else indent (T.length sps)+ v <- P.option mempty $ indentVar <$> pVar+ return $ lit sps <> v++pEscapedDollar :: Parser Template+pEscapedDollar = lit "$" <$ P.try (P.string "$$")++pVar :: Parser Template+pVar = var <$> (P.try $ P.char '$' *> pIdent <* P.char '$')++pIdent :: Parser [Text]+pIdent = do+ first <- pIdentPart+ rest <- many (P.char '.' *> pIdentPart)+ return (first:rest)++pIdentPart :: Parser Text+pIdentPart = P.try $ do+ first <- P.letter+ rest <- T.pack <$> P.many (P.satisfy (\c -> isAlphaNum c || c == '_' || c == '-'))+ let id' = T.singleton first <> rest+ guard $ id' `notElem` reservedWords+ return id'++reservedWords :: [Text]+reservedWords = ["else","endif","for","endfor","sep"]++skipEndline :: Parser ()+skipEndline = P.try $ P.skipMany (P.satisfy (`elem` " \t")) >> P.char '\n' >> return ()++pConditional :: Parser Template+pConditional = do+ P.try $ P.string "$if("+ id' <- pIdent+ P.string ")$"+ -- if newline after the "if", then a newline after "endif" will be swallowed+ multiline <- P.option False (True <$ skipEndline)+ ifContents <- pTemplate+ elseContents <- P.option mempty $ P.try $+ do P.string "$else$"+ when multiline $ P.option () skipEndline+ pTemplate+ P.string "$endif$"+ when multiline $ P.option () skipEndline+ return $ cond id' ifContents elseContents++pFor :: Parser Template+pFor = do+ P.try $ P.string "$for("+ id' <- pIdent+ P.string ")$"+ -- if newline after the "for", then a newline after "endfor" will be swallowed+ multiline <- P.option False $ skipEndline >> return True+ contents <- pTemplate+ sep <- P.option mempty $+ do P.try $ P.string "$sep$"+ when multiline $ P.option () skipEndline+ pTemplate+ P.string "$endfor$"+ when multiline $ P.option () skipEndline+ return $ iter id' contents sep++indent :: Int -> Template -> Template+indent 0 x = x+indent ind (Template f) = Template $ \val -> indent' (f val)+ where indent' t = T.concat+ $ intersperse ("\n" <> T.replicate ind " ") $ T.lines t
@@ -0,0 +1,120 @@+{-# LANGUAGE CPP #-}+{-+Copyright (C) 2010-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.UTF8+ Copyright : Copyright (C) 2010-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++UTF-8 aware string IO functions that will work with GHC 6.10, 6.12, or 7.+-}+module Text.Pandoc.UTF8 ( readFile+ , writeFile+ , getContents+ , putStr+ , putStrLn+ , hPutStr+ , hPutStrLn+ , hGetContents+ , toString+ , fromString+ , toStringLazy+ , fromStringLazy+ , encodePath+ , decodeArg+ )++where++import System.IO hiding (readFile, writeFile, getContents,+ putStr, putStrLn, hPutStr, hPutStrLn, hGetContents)+import Prelude hiding (readFile, writeFile, getContents, putStr, putStrLn)+import qualified System.IO as IO+import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Lazy as BL+import qualified Data.Text.Encoding as T+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.Encoding as TL++readFile :: FilePath -> IO String+readFile f = do+ h <- openFile (encodePath f) ReadMode+ hGetContents h++writeFile :: FilePath -> String -> IO ()+writeFile f s = withFile (encodePath f) WriteMode $ \h -> hPutStr h s++getContents :: IO String+getContents = hGetContents stdin++putStr :: String -> IO ()+putStr s = hPutStr stdout s++putStrLn :: String -> IO ()+putStrLn s = hPutStrLn stdout s++hPutStr :: Handle -> String -> IO ()+hPutStr h s = hSetEncoding h utf8 >> IO.hPutStr h s++hPutStrLn :: Handle -> String -> IO ()+hPutStrLn h s = hSetEncoding h utf8 >> IO.hPutStrLn h s++hGetContents :: Handle -> IO String+hGetContents = fmap toString . B.hGetContents+-- hGetContents h = hSetEncoding h utf8_bom+-- >> hSetNewlineMode h universalNewlineMode+-- >> IO.hGetContents h++-- | Drop BOM (byte order marker) if present at beginning of string.+-- Note that Data.Text converts the BOM to code point FEFF, zero-width+-- no-break space, so if the string begins with this we strip it off.+dropBOM :: String -> String+dropBOM ('\xFEFF':xs) = xs+dropBOM xs = xs++-- | Convert UTF8-encoded ByteString to String, also+-- removing '\r' characters.+toString :: B.ByteString -> String+toString = filter (/='\r') . dropBOM . T.unpack . T.decodeUtf8++fromString :: String -> B.ByteString+fromString = T.encodeUtf8 . T.pack++-- | Convert UTF8-encoded ByteString to String, also+-- removing '\r' characters.+toStringLazy :: BL.ByteString -> String+toStringLazy = filter (/='\r') . dropBOM . TL.unpack . TL.decodeUtf8++fromStringLazy :: String -> BL.ByteString+fromStringLazy = TL.encodeUtf8 . TL.pack++encodePath :: FilePath -> FilePath+decodeArg :: String -> String+#if MIN_VERSION_base(4,4,0)+encodePath = id+decodeArg = id+#else+encodePath = B.unpack . fromString+decodeArg = toString . B.pack+#endif
@@ -0,0 +1,77 @@+{-+Copyright (C) 2010-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.UUID+ Copyright : Copyright (C) 2010-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++UUID generation using Version 4 (random method) described+in RFC4122. See http://tools.ietf.org/html/rfc4122+-}++module Text.Pandoc.UUID ( UUID, getRandomUUID ) where++import Text.Printf ( printf )+import System.Random ( randomIO )+import Data.Word+import Data.Bits ( setBit, clearBit )+import Control.Monad ( liftM )++data UUID = UUID Word8 Word8 Word8 Word8 Word8 Word8 Word8 Word8+ Word8 Word8 Word8 Word8 Word8 Word8 Word8 Word8++instance Show UUID where+ show (UUID a b c d e f g h i j k l m n o p) =+ "urn:uuid:" +++ printf "%02x" a +++ printf "%02x" b +++ printf "%02x" c +++ printf "%02x" d +++ "-" +++ printf "%02x" e +++ printf "%02x" f +++ "-" +++ printf "%02x" g +++ printf "%02x" h +++ "-" +++ printf "%02x" i +++ printf "%02x" j +++ "-" +++ printf "%02x" k +++ printf "%02x" l +++ printf "%02x" m +++ printf "%02x" n +++ printf "%02x" o +++ printf "%02x" p++getRandomUUID :: IO UUID+getRandomUUID = do+ let getRN :: a -> IO Word8+ getRN _ = liftM fromIntegral (randomIO :: IO Int)+ [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p] <- mapM getRN ([1..16] :: [Int])+ -- set variant+ let i' = i `setBit` 7 `clearBit` 6+ -- set version (0100 for random)+ let g' = g `clearBit` 7 `setBit` 6 `clearBit` 5 `clearBit` 4+ return $ UUID a b c d e f g' h i' j k l m n o p+
@@ -0,0 +1,336 @@+{-# LANGUAGE OverlappingInstances, FlexibleInstances, OverloadedStrings,+ ScopedTypeVariables #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+{- Copyright (C) 2012-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.Custom+ Copyright : Copyright (C) 2012-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to custom markup using+a lua writer.+-}+module Text.Pandoc.Writers.Custom ( writeCustom ) where+import Text.Pandoc.Definition+import Text.Pandoc.Options+import Data.List ( intersperse )+import Data.Char ( toLower )+import Scripting.Lua (LuaState, StackValue, callfunc)+import Text.Pandoc.Writers.Shared+import qualified Scripting.Lua as Lua+import Text.Pandoc.UTF8 (fromString, toString)+import Data.ByteString (ByteString)+import qualified Data.ByteString.Char8 as C8+import Data.Monoid+import qualified Data.Map as M+import Text.Pandoc.Templates++attrToMap :: Attr -> M.Map ByteString ByteString+attrToMap (id',classes,keyvals) = M.fromList+ $ ("id", fromString id')+ : ("class", fromString $ unwords classes)+ : map (\(x,y) -> (fromString x, fromString y)) keyvals++getList :: StackValue a => LuaState -> Int -> IO [a]+getList lua i' = do+ continue <- Lua.next lua i'+ if continue+ then do+ next <- Lua.peek lua (-1)+ Lua.pop lua 1+ x <- maybe (fail "peek returned Nothing") return next+ rest <- getList lua i'+ return (x : rest)+ else return []++instance StackValue ByteString where+ push l x = Lua.push l $ C8.unpack x+ peek l n = (fmap . fmap) C8.pack (Lua.peek l n)+ valuetype _ = Lua.TSTRING++instance StackValue a => StackValue [a] where+ push lua xs = do+ Lua.createtable lua (length xs + 1) 0+ let addValue (i, x) = Lua.push lua x >> Lua.rawseti lua (-2) i+ mapM_ addValue $ zip [1..] xs+ peek lua i = do+ top <- Lua.gettop lua+ let i' = if i < 0 then top + i + 1 else i+ Lua.pushnil lua+ lst <- getList lua i'+ Lua.pop lua 1+ return (Just lst)+ valuetype _ = Lua.TTABLE++instance StackValue Format where+ push lua (Format f) = Lua.push lua (map toLower f)+ peek l n = fmap Format `fmap` Lua.peek l n+ valuetype _ = Lua.TSTRING++instance (StackValue a, StackValue b) => StackValue (M.Map a b) where+ push lua m = do+ let xs = M.toList m+ Lua.createtable lua (length xs + 1) 0+ let addValue (k, v) = Lua.push lua k >> Lua.push lua v >>+ Lua.rawset lua (-3)+ mapM_ addValue xs+ peek _ _ = undefined -- not needed for our purposes+ valuetype _ = Lua.TTABLE++instance (StackValue a, StackValue b) => StackValue (a,b) where+ push lua (k,v) = do+ Lua.createtable lua 2 0+ Lua.push lua k+ Lua.push lua v+ Lua.rawset lua (-3)+ peek _ _ = undefined -- not needed for our purposes+ valuetype _ = Lua.TTABLE++instance StackValue [Inline] where+ push l ils = Lua.push l . C8.unpack =<< inlineListToCustom l ils+ peek _ _ = undefined+ valuetype _ = Lua.TSTRING++instance StackValue [Block] where+ push l ils = Lua.push l . C8.unpack =<< blockListToCustom l ils+ peek _ _ = undefined+ valuetype _ = Lua.TSTRING++instance StackValue MetaValue where+ push l (MetaMap m) = Lua.push l m+ push l (MetaList xs) = Lua.push l xs+ push l (MetaBool x) = Lua.push l x+ push l (MetaString s) = Lua.push l s+ push l (MetaInlines ils) = Lua.push l ils+ push l (MetaBlocks bs) = Lua.push l bs+ peek _ _ = undefined+ valuetype (MetaMap _) = Lua.TTABLE+ valuetype (MetaList _) = Lua.TTABLE+ valuetype (MetaBool _) = Lua.TBOOLEAN+ valuetype (MetaString _) = Lua.TSTRING+ valuetype (MetaInlines _) = Lua.TSTRING+ valuetype (MetaBlocks _) = Lua.TSTRING++instance StackValue Citation where+ push lua cit = do+ Lua.createtable lua 6 0+ let addValue ((k :: String), v) = Lua.push lua k >> Lua.push lua v >>+ Lua.rawset lua (-3)+ addValue ("citationId", citationId cit)+ addValue ("citationPrefix", citationPrefix cit)+ addValue ("citationSuffix", citationSuffix cit)+ addValue ("citationMode", show (citationMode cit))+ addValue ("citationNoteNum", citationNoteNum cit)+ addValue ("citationHash", citationHash cit)+ peek = undefined+ valuetype _ = Lua.TTABLE++instance StackValue PreparedContent where+ push lua pc = do+ Lua.createtable lua 2 0+ let addValue ((k :: String), v) = Lua.push lua k >> Lua.push lua v >>+ Lua.rawset lua (-3)+ addValue ("preparedImageContent", [preparedImageContent pc])+ addValue ("preparedLaTeXContent", preparedLaTeXContent pc)+ peek = undefined+ valuetype _ = Lua.TTABLE++instance StackValue StatementAttr where+ push lua stmattr = do+ Lua.createtable lua 7 0+ let addValue ((k :: String), v) = Lua.push lua k >> Lua.push lua v >>+ Lua.rawset lua (-3)+ addValue ("statementId", statementId stmattr)+ addValue ("statementStyle", show (statementStyle stmattr))+ addValue ("statementLabel", statementLabel stmattr)+ addValue ("statementCounter", statementCounter stmattr)+ addValue ("statementLevel", statementLevel stmattr)+ addValue ("statementNum", statementNum stmattr)+ addValue ("statementCaption", statementCaption stmattr)+ peek = undefined+ valuetype _ = Lua.TTABLE++instance StackValue NumberedReference where+ push lua numref = do+ Lua.createtable lua 3 0+ let addValue ((k :: String), v) = Lua.push lua k >> Lua.push lua v >>+ Lua.rawset lua (-3)+ addValue ("numRefId", numRefId numref)+ addValue ("numRefStyle", show (numRefStyle numref))+ addValue ("numRefLabel", numRefLabel numref)+ peek = undefined+ valuetype _ = Lua.TTABLE++-- | Convert Pandoc to custom markup.+writeCustom :: FilePath -> WriterOptions -> Pandoc -> IO String+writeCustom luaFile opts doc@(Pandoc meta _) = do+ luaScript <- C8.unpack `fmap` C8.readFile luaFile+ lua <- Lua.newstate+ Lua.openlibs lua+ Lua.loadstring lua luaScript "custom"+ Lua.call lua 0 0+ -- TODO - call hierarchicalize, so we have that info+ rendered <- docToCustom lua opts doc+ context <- metaToJSON opts+ (fmap toString . blockListToCustom lua)+ (fmap toString . inlineListToCustom lua)+ meta+ Lua.close lua+ let body = toString rendered+ if writerStandalone opts+ then do+ let context' = setField "body" body context+ return $ renderTemplate' (writerTemplate opts) context'+ else return body++docToCustom :: LuaState -> WriterOptions -> Pandoc -> IO ByteString+docToCustom lua opts (Pandoc (Meta metamap) blocks) = do+ body <- blockListToCustom lua blocks+ callfunc lua "Doc" body metamap (writerVariables opts)++-- | Convert Pandoc block element to Custom.+blockToCustom :: LuaState -- ^ Lua state+ -> Block -- ^ Block element+ -> IO ByteString++blockToCustom _ Null = return ""++blockToCustom lua (Plain inlines) = callfunc lua "Plain" inlines++blockToCustom lua (Para [Image _ txt (src,tit)]) =+ callfunc lua "CaptionedImage" src tit txt++blockToCustom lua (Para inlines) = callfunc lua "Para" inlines++blockToCustom lua (RawBlock format str) =+ callfunc lua "RawBlock" format (fromString str)++blockToCustom lua HorizontalRule = callfunc lua "HorizontalRule"++blockToCustom lua (Header level attr inlines) =+ callfunc lua "Header" level inlines (attrToMap attr)++blockToCustom lua (CodeBlock attr str) =+ callfunc lua "CodeBlock" (fromString str) (attrToMap attr)++blockToCustom lua (BlockQuote blocks) = callfunc lua "BlockQuote" blocks++blockToCustom lua (Table capt aligns widths headers rows') =+ callfunc lua "Table" capt (map show aligns) widths headers rows'++blockToCustom lua (BulletList items) = callfunc lua "BulletList" items++blockToCustom lua (OrderedList (num,sty,delim) items) =+ callfunc lua "OrderedList" items num (show sty) (show delim)++blockToCustom lua (DefinitionList items) =+ callfunc lua "DefinitionList" items++blockToCustom lua (Figure figtype attr content pc capt) =+ callfunc lua "Figure" (show figtype) content capt (attrToMap attr) pc++blockToCustom lua (ImageGrid content) =+ callfunc lua "ImageGrid" content++blockToCustom lua (Statement stmattr content) =+ callfunc lua "Statement" content stmattr++blockToCustom lua (Proof capt content) =+ callfunc lua "Proof" capt content++blockToCustom lua (Div attr items) =+ callfunc lua "Div" items (attrToMap attr)++-- | Convert list of Pandoc block elements to Custom.+blockListToCustom :: LuaState -- ^ Options+ -> [Block] -- ^ List of block elements+ -> IO ByteString+blockListToCustom lua xs = do+ blocksep <- callfunc lua "Blocksep"+ bs <- mapM (blockToCustom lua) xs+ return $ mconcat $ intersperse blocksep bs++-- | Convert list of Pandoc inline elements to Custom.+inlineListToCustom :: LuaState -> [Inline] -> IO ByteString+inlineListToCustom lua lst = do+ xs <- mapM (inlineToCustom lua) lst+ return $ C8.concat xs++-- | Convert Pandoc inline element to Custom.+inlineToCustom :: LuaState -> Inline -> IO ByteString++inlineToCustom lua (Str str) = callfunc lua "Str" $ fromString str++inlineToCustom lua Space = callfunc lua "Space"++inlineToCustom lua (Emph lst) = callfunc lua "Emph" lst++inlineToCustom lua (Strong lst) = callfunc lua "Strong" lst++inlineToCustom lua (Strikeout lst) = callfunc lua "Strikeout" lst++inlineToCustom lua (Superscript lst) = callfunc lua "Superscript" lst++inlineToCustom lua (Subscript lst) = callfunc lua "Subscript" lst++inlineToCustom lua (SmallCaps lst) = callfunc lua "SmallCaps" lst++inlineToCustom lua (Quoted SingleQuote lst) = callfunc lua "SingleQuoted" lst++inlineToCustom lua (Quoted DoubleQuote lst) = callfunc lua "DoubleQuoted" lst++inlineToCustom lua (Cite cs lst) = callfunc lua "Cite" lst cs++inlineToCustom lua (Code attr str) =+ callfunc lua "Code" (fromString str) (attrToMap attr)++inlineToCustom lua (Math (DisplayMath ("",[],[])) str) =+ callfunc lua "DisplayMath" (fromString str)++inlineToCustom lua (Math (DisplayMath attr) str) =+ callfunc lua "DisplayMathWithAttr" (fromString str) (attrToMap attr)++inlineToCustom lua (Math InlineMath str) =+ callfunc lua "InlineMath" (fromString str)++inlineToCustom lua (RawInline format str) =+ callfunc lua "RawInline" format (fromString str)++inlineToCustom lua (LineBreak) = callfunc lua "LineBreak"++inlineToCustom lua (Link txt (src,tit)) =+ callfunc lua "Link" txt (fromString src) (fromString tit)++inlineToCustom lua (Image ("",[],[]) alt (src,tit)) =+ callfunc lua "Image" alt (fromString src) (fromString tit)++inlineToCustom lua (Image attr alt (src,tit)) =+ callfunc lua "ImageWithAttr" alt (fromString src) (fromString tit) (attrToMap attr)++inlineToCustom lua (NumRef numref str) =+ callfunc lua "NumRef" (fromString str) numref++inlineToCustom lua (Note contents) = callfunc lua "Note" contents++inlineToCustom lua (Span attr items) =+ callfunc lua "Span" items (attrToMap attr)
@@ -0,0 +1,1025 @@+{-# LANGUAGE ScopedTypeVariables, PatternGuards #-}+{-+Copyright (C) 2012-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.Docx+ Copyright : Copyright (C) 2012-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to docx.+-}+module Text.Pandoc.Writers.Docx ( writeDocx ) where+import Data.List ( intercalate, isPrefixOf, isSuffixOf )+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString.Lazy.Char8 as BL8+import qualified Data.Map as M+import qualified Text.Pandoc.UTF8 as UTF8+import Text.Pandoc.Compat.Monoid ((<>))+import Codec.Archive.Zip+import Data.Time.Clock.POSIX+import Data.Time.Clock+import Data.Time.Format+import System.Environment+import System.Locale+import Text.Pandoc.Definition+import Text.Pandoc.Generic+import Text.Pandoc.ImageSize+import Text.Pandoc.Shared hiding (Element)+import Text.Pandoc.Writers.Shared (fixDisplayMath)+import Text.Pandoc.Options+import Text.Pandoc.Readers.TeXMath+import Text.Pandoc.Highlighting ( highlight )+import Text.Pandoc.Walk+import Text.Highlighting.Kate.Types ()+import Text.XML.Light as XML+import Text.TeXMath+import Control.Monad.State+import Text.Highlighting.Kate+import Data.Unique (hashUnique, newUnique)+import System.Random (randomRIO)+import Text.Printf (printf)+import qualified Control.Exception as E+import Text.Pandoc.MIME (MimeType, getMimeType, getMimeTypeDef,+ extensionFromMimeType)+import Control.Applicative ((<$>), (<|>))+import Data.Maybe (fromMaybe, mapMaybe)++data ListMarker = NoMarker+ | BulletMarker+ | NumberMarker ListNumberStyle ListNumberDelim Int+ deriving (Show, Read, Eq, Ord)++listMarkerToId :: ListMarker -> String+listMarkerToId NoMarker = "990"+listMarkerToId BulletMarker = "991"+listMarkerToId (NumberMarker sty delim n) =+ '9' : '9' : styNum : delimNum : show n+ where styNum = case sty of+ DefaultStyle -> '2'+ Example -> '3'+ Decimal -> '4'+ LowerRoman -> '5'+ UpperRoman -> '6'+ LowerAlpha -> '7'+ UpperAlpha -> '8'+ delimNum = case delim of+ DefaultDelim -> '0'+ Period -> '1'+ OneParen -> '2'+ TwoParens -> '3'++data WriterState = WriterState{+ stTextProperties :: [Element]+ , stParaProperties :: [Element]+ , stFootnotes :: [Element]+ , stSectionIds :: [String]+ , stExternalLinks :: M.Map String String+ , stImages :: M.Map FilePath (String, String, Maybe MimeType, Element, B.ByteString)+ , stListLevel :: Int+ , stListNumId :: Int+ , stLists :: [ListMarker]+ , stInsId :: Int+ , stDelId :: Int+ , stInDel :: Bool+ , stChangesAuthor :: String+ , stChangesDate :: String+ }++defaultWriterState :: WriterState+defaultWriterState = WriterState{+ stTextProperties = []+ , stParaProperties = []+ , stFootnotes = []+ , stSectionIds = []+ , stExternalLinks = M.empty+ , stImages = M.empty+ , stListLevel = -1+ , stListNumId = 1+ , stLists = [NoMarker]+ , stInsId = 1+ , stDelId = 1+ , stInDel = False+ , stChangesAuthor = "unknown"+ , stChangesDate = "1969-12-31T19:00:00Z"+ }++type WS a = StateT WriterState IO a++mknode :: Node t => String -> [(String,String)] -> t -> Element+mknode s attrs =+ add_attrs (map (\(k,v) -> Attr (nodename k) v) attrs) . node (nodename s)++nodename :: String -> QName+nodename s = QName{ qName = name, qURI = Nothing, qPrefix = prefix }+ where (name, prefix) = case break (==':') s of+ (xs,[]) -> (xs, Nothing)+ (ys, _:zs) -> (zs, Just ys)++toLazy :: B.ByteString -> BL.ByteString+toLazy = BL.fromChunks . (:[])++renderXml :: Element -> BL.ByteString+renderXml elt = BL8.pack "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" <>+ UTF8.fromStringLazy (showElement elt)++renumIdMap :: Int -> [Element] -> M.Map String String+renumIdMap _ [] = M.empty+renumIdMap n (e:es)+ | Just oldId <- findAttr (QName "Id" Nothing Nothing) e =+ M.insert oldId ("rId" ++ (show n)) (renumIdMap (n+1) es)+ | otherwise = renumIdMap n es++replaceAttr :: (QName -> Bool) -> String -> [XML.Attr] -> [XML.Attr]+replaceAttr _ _ [] = []+replaceAttr f val (a:as) | f (attrKey a) =+ (XML.Attr (attrKey a) val) : (replaceAttr f val as)+ | otherwise = a : (replaceAttr f val as)++renumId :: (QName -> Bool) -> (M.Map String String) -> Element -> Element+renumId f renumMap e+ | Just oldId <- findAttrBy f e+ , Just newId <- M.lookup oldId renumMap =+ let attrs' = replaceAttr f newId (elAttribs e)+ in+ e { elAttribs = attrs' }+ | otherwise = e++renumIds :: (QName -> Bool) -> (M.Map String String) -> [Element] -> [Element]+renumIds f renumMap = map (renumId f renumMap)++-- | Produce an Docx file from a Pandoc document.+writeDocx :: WriterOptions -- ^ Writer options+ -> Pandoc -- ^ Document to convert+ -> IO BL.ByteString+writeDocx opts doc@(Pandoc meta _) = do+ let datadir = writerUserDataDir opts+ let doc' = walk fixDisplayMath doc+ username <- lookup "USERNAME" <$> getEnvironment+ utctime <- getCurrentTime+ refArchive <- liftM (toArchive . toLazy) $+ case writerReferenceDocx opts of+ Just f -> B.readFile f+ Nothing -> readDataFile datadir "reference.docx"+ distArchive <- liftM (toArchive . toLazy) $ readDataFile Nothing "reference.docx"++ ((contents, footnotes), st) <- runStateT (writeOpenXML opts{writerWrapText = False} doc')+ defaultWriterState{ stChangesAuthor = fromMaybe "unknown" username+ , stChangesDate = formatTime defaultTimeLocale "%FT%XZ" utctime}+ let epochtime = floor $ utcTimeToPOSIXSeconds utctime+ let imgs = M.elems $ stImages st++ -- create entries for images in word/media/...+ let toImageEntry (_,path,_,_,img) = toEntry ("word/" ++ path) epochtime $ toLazy img+ let imageEntries = map toImageEntry imgs+++++ let stdAttributes =+ [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")+ ,("xmlns:m","http://schemas.openxmlformats.org/officeDocument/2006/math")+ ,("xmlns:r","http://schemas.openxmlformats.org/officeDocument/2006/relationships")+ ,("xmlns:o","urn:schemas-microsoft-com:office:office")+ ,("xmlns:v","urn:schemas-microsoft-com:vml")+ ,("xmlns:w10","urn:schemas-microsoft-com:office:word")+ ,("xmlns:a","http://schemas.openxmlformats.org/drawingml/2006/main")+ ,("xmlns:pic","http://schemas.openxmlformats.org/drawingml/2006/picture")+ ,("xmlns:wp","http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing")]+++ parsedRels <- parseXml refArchive distArchive "word/_rels/document.xml.rels"+ let isHeaderNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"+ let isFooterNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer"+ let headers = filterElements isHeaderNode parsedRels+ let footers = filterElements isFooterNode parsedRels++ let extractTarget = findAttr (QName "Target" Nothing Nothing)++ -- we create [Content_Types].xml and word/_rels/document.xml.rels+ -- from scratch rather than reading from reference.docx,+ -- because Word sometimes changes these files when a reference.docx is modified,+ -- e.g. deleting the reference to footnotes.xml or removing default entries+ -- for image content types.++ -- [Content_Types].xml+ let mkOverrideNode (part', contentType') = mknode "Override"+ [("PartName",part'),("ContentType",contentType')] ()+ let mkImageOverride (_, imgpath, mbMimeType, _, _) =+ mkOverrideNode ("/word/" ++ imgpath,+ fromMaybe "application/octet-stream" mbMimeType)+ let mkMediaOverride imgpath =+ mkOverrideNode ('/':imgpath, getMimeTypeDef imgpath)+ let overrides = map mkOverrideNode (+ [("/word/webSettings.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml")+ ,("/word/numbering.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml")+ ,("/word/settings.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml")+ ,("/word/theme/theme1.xml",+ "application/vnd.openxmlformats-officedocument.theme+xml")+ ,("/word/fontTable.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml")+ ,("/docProps/app.xml",+ "application/vnd.openxmlformats-officedocument.extended-properties+xml")+ ,("/docProps/core.xml",+ "application/vnd.openxmlformats-package.core-properties+xml")+ ,("/word/styles.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml")+ ,("/word/document.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")+ ,("/word/footnotes.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml")+ ] +++ map (\x -> (maybe "" ("/word/" ++) $ extractTarget x,+ "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml")) headers +++ map (\x -> (maybe "" ("/word/" ++) $ extractTarget x,+ "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml")) footers) +++ map mkImageOverride imgs +++ map mkMediaOverride [ eRelativePath e | e <- zEntries refArchive+ , "word/media/" `isPrefixOf` eRelativePath e ]++ let defaultnodes = [mknode "Default"+ [("Extension","xml"),("ContentType","application/xml")] (),+ mknode "Default"+ [("Extension","rels"),("ContentType","application/vnd.openxmlformats-package.relationships+xml")] ()]+ let contentTypesDoc = mknode "Types" [("xmlns","http://schemas.openxmlformats.org/package/2006/content-types")] $ defaultnodes ++ overrides+ let contentTypesEntry = toEntry "[Content_Types].xml" epochtime+ $ renderXml contentTypesDoc++ -- word/_rels/document.xml.rels+ let toBaseRel (url', id', target') = mknode "Relationship"+ [("Type",url')+ ,("Id",id')+ ,("Target",target')] ()+ let baserels' = map toBaseRel+ [("http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",+ "rId1",+ "numbering.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",+ "rId2",+ "styles.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",+ "rId3",+ "settings.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings",+ "rId4",+ "webSettings.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",+ "rId5",+ "fontTable.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",+ "rId6",+ "theme/theme1.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",+ "rId7",+ "footnotes.xml")+ ]++ let idMap = renumIdMap (length baserels' + 1) (headers ++ footers)+ let renumHeaders = renumIds (\q -> qName q == "Id") idMap headers+ let renumFooters = renumIds (\q -> qName q == "Id") idMap footers+ let baserels = baserels' ++ renumHeaders ++ renumFooters+ let toImgRel (ident,path,_,_,_) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"),("Id",ident),("Target",path)] ()+ let imgrels = map toImgRel imgs+ let toLinkRel (src,ident) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"),("Id",ident),("Target",src),("TargetMode","External") ] ()+ let linkrels = map toLinkRel $ M.toList $ stExternalLinks st+ let reldoc = mknode "Relationships" [("xmlns","http://schemas.openxmlformats.org/package/2006/relationships")] $ baserels ++ imgrels ++ linkrels+ let relEntry = toEntry "word/_rels/document.xml.rels" epochtime+ $ renderXml reldoc+++ -- adjust contents to add sectPr from reference.docx+ parsedDoc <- parseXml refArchive distArchive "word/document.xml"+ let wname f qn = qPrefix qn == Just "w" && f (qName qn)+ let mbsectpr = filterElementName (wname (=="sectPr")) parsedDoc+ let sectpr = case mbsectpr of+ Just sectpr' -> let cs = renumIds+ (\q -> qName q == "id" && qPrefix q == Just "r")+ idMap+ (elChildren sectpr')+ in+ add_attrs (elAttribs sectpr') $ mknode "w:sectPr" [] cs+ Nothing -> (mknode "w:sectPr" [] ())++++ -- let sectpr = fromMaybe (mknode "w:sectPr" [] ()) mbsectpr'+ let contents' = contents ++ [sectpr]+ let docContents = mknode "w:document" stdAttributes+ $ mknode "w:body" [] contents'++++ -- word/document.xml+ let contentEntry = toEntry "word/document.xml" epochtime+ $ renderXml docContents++ -- footnotes+ let notes = mknode "w:footnotes" stdAttributes footnotes+ let footnotesEntry = toEntry "word/footnotes.xml" epochtime $ renderXml notes++ -- footnote rels+ let footnoteRelEntry = toEntry "word/_rels/footnotes.xml.rels" epochtime+ $ renderXml $ mknode "Relationships" [("xmlns","http://schemas.openxmlformats.org/package/2006/relationships")]+ linkrels++ -- styles+ let newstyles = styleToOpenXml $ writerHighlightStyle opts+ let stylepath = "word/styles.xml"+ styledoc <- parseXml refArchive distArchive stylepath+ let styledoc' = styledoc{ elContent = elContent styledoc +++ [Elem x | x <- newstyles, writerHighlight opts] }+ let styleEntry = toEntry stylepath epochtime $ renderXml styledoc'++ -- construct word/numbering.xml+ let numpath = "word/numbering.xml"+ numbering <- parseXml refArchive distArchive numpath+ newNumElts <- mkNumbering (stLists st)+ let allElts = onlyElems (elContent numbering) ++ newNumElts+ let numEntry = toEntry numpath epochtime $ renderXml numbering{ elContent =+ -- we want all the abstractNums first, then the nums,+ -- otherwise things break:+ [Elem e | e <- allElts+ , qName (elName e) == "abstractNum" ] +++ [Elem e | e <- allElts+ , qName (elName e) == "num" ] }+ let docPropsPath = "docProps/core.xml"+ let docProps = mknode "cp:coreProperties"+ [("xmlns:cp","http://schemas.openxmlformats.org/package/2006/metadata/core-properties")+ ,("xmlns:dc","http://purl.org/dc/elements/1.1/")+ ,("xmlns:dcterms","http://purl.org/dc/terms/")+ ,("xmlns:dcmitype","http://purl.org/dc/dcmitype/")+ ,("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance")]+ $ mknode "dc:title" [] (stringify $ docTitle meta)+ : mknode "dc:creator" [] (intercalate "; " (map stringify $ docAuthors meta))+ : maybe []+ (\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] x+ , mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] x+ ]) (normalizeDate $ stringify $ docDate meta)+ let docPropsEntry = toEntry docPropsPath epochtime $ renderXml docProps++ let relsPath = "_rels/.rels"+ let rels = mknode "Relationships" [("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships")]+ $ map (\attrs -> mknode "Relationship" attrs ())+ [ [("Id","rId1")+ ,("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument")+ ,("Target","word/document.xml")]+ , [("Id","rId4")+ ,("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties")+ ,("Target","docProps/app.xml")]+ , [("Id","rId3")+ ,("Type","http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties")+ ,("Target","docProps/core.xml")]+ ]+ let relsEntry = toEntry relsPath epochtime $ renderXml rels++ let entryFromArchive arch path =+ maybe (fail $ path ++ " corrupt or missing in reference docx")+ return+ (findEntryByPath path arch `mplus` findEntryByPath path distArchive)+ docPropsAppEntry <- entryFromArchive refArchive "docProps/app.xml"+ themeEntry <- entryFromArchive refArchive "word/theme/theme1.xml"+ fontTableEntry <- entryFromArchive refArchive "word/fontTable.xml"+ -- we use dist archive for settings.xml, because Word sometimes+ -- adds references to footnotes or endnotes we don't have...+ settingsEntry <- entryFromArchive distArchive "word/settings.xml"+ webSettingsEntry <- entryFromArchive refArchive "word/webSettings.xml"+ headerFooterEntries <- mapM (entryFromArchive refArchive) $+ mapMaybe (fmap ("word/" ++) . extractTarget)+ (headers ++ footers)+ let miscRelEntries = [ e | e <- zEntries refArchive+ , "word/_rels/" `isPrefixOf` (eRelativePath e)+ , ".xml.rels" `isSuffixOf` (eRelativePath e)+ , eRelativePath e /= "word/_rels/document.xml.rels"+ , eRelativePath e /= "word/_rels/footnotes.xml.rels" ]+ let otherMediaEntries = [ e | e <- zEntries refArchive+ , "word/media/" `isPrefixOf` eRelativePath e ]++ -- Create archive+ let archive = foldr addEntryToArchive emptyArchive $+ contentTypesEntry : relsEntry : contentEntry : relEntry :+ footnoteRelEntry : numEntry : styleEntry : footnotesEntry :+ docPropsEntry : docPropsAppEntry : themeEntry :+ fontTableEntry : settingsEntry : webSettingsEntry :+ imageEntries ++ headerFooterEntries +++ miscRelEntries ++ otherMediaEntries+ return $ fromArchive archive++styleToOpenXml :: Style -> [Element]+styleToOpenXml style = parStyle : map toStyle alltoktypes+ where alltoktypes = enumFromTo KeywordTok NormalTok+ toStyle toktype = mknode "w:style" [("w:type","character"),+ ("w:customStyle","1"),("w:styleId",show toktype)]+ [ mknode "w:name" [("w:val",show toktype)] ()+ , mknode "w:basedOn" [("w:val","VerbatimChar")] ()+ , mknode "w:rPr" [] $+ [ mknode "w:color" [("w:val",tokCol toktype)] ()+ | tokCol toktype /= "auto" ] +++ [ mknode "w:shd" [("w:val","clear"),("w:fill",tokBg toktype)] ()+ | tokBg toktype /= "auto" ] +++ [ mknode "w:b" [] () | tokFeature tokenBold toktype ] +++ [ mknode "w:i" [] () | tokFeature tokenItalic toktype ] +++ [ mknode "w:u" [] () | tokFeature tokenUnderline toktype ]+ ]+ tokStyles = tokenStyles style+ tokFeature f toktype = maybe False f $ lookup toktype tokStyles+ tokCol toktype = maybe "auto" (drop 1 . fromColor)+ $ (tokenColor =<< lookup toktype tokStyles)+ `mplus` defaultColor style+ tokBg toktype = maybe "auto" (drop 1 . fromColor)+ $ (tokenBackground =<< lookup toktype tokStyles)+ `mplus` backgroundColor style+ parStyle = mknode "w:style" [("w:type","paragraph"),+ ("w:customStyle","1"),("w:styleId","SourceCode")]+ [ mknode "w:name" [("w:val","Source Code")] ()+ , mknode "w:basedOn" [("w:val","Normal")] ()+ , mknode "w:link" [("w:val","VerbatimChar")] ()+ , mknode "w:pPr" []+ $ mknode "w:wordWrap" [("w:val","off")] ()+ : ( maybe [] (\col -> [mknode "w:shd" [("w:val","clear"),("w:fill",drop 1 $ fromColor col)] ()])+ $ backgroundColor style )+ ]++-- this is the lowest number used for a list numId+baseListId :: Int+baseListId = 1000++mkNumbering :: [ListMarker] -> IO [Element]+mkNumbering lists = do+ elts <- mapM mkAbstractNum (ordNub lists)+ return $ elts ++ zipWith mkNum lists [baseListId..(baseListId + length lists - 1)]++mkNum :: ListMarker -> Int -> Element+mkNum marker numid =+ mknode "w:num" [("w:numId",show numid)]+ $ mknode "w:abstractNumId" [("w:val",listMarkerToId marker)] ()+ : case marker of+ NoMarker -> []+ BulletMarker -> []+ NumberMarker _ _ start ->+ map (\lvl -> mknode "w:lvlOverride" [("w:ilvl",show (lvl :: Int))]+ $ mknode "w:startOverride" [("w:val",show start)] ()) [0..6]++mkAbstractNum :: ListMarker -> IO Element+mkAbstractNum marker = do+ nsid <- randomRIO (0x10000000 :: Integer, 0xFFFFFFFF :: Integer)+ return $ mknode "w:abstractNum" [("w:abstractNumId",listMarkerToId marker)]+ $ mknode "w:nsid" [("w:val", printf "%8x" nsid)] ()+ : mknode "w:multiLevelType" [("w:val","multilevel")] ()+ : map (mkLvl marker) [0..6]++mkLvl :: ListMarker -> Int -> Element+mkLvl marker lvl =+ mknode "w:lvl" [("w:ilvl",show lvl)] $+ [ mknode "w:start" [("w:val",start)] ()+ | marker /= NoMarker && marker /= BulletMarker ] +++ [ mknode "w:numFmt" [("w:val",fmt)] ()+ , mknode "w:lvlText" [("w:val",lvltxt)] ()+ , mknode "w:lvlJc" [("w:val","left")] ()+ , mknode "w:pPr" []+ [ mknode "w:tabs" []+ $ mknode "w:tab" [("w:val","num"),("w:pos",show $ lvl * step)] ()+ , mknode "w:ind" [("w:left",show $ lvl * step + hang),("w:hanging",show hang)] ()+ ]+ ]+ where (fmt, lvltxt, start) =+ case marker of+ NoMarker -> ("bullet"," ","1")+ BulletMarker -> ("bullet",bulletFor lvl,"1")+ NumberMarker st de n -> (styleFor st lvl+ ,patternFor de ("%" ++ show (lvl + 1))+ ,show n)+ step = 720+ hang = 480+ bulletFor 0 = "\x2022" -- filled circle+ bulletFor 1 = "\x2013" -- en dash+ bulletFor 2 = "\x2022" -- hyphen bullet+ bulletFor 3 = "\x2013"+ bulletFor 4 = "\x2022"+ bulletFor 5 = "\x2013"+ bulletFor _ = "\x2022"+ styleFor UpperAlpha _ = "upperLetter"+ styleFor LowerAlpha _ = "lowerLetter"+ styleFor UpperRoman _ = "upperRoman"+ styleFor LowerRoman _ = "lowerRoman"+ styleFor Decimal _ = "decimal"+ styleFor DefaultStyle 1 = "decimal"+ styleFor DefaultStyle 2 = "lowerLetter"+ styleFor DefaultStyle 3 = "lowerRoman"+ styleFor DefaultStyle 4 = "decimal"+ styleFor DefaultStyle 5 = "lowerLetter"+ styleFor DefaultStyle 6 = "lowerRoman"+ styleFor _ _ = "decimal"+ patternFor OneParen s = s ++ ")"+ patternFor TwoParens s = "(" ++ s ++ ")"+ patternFor _ s = s ++ "."++getNumId :: WS Int+getNumId = (((baseListId - 1) +) . length) `fmap` gets stLists++-- | Convert Pandoc document to two lists of+-- OpenXML elements (the main document and footnotes).+writeOpenXML :: WriterOptions -> Pandoc -> WS ([Element], [Element])+writeOpenXML opts (Pandoc meta blocks) = do+ let tit = docTitle meta ++ case lookupMeta "subtitle" meta of+ Just (MetaBlocks [Plain xs]) -> LineBreak : xs+ _ -> []+ let auths = docAuthors meta+ let dat = docDate meta+ let abstract' = case lookupMeta "abstract" meta of+ Just (MetaBlocks bs) -> bs+ Just (MetaInlines ils) -> [Plain ils]+ _ -> []+ let subtitle' = case lookupMeta "subtitle" meta of+ Just (MetaBlocks [Plain xs]) -> xs+ Just (MetaBlocks [Para xs]) -> xs+ Just (MetaInlines xs) -> xs+ _ -> []+ title <- withParaProp (pStyle "Title") $ blocksToOpenXML opts [Para tit | not (null tit)]+ subtitle <- withParaProp (pStyle "Subtitle") $ blocksToOpenXML opts [Para subtitle' | not (null subtitle')]+ authors <- withParaProp (pStyle "Author") $ blocksToOpenXML opts $+ map Para auths+ date <- withParaProp (pStyle "Date") $ blocksToOpenXML opts [Para dat | not (null dat)]+ abstract <- if null abstract'+ then return []+ else withParaProp (pStyle "Abstract") $ blocksToOpenXML opts abstract'+ let convertSpace (Str x : Space : Str y : xs) = Str (x ++ " " ++ y) : xs+ convertSpace (Str x : Str y : xs) = Str (x ++ y) : xs+ convertSpace xs = xs+ let blocks' = bottomUp convertSpace blocks+ doc' <- blocksToOpenXML opts blocks'+ notes' <- reverse `fmap` gets stFootnotes+ let meta' = title ++ subtitle ++ authors ++ date ++ abstract+ return (meta' ++ doc', notes')++-- | Convert a list of Pandoc blocks to OpenXML.+blocksToOpenXML :: WriterOptions -> [Block] -> WS [Element]+blocksToOpenXML opts bls = concat `fmap` mapM (blockToOpenXML opts) bls++pStyle :: String -> Element+pStyle sty = mknode "w:pStyle" [("w:val",sty)] ()++rStyle :: String -> Element+rStyle sty = mknode "w:rStyle" [("w:val",sty)] ()++getUniqueId :: MonadIO m => m String+-- the + 20 is to ensure that there are no clashes with the rIds+-- already in word/document.xml.rel+getUniqueId = liftIO $ (show . (+ 20) . hashUnique) `fmap` newUnique++-- | Convert a Pandoc block element to OpenXML.+blockToOpenXML :: WriterOptions -> Block -> WS [Element]+blockToOpenXML _ Null = return []+blockToOpenXML opts (Div (_,["references"],_) bs) = do+ let (hs, bs') = span isHeaderBlock bs+ header <- blocksToOpenXML opts hs+ -- We put the Bibliography style on paragraphs after the header+ rest <- withParaProp (pStyle "Bibliography") $ blocksToOpenXML opts bs'+ return (header ++ rest)+blockToOpenXML opts (Div _ bs) = blocksToOpenXML opts bs+blockToOpenXML opts (Header lev (ident,_,_) lst) = do+ paraProps <- withParaProp (pStyle $ "Heading" ++ show lev) $+ getParaProps False+ contents <- inlinesToOpenXML opts lst+ usedIdents <- gets stSectionIds+ let bookmarkName = if null ident+ then uniqueIdent lst usedIdents+ else ident+ modify $ \s -> s{ stSectionIds = bookmarkName : stSectionIds s }+ id' <- getUniqueId+ let bookmarkStart = mknode "w:bookmarkStart" [("w:id", id')+ ,("w:name",bookmarkName)] ()+ let bookmarkEnd = mknode "w:bookmarkEnd" [("w:id", id')] ()+ return [mknode "w:p" [] (paraProps ++ [bookmarkStart, bookmarkEnd] ++ contents)]+blockToOpenXML opts (Plain lst) = withParaProp (pStyle "Compact")+ $ blockToOpenXML opts (Para lst)+-- title beginning with fig: indicates that the image is a figure+blockToOpenXML opts (Para [Image attr alt (src,'f':'i':'g':':':tit)]) = do+ paraProps <- getParaProps False+ contents <- inlinesToOpenXML opts [Image attr alt (src,tit)]+ captionNode <- withParaProp (pStyle "ImageCaption")+ $ blockToOpenXML opts (Para alt)+ return $ mknode "w:p" [] (paraProps ++ contents) : captionNode+-- fixDisplayMath sometimes produces a Para [] as artifact+blockToOpenXML _ (Para []) = return []+blockToOpenXML opts (Para lst) = do+ paraProps <- getParaProps $ case lst of+ [Math (DisplayMath _) _] -> True+ _ -> False+ contents <- inlinesToOpenXML opts lst+ return [mknode "w:p" [] (paraProps ++ contents)]+blockToOpenXML _ (RawBlock format str)+ | format == Format "openxml" = return [ x | Elem x <- parseXML str ]+ | otherwise = return []+blockToOpenXML opts (BlockQuote blocks) =+ withParaProp (pStyle "BlockQuote") $ blocksToOpenXML opts blocks+blockToOpenXML opts (CodeBlock attrs str) =+ withParaProp (pStyle "SourceCode") $ blockToOpenXML opts $ Para [Code attrs str]+blockToOpenXML _ HorizontalRule = return [+ mknode "w:p" [] $ mknode "w:r" [] $ mknode "w:pict" []+ $ mknode "v:rect" [("style","width:0;height:1.5pt"),+ ("o:hralign","center"),+ ("o:hrstd","t"),("o:hr","t")] () ]+blockToOpenXML opts (Table caption aligns widths headers rows) = do+ let captionStr = stringify caption+ caption' <- if null caption+ then return []+ else withParaProp (pStyle "TableCaption")+ $ blockToOpenXML opts (Para caption)+ let alignmentFor al = mknode "w:jc" [("w:val",alignmentToString al)] ()+ let cellToOpenXML (al, cell) = withParaProp (alignmentFor al)+ $ blocksToOpenXML opts cell+ headers' <- mapM cellToOpenXML $ zip aligns headers+ rows' <- mapM (mapM cellToOpenXML . zip aligns) rows+ let borderProps = mknode "w:tcPr" []+ [ mknode "w:tcBorders" []+ $ mknode "w:bottom" [("w:val","single")] ()+ , mknode "w:vAlign" [("w:val","bottom")] () ]+ let emptyCell = [mknode "w:p" [] [mknode "w:pPr" []+ [mknode "w:pStyle" [("w:val","Compact")] ()]]]+ let mkcell border contents = mknode "w:tc" []+ $ [ borderProps | border ] +++ if null contents+ then emptyCell+ else contents+ let mkrow border cells = mknode "w:tr" [] $ map (mkcell border) cells+ let textwidth = 7920 -- 5.5 in in twips, 1/20 pt+ let fullrow = 5000 -- 100% specified in pct+ let rowwidth = fullrow * sum widths+ let mkgridcol w = mknode "w:gridCol"+ [("w:w", show (floor (textwidth * w) :: Integer))] ()+ return $+ mknode "w:tbl" []+ ( mknode "w:tblPr" []+ ( mknode "w:tblStyle" [("w:val","TableNormal")] () :+ mknode "w:tblW" [("w:type", "pct"), ("w:w", show rowwidth)] () :+ [ mknode "w:tblCaption" [("w:val", captionStr)] ()+ | not (null caption) ] )+ : mknode "w:tblGrid" []+ (if all (==0) widths+ then []+ else map mkgridcol widths)+ : [ mkrow True headers' | not (all null headers) ] +++ map (mkrow False) rows'+ ) : caption'+blockToOpenXML opts (BulletList lst) = do+ let marker = BulletMarker+ addList marker+ numid <- getNumId+ asList $ concat `fmap` mapM (listItemToOpenXML opts numid) lst+blockToOpenXML opts (OrderedList (start, numstyle, numdelim) lst) = do+ let marker = NumberMarker numstyle numdelim start+ addList marker+ numid <- getNumId+ asList $ concat `fmap` mapM (listItemToOpenXML opts numid) lst+blockToOpenXML opts (DefinitionList items) =+ concat `fmap` mapM (definitionListItemToOpenXML opts) items+-- These elements await implementation+blockToOpenXML _opts (Figure _ _ _ _ _) = return []+blockToOpenXML _opts (ImageGrid _) = return []+blockToOpenXML _opts (Statement _ _ ) = return []+blockToOpenXML _opts (Proof _ _ ) = return []++definitionListItemToOpenXML :: WriterOptions -> ([Inline],[[Block]]) -> WS [Element]+definitionListItemToOpenXML opts (term,defs) = do+ term' <- withParaProp (pStyle "DefinitionTerm")+ $ blockToOpenXML opts (Para term)+ defs' <- withParaProp (pStyle "Definition")+ $ concat `fmap` mapM (blocksToOpenXML opts) defs+ return $ term' ++ defs'++addList :: ListMarker -> WS ()+addList marker = do+ lists <- gets stLists+ modify $ \st -> st{ stLists = lists ++ [marker] }++listItemToOpenXML :: WriterOptions -> Int -> [Block] -> WS [Element]+listItemToOpenXML _ _ [] = return []+listItemToOpenXML opts numid (first:rest) = do+ first' <- withNumId numid $ blockToOpenXML opts first+ -- baseListId is the code for no list marker:+ rest' <- withNumId baseListId $ blocksToOpenXML opts rest+ return $ first' ++ rest'++alignmentToString :: Alignment -> [Char]+alignmentToString alignment = case alignment of+ AlignLeft -> "left"+ AlignRight -> "right"+ AlignCenter -> "center"+ AlignDefault -> "left"++-- | Convert a list of inline elements to OpenXML.+inlinesToOpenXML :: WriterOptions -> [Inline] -> WS [Element]+inlinesToOpenXML opts lst = concat `fmap` mapM (inlineToOpenXML opts) lst++withNumId :: Int -> WS a -> WS a+withNumId numid p = do+ origNumId <- gets stListNumId+ modify $ \st -> st{ stListNumId = numid }+ result <- p+ modify $ \st -> st{ stListNumId = origNumId }+ return result++asList :: WS a -> WS a+asList p = do+ origListLevel <- gets stListLevel+ modify $ \st -> st{ stListLevel = stListLevel st + 1 }+ result <- p+ modify $ \st -> st{ stListLevel = origListLevel }+ return result++getTextProps :: WS [Element]+getTextProps = do+ props <- gets stTextProperties+ return $ if null props+ then []+ else [mknode "w:rPr" [] props]++pushTextProp :: Element -> WS ()+pushTextProp d = modify $ \s -> s{ stTextProperties = d : stTextProperties s }++popTextProp :: WS ()+popTextProp = modify $ \s -> s{ stTextProperties = drop 1 $ stTextProperties s }++withTextProp :: Element -> WS a -> WS a+withTextProp d p = do+ pushTextProp d+ res <- p+ popTextProp+ return res++getParaProps :: Bool -> WS [Element]+getParaProps displayMathPara = do+ props <- gets stParaProperties+ listLevel <- gets stListLevel+ numid <- gets stListNumId+ let listPr = if listLevel >= 0 && not displayMathPara+ then [ mknode "w:numPr" []+ [ mknode "w:numId" [("w:val",show numid)] ()+ , mknode "w:ilvl" [("w:val",show listLevel)] () ]+ ]+ else []+ return $ case props ++ listPr of+ [] -> []+ ps -> [mknode "w:pPr" [] ps]++pushParaProp :: Element -> WS ()+pushParaProp d = modify $ \s -> s{ stParaProperties = d : stParaProperties s }++popParaProp :: WS ()+popParaProp = modify $ \s -> s{ stParaProperties = drop 1 $ stParaProperties s }++withParaProp :: Element -> WS a -> WS a+withParaProp d p = do+ pushParaProp d+ res <- p+ popParaProp+ return res++formattedString :: String -> WS [Element]+formattedString str = do+ props <- getTextProps+ inDel <- gets stInDel+ return [ mknode "w:r" [] $+ props +++ [ mknode (if inDel then "w:delText" else "w:t")+ [("xml:space","preserve")] str ] ]++-- | Convert an inline element to OpenXML.+inlineToOpenXML :: WriterOptions -> Inline -> WS [Element]+inlineToOpenXML _ (Str str) = formattedString str+inlineToOpenXML opts Space = inlineToOpenXML opts (Str " ")+inlineToOpenXML opts (Span (_,classes,kvs) ils)+ | "insertion" `elem` classes = do+ defaultAuthor <- gets stChangesAuthor+ defaultDate <- gets stChangesDate+ let author = fromMaybe defaultAuthor (lookup "author" kvs)+ date = fromMaybe defaultDate (lookup "date" kvs)+ insId <- gets stInsId+ modify $ \s -> s{stInsId = (insId + 1)}+ x <- inlinesToOpenXML opts ils+ return [ mknode "w:ins" [("w:id", (show insId)),+ ("w:author", author),+ ("w:date", date)]+ x ]+ | "deletion" `elem` classes = do+ defaultAuthor <- gets stChangesAuthor+ defaultDate <- gets stChangesDate+ let author = fromMaybe defaultAuthor (lookup "author" kvs)+ date = fromMaybe defaultDate (lookup "date" kvs)+ delId <- gets stDelId+ modify $ \s -> s{stDelId = (delId + 1)}+ modify $ \s -> s{stInDel = True}+ x <- inlinesToOpenXML opts ils+ modify $ \s -> s{stInDel = False}+ return [ mknode "w:del" [("w:id", (show delId)),+ ("w:author", author),+ ("w:date", date)]+ x ]+ | otherwise = do+ let off x = withTextProp (mknode x [("w:val","0")] ())+ ((if "csl-no-emph" `elem` classes then off "w:i" else id) .+ (if "csl-no-strong" `elem` classes then off "w:b" else id) .+ (if "csl-no-smallcaps" `elem` classes then off "w:smallCaps" else id))+ $ inlinesToOpenXML opts ils+inlineToOpenXML opts (Strong lst) =+ withTextProp (mknode "w:b" [] ()) $ inlinesToOpenXML opts lst+inlineToOpenXML opts (Emph lst) =+ withTextProp (mknode "w:i" [] ()) $ inlinesToOpenXML opts lst+inlineToOpenXML opts (Subscript lst) =+ withTextProp (mknode "w:vertAlign" [("w:val","subscript")] ())+ $ inlinesToOpenXML opts lst+inlineToOpenXML opts (Superscript lst) =+ withTextProp (mknode "w:vertAlign" [("w:val","superscript")] ())+ $ inlinesToOpenXML opts lst+inlineToOpenXML opts (SmallCaps lst) =+ withTextProp (mknode "w:smallCaps" [] ())+ $ inlinesToOpenXML opts lst+inlineToOpenXML opts (Strikeout lst) =+ withTextProp (mknode "w:strike" [] ())+ $ inlinesToOpenXML opts lst+inlineToOpenXML _ LineBreak = return [br]+inlineToOpenXML _ (RawInline f str)+ | f == Format "openxml" = return [ x | Elem x <- parseXML str ]+ | otherwise = return []+inlineToOpenXML opts (Quoted quoteType lst) =+ inlinesToOpenXML opts $ [Str open] ++ lst ++ [Str close]+ where (open, close) = case quoteType of+ SingleQuote -> ("\x2018", "\x2019")+ DoubleQuote -> ("\x201C", "\x201D")+inlineToOpenXML opts (Math mathType str) = do+ let displayType = case mathType of+ DisplayMath _ -> DisplayBlock+ InlineMath -> DisplayInline+ case writeOMML displayType <$> readTeX str of+ Right r -> return [r]+ Left _ -> inlinesToOpenXML opts (texMathToInlines mathType str)+inlineToOpenXML opts (Cite _ lst) = inlinesToOpenXML opts lst+inlineToOpenXML opts (Code attrs str) =+ withTextProp (rStyle "VerbatimChar")+ $ if writerHighlight opts+ then case highlight formatOpenXML attrs str of+ Nothing -> unhighlighted+ Just h -> return h+ else unhighlighted+ where unhighlighted = intercalate [br] `fmap`+ (mapM formattedString $ lines str)+ formatOpenXML _fmtOpts = intercalate [br] . map (map toHlTok)+ toHlTok (toktype,tok) = mknode "w:r" []+ [ mknode "w:rPr" []+ [ rStyle $ show toktype ]+ , mknode "w:t" [("xml:space","preserve")] tok ]+inlineToOpenXML opts (Note bs) = do+ notes <- gets stFootnotes+ notenum <- getUniqueId+ let notemarker = mknode "w:r" []+ [ mknode "w:rPr" [] (rStyle "FootnoteRef")+ , mknode "w:footnoteRef" [] () ]+ let notemarkerXml = RawInline (Format "openxml") $ ppElement notemarker+ let insertNoteRef (Plain ils : xs) = Plain (notemarkerXml : ils) : xs+ insertNoteRef (Para ils : xs) = Para (notemarkerXml : ils) : xs+ insertNoteRef xs = Para [notemarkerXml] : xs+ oldListLevel <- gets stListLevel+ oldParaProperties <- gets stParaProperties+ oldTextProperties <- gets stTextProperties+ modify $ \st -> st{ stListLevel = -1, stParaProperties = [], stTextProperties = [] }+ contents <- withParaProp (pStyle "FootnoteText") $ blocksToOpenXML opts+ $ insertNoteRef bs+ modify $ \st -> st{ stListLevel = oldListLevel, stParaProperties = oldParaProperties,+ stTextProperties = oldTextProperties }+ let newnote = mknode "w:footnote" [("w:id", notenum)] $ contents+ modify $ \s -> s{ stFootnotes = newnote : notes }+ return [ mknode "w:r" []+ [ mknode "w:rPr" [] (rStyle "FootnoteRef")+ , mknode "w:footnoteReference" [("w:id", notenum)] () ] ]+-- internal link:+inlineToOpenXML opts (Link txt ('#':xs,_)) = do+ contents <- withTextProp (rStyle "Link") $ inlinesToOpenXML opts txt+ return [ mknode "w:hyperlink" [("w:anchor",xs)] contents ]+-- external link:+inlineToOpenXML opts (Link txt (src,_)) = do+ contents <- withTextProp (rStyle "Link") $ inlinesToOpenXML opts txt+ extlinks <- gets stExternalLinks+ id' <- case M.lookup src extlinks of+ Just i -> return i+ Nothing -> do+ i <- ("rId"++) `fmap` getUniqueId+ modify $ \st -> st{ stExternalLinks =+ M.insert src i extlinks }+ return i+ return [ mknode "w:hyperlink" [("r:id",id')] contents ]+inlineToOpenXML opts (Image _ alt (src, tit)) = do+ -- first, check to see if we've already done this image+ imgs <- gets stImages+ case M.lookup src imgs of+ Just (_,_,_,elt,_) -> return [elt]+ Nothing -> do+ res <- liftIO $+ fetchItem' (writerMediaBag opts) (writerSourceURL opts) src+ case res of+ Left (_ :: E.SomeException) -> do+ liftIO $ warn $ "Could not find image `" ++ src ++ "', skipping..."+ -- emit alt text+ inlinesToOpenXML opts alt+ Right (img, mt) -> do+ ident <- ("rId"++) `fmap` getUniqueId+ let size = imageSize img+ let (xpt,ypt) = maybe (120,120) sizeInPoints size+ -- 12700 emu = 1 pt+ let (xemu,yemu) = fitToPage (xpt * 12700, ypt * 12700)+ let cNvPicPr = mknode "pic:cNvPicPr" [] $+ mknode "a:picLocks" [("noChangeArrowheads","1"),("noChangeAspect","1")] ()+ let nvPicPr = mknode "pic:nvPicPr" []+ [ mknode "pic:cNvPr"+ [("descr",src),("id","0"),("name","Picture")] ()+ , cNvPicPr ]+ let blipFill = mknode "pic:blipFill" []+ [ mknode "a:blip" [("r:embed",ident)] ()+ , mknode "a:stretch" [] $ mknode "a:fillRect" [] () ]+ let xfrm = mknode "a:xfrm" []+ [ mknode "a:off" [("x","0"),("y","0")] ()+ , mknode "a:ext" [("cx",show xemu),("cy",show yemu)] () ]+ let prstGeom = mknode "a:prstGeom" [("prst","rect")] $+ mknode "a:avLst" [] ()+ let ln = mknode "a:ln" [("w","9525")]+ [ mknode "a:noFill" [] ()+ , mknode "a:headEnd" [] ()+ , mknode "a:tailEnd" [] () ]+ let spPr = mknode "pic:spPr" [("bwMode","auto")]+ [xfrm, prstGeom, mknode "a:noFill" [] (), ln]+ let graphic = mknode "a:graphic" [] $+ mknode "a:graphicData" [("uri","http://schemas.openxmlformats.org/drawingml/2006/picture")]+ [ mknode "pic:pic" []+ [ nvPicPr+ , blipFill+ , spPr ] ]+ let imgElt = mknode "w:r" [] $+ mknode "w:drawing" [] $+ mknode "wp:inline" []+ [ mknode "wp:extent" [("cx",show xemu),("cy",show yemu)] ()+ , mknode "wp:effectExtent" [("b","0"),("l","0"),("r","0"),("t","0")] ()+ , mknode "wp:docPr" [("descr",tit),("id","1"),("name","Picture")] ()+ , graphic ]+ let imgext = case mt >>= extensionFromMimeType of+ Just x -> '.':x+ Nothing -> case imageType img of+ Just Png -> ".png"+ Just Jpeg -> ".jpeg"+ Just Gif -> ".gif"+ Just Pdf -> ".pdf"+ Just Eps -> ".eps"+ Nothing -> ""+ if null imgext+ then -- without an extension there is no rule for content type+ inlinesToOpenXML opts alt -- return alt to avoid corrupted docx+ else do+ let imgpath = "media/" ++ ident ++ imgext+ let mbMimeType = mt <|> getMimeType imgpath+ -- insert mime type to use in constructing [Content_Types].xml+ modify $ \st -> st{ stImages =+ M.insert src (ident, imgpath, mbMimeType, imgElt, img)+ $ stImages st }+ return [imgElt]+-- These elements await implementation+inlineToOpenXML _opts (NumRef _ _) = return []++br :: Element+br = mknode "w:r" [] [mknode "w:br" [("w:type","textWrapping")] () ]++parseXml :: Archive -> Archive -> String -> IO Element+parseXml refArchive distArchive relpath =+ case ((findEntryByPath relpath refArchive `mplus`+ findEntryByPath relpath distArchive)+ >>= parseXMLDoc . UTF8.toStringLazy . fromEntry) of+ Just d -> return d+ Nothing -> fail $ relpath ++ " corrupt or missing in reference docx"++-- | Scales the image to fit the page+fitToPage :: (Integer, Integer) -> (Integer, Integer)+fitToPage (x, y)+ --5440680 is the emu width size of a letter page in portrait, minus the margins+ | x > 5440680 =+ (5440680, round $ (5440680 / ((fromIntegral :: Integer -> Double) x)) * (fromIntegral y))+ | otherwise = (x, y)
@@ -0,0 +1,1053 @@+{-# LANGUAGE OverloadedStrings, CPP, ViewPatterns #-}+{-# OPTIONS_GHC -fno-warn-deprecations #-}+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>+Copyright (C) 2014 Tim T.Y. Lin <timtylin@gmail.com>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.HTML+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to HTML.+-}+module Text.Pandoc.Writers.HTML ( writeHtml , writeHtmlString ) where+import Text.Pandoc.Definition+import Text.Pandoc.Shared+import Text.Pandoc.Writers.Shared+import Text.Pandoc.Options+import Text.Pandoc.Templates+import Text.Pandoc.Readers.TeXMath+import Text.Pandoc.Slides+import Text.Pandoc.Highlighting ( highlight, styleToCss,+ formatHtmlInline, formatHtmlBlock )+import Text.Pandoc.XML (fromEntities, escapeStringForXML)+import Text.Pandoc.Scholarly+import Network.URI ( parseURIReference, URI(..), unEscapeString )+import Network.HTTP ( urlEncode )+import Numeric ( showHex )+import Data.Char ( ord, toLower )+import Data.List ( isPrefixOf, intersperse, intercalate )+import Data.String ( fromString )+import Data.Maybe ( catMaybes, fromMaybe, fromJust, isJust, isNothing )+import Control.Monad.State+import Text.Blaze.Html hiding(contents)+import Text.Blaze.Internal(preEscapedString)+#if MIN_VERSION_blaze_html(0,5,1)+import qualified Text.Blaze.XHtml5 as H5+#else+import qualified Text.Blaze.Html5 as H5+#endif+import qualified Text.Blaze.XHtml1.Transitional as H+import qualified Text.Blaze.XHtml1.Transitional.Attributes as A+import Text.Blaze.Renderer.String (renderHtml)+import Text.TeXMath+import Text.XML.Light.Output+import Text.XML.Light (unode, elChildren, add_attr, unqual)+import qualified Text.XML.Light as XML+import System.FilePath (takeExtension)+import Data.Monoid+import Data.Aeson (Value)+import Control.Applicative ((<$>))++data WriterState = WriterState+ { stNotes :: [Html] -- ^ List of notes+ , stMath :: Bool -- ^ Math is used in document+ , stQuotes :: Bool -- ^ <q> tag is used+ , stHighlighting :: Bool -- ^ Syntax highlighting is used+ , stSecNum :: [Int] -- ^ Number of current section+ , stMathIds :: [String]+ , stLastHeight :: Maybe String -- last img height value+ , stLastWidth :: Maybe String -- last img width value+ }++defaultWriterState :: WriterState+defaultWriterState = WriterState {stNotes= [], stMath = False, stQuotes = False,+ stHighlighting = False, stSecNum = [],+ stMathIds = [], stLastHeight = Nothing,+ stLastWidth = Nothing }++-- Helpers to render HTML with the appropriate function.++strToHtml :: String -> Html+strToHtml ('\'':xs) = preEscapedString "\'" `mappend` strToHtml xs+strToHtml xs@(_:_) = case break (=='\'') xs of+ (_ ,[]) -> toHtml xs+ (ys,zs) -> toHtml ys `mappend` strToHtml zs+strToHtml [] = ""++-- | Hard linebreak.+nl :: WriterOptions -> Html+nl opts = if writerWrapText opts+ then preEscapedString "\n"+ else mempty++-- | Convert Pandoc document to Html string.+writeHtmlString :: WriterOptions -> Pandoc -> String+writeHtmlString opts d =+ let (body, context) = evalState (pandocToHtml opts d) defaultWriterState+ in if writerStandalone opts+ then inTemplate opts context body+ else renderHtml body++-- | Convert Pandoc document to Html structure.+writeHtml :: WriterOptions -> Pandoc -> Html+writeHtml opts d =+ let (body, context) = evalState (pandocToHtml opts d) defaultWriterState+ in if writerStandalone opts+ then inTemplate opts context body+ else body++-- result is (title, authors, date, toc, body, new variables)+pandocToHtml :: WriterOptions+ -> Pandoc+ -> State WriterState (Html, Value)+pandocToHtml opts (Pandoc meta blocks) = do+ -- make sure title is set for abstract section+ metadata <- metaToJSON opts+ (fmap renderHtml . blockListToHtml opts)+ (fmap renderHtml . inlineListToHtml opts)+ meta+ initSt <- get+ -- these ids will be handled by MathJax if in Scholarly Markdown+ let mathIds = extractMetaStringList $ lookupMeta "identifiersForMath" meta+ put initSt{ stMathIds = mathIds }+ let stringifyHTML = escapeStringForXML . stringify+ let authsMeta = map stringifyHTML $ docAuthors meta+ let dateMeta = stringifyHTML $ docDate meta+ let slideLevel = fromMaybe (getSlideLevel blocks) $ writerSlideLevel opts+ let sects = hierarchicalize $+ if writerSlideVariant opts == NoSlides+ then blocks+ else prepSlides slideLevel blocks+ toc <- if writerTableOfContents opts+ then tableOfContents opts sects+ else return Nothing+ blocks' <- liftM (mconcat . intersperse (nl opts)) $+ mapM (elementToHtml slideLevel opts) sects+ st <- get+ let notes = reverse (stNotes st)+ let thebody = blocks' >> footnoteSection opts notes+ let mathDefs = lookupMeta "latexMacrosForMath" meta+ let math = if stMath st+ then case writerHTMLMathMethod opts of+ LaTeXMathML (Just url) ->+ H.script ! A.src (toValue url)+ ! A.type_ "text/javascript"+ $ mempty+ MathML (Just url) ->+ H.script ! A.src (toValue url)+ ! A.type_ "text/javascript"+ $ mempty+ MathJax url ->+ if url == "" then mempty+ else H.script ! A.src (toValue url)+ ! A.type_ "text/javascript"+ $ case writerSlideVariant opts of+ SlideousSlides ->+ preEscapedString+ "MathJax.Hub.Queue([\"Typeset\",MathJax.Hub]);"+ _ -> mempty+ JsMath (Just url) ->+ H.script ! A.src (toValue url)+ ! A.type_ "text/javascript"+ $ mempty+ KaTeX js css ->+ (H.script ! A.src (toValue js) $ mempty) <>+ (H.link ! A.rel "stylesheet" ! A.href (toValue css)) <>+ (H.script ! A.type_ "text/javascript" $ toHtml renderKaTeX)+ _ -> case lookup "mathml-script" (writerVariables opts) of+ Just s | not (writerHtml5 opts) ->+ H.script ! A.type_ "text/javascript"+ $ preEscapedString+ ("/*<![CDATA[*/\n" ++ s ++ "/*]]>*/\n")+ | otherwise -> mempty+ Nothing -> mempty+ else mempty+ let context = (if stHighlighting st+ then defField "highlighting-css"+ (styleToCss $ writerHighlightStyle opts)+ else id) $+ (if stMath st+ then defField "math" (renderHtml math)+ else id) $+ (if isJust mathDefs+ then defField "math-macros"+ (extractMetaString $ fromJust mathDefs)+ else id) $+ defField "quotes" (stQuotes st) $+ maybe id (defField "toc" . renderHtml) toc $+ defField "author-meta" authsMeta $+ maybe id (defField "date-meta") (normalizeDate dateMeta) $+ (if (isJust $ lookupMeta "abstract" meta)+ && (isNothing $ lookupMeta "abstract-title" meta)+ then defField "abstract-title" ("Abstract" :: String)+ else id) $+ defField "pagetitle" (stringifyHTML $ docTitle meta) $+ defField "idprefix" (writerIdentifierPrefix opts) $+ -- these should maybe be set in pandoc.hs+ defField "slidy-url"+ ("http://www.w3.org/Talks/Tools/Slidy2" :: String) $+ defField "slideous-url" ("slideous" :: String) $+ defField "revealjs-url" ("reveal.js" :: String) $+ defField "s5-url" ("s5/default" :: String) $+ defField "html5" (writerHtml5 opts) $+ metadata+ return (thebody, context)++inTemplate :: TemplateTarget a+ => WriterOptions+ -> Value+ -> Html+ -> a+inTemplate opts context body = renderTemplate' (writerTemplate opts)+ $ defField "body" (renderHtml body) context++-- | Like Text.XHtml's identifier, but adds the writerIdentifierPrefix+prefixedId :: WriterOptions -> String -> Attribute+prefixedId opts s =+ case s of+ "" -> mempty+ _ -> A.id $ toValue $ writerIdentifierPrefix opts ++ s++toList :: (Html -> Html) -> WriterOptions -> ([Html] -> Html)+toList listop opts items = do+ if (writerIncremental opts)+ then if (writerSlideVariant opts /= RevealJsSlides)+ then (listop $ mconcat items) ! A.class_ "incremental"+ else listop $ mconcat $ map (! A.class_ "fragment") items+ else listop $ mconcat items++unordList :: WriterOptions -> [Html] -> Html+unordList opts = toList H.ul opts . toListItems opts++ordList :: WriterOptions -> [Html] -> Html+ordList opts = toList H.ol opts . toListItems opts++defList :: WriterOptions -> [Html] -> Html+defList opts items = toList H.dl opts (items ++ [nl opts])++-- | Construct table of contents from list of elements.+tableOfContents :: WriterOptions -> [Element] -> State WriterState (Maybe Html)+tableOfContents _ [] = return Nothing+tableOfContents opts sects = do+ let opts' = opts { writerIgnoreNotes = True }+ contents <- mapM (elementToListItem opts') sects+ let tocList = catMaybes contents+ return $ if null tocList+ then Nothing+ else Just $ unordList opts tocList++-- | Convert section number to string+showSecNum :: [Int] -> String+showSecNum = concat . intersperse "." . map show++-- | Converts an Element to a list item for a table of contents,+-- retrieving the appropriate identifier from state.+elementToListItem :: WriterOptions -> Element -> State WriterState (Maybe Html)+-- Don't include the empty headers created in slide shows+-- shows when an hrule is used to separate slides without a new title:+elementToListItem _ (Sec _ _ _ [Str "\0"] _) = return Nothing+elementToListItem opts (Sec lev num (id',classes,_) headerText subsecs)+ | lev <= writerTOCDepth opts = do+ let num' = zipWith (+) num (writerNumberOffset opts ++ repeat 0)+ let sectnum = if writerNumberSections opts && not (null num) &&+ "unnumbered" `notElem` classes+ then (H.span ! A.class_ "toc-section-number"+ $ toHtml $ showSecNum num') >> preEscapedString " "+ else mempty+ txt <- liftM (sectnum >>) $ inlineListToHtml opts headerText+ subHeads <- mapM (elementToListItem opts) subsecs >>= return . catMaybes+ let subList = if null subHeads+ then mempty+ else unordList opts subHeads+ -- in reveal.js, we need #/apples, not #apples:+ let revealSlash = ['/' | writerSlideVariant opts == RevealJsSlides]+ return $ Just+ $ if null id'+ then (H.a $ toHtml txt) >> subList+ else (H.a ! A.href (toValue $ "#" ++ revealSlash +++ writerIdentifierPrefix opts ++ id')+ $ toHtml txt) >> subList+elementToListItem _ _ = return Nothing++-- | Convert an Element to Html.+elementToHtml :: Int -> WriterOptions -> Element -> State WriterState Html+elementToHtml _slideLevel opts (Blk block) = blockToHtml opts block+elementToHtml slideLevel opts (Sec level num (id',classes,keyvals) title' elements) = do+ let slide = writerSlideVariant opts /= NoSlides && level <= slideLevel+ let num' = zipWith (+) num (writerNumberOffset opts ++ repeat 0)+ modify $ \st -> st{stSecNum = num'} -- update section number+ -- always use level 1 for slide titles+ let level' = if slide then 1 else level+ let titleSlide = slide && level < slideLevel+ header' <- if title' == [Str "\0"] -- marker for hrule+ then return mempty+ else blockToHtml opts (Header level' (id',classes,keyvals) title')+ let isSec (Sec _ _ _ _ _) = True+ isSec (Blk _) = False+ let isPause (Blk x) = x == Para [Str ".",Space,Str ".",Space,Str "."]+ isPause _ = False+ let fragmentClass = case writerSlideVariant opts of+ RevealJsSlides -> "fragment"+ _ -> "incremental"+ let inDiv xs = Blk (RawBlock (Format "html") ("<div class=\""+ ++ fragmentClass ++ "\">")) :+ (xs ++ [Blk (RawBlock (Format "html") "</div>")])+ innerContents <- mapM (elementToHtml slideLevel opts)+ $ if titleSlide+ -- title slides have no content of their own+ then filter isSec elements+ else if slide+ then case splitBy isPause elements of+ [] -> []+ (x:xs) -> x ++ concatMap inDiv xs+ else elements+ let inNl x = mconcat $ nl opts : intersperse (nl opts) x ++ [nl opts]+ let classes' = ["titleslide" | titleSlide] ++ ["slide" | slide] +++ ["section" | (slide || writerSectionDivs opts) &&+ not (writerHtml5 opts) ] +++ ["level" ++ show level | slide || writerSectionDivs opts ]+ ++ classes+ let secttag = if writerHtml5 opts+ then H5.section+ else H.div+ let attr = (id',classes',keyvals)+ return $ if titleSlide+ then (if writerSlideVariant opts == RevealJsSlides+ then H5.section+ else id) $ mconcat $+ (addAttrs opts attr $ secttag $ header') : innerContents+ else if writerSectionDivs opts || slide+ then addAttrs opts attr+ $ secttag $ inNl $ header' : innerContents+ else mconcat $ intersperse (nl opts)+ $ addAttrs opts attr header' : innerContents++-- | Convert list of Note blocks to a footnote <div>.+-- Assumes notes are sorted.+footnoteSection :: WriterOptions -> [Html] -> Html+footnoteSection opts notes =+ if null notes+ then mempty+ else nl opts >> (container+ $ nl opts >> hrtag >> nl opts >>+ H.ol (mconcat notes >> nl opts) >> nl opts)+ where container x = if writerHtml5 opts+ then H5.section ! A.class_ "footnotes" $ x+ else if writerSlideVariant opts /= NoSlides+ then H.div ! A.class_ "footnotes slide" $ x+ else H.div ! A.class_ "footnotes" $ x+ hrtag = if writerHtml5 opts then H5.hr else H.hr++-- | Parse a mailto link; return Just (name, domain) or Nothing.+parseMailto :: String -> Maybe (String, String)+parseMailto s = do+ case break (==':') s of+ (xs,':':addr) | map toLower xs == "mailto" -> do+ let (name', rest) = span (/='@') addr+ let domain = drop 1 rest+ return (name', domain)+ _ -> fail "not a mailto: URL"++-- | Obfuscate a "mailto:" link.+obfuscateLink :: WriterOptions -> Html -> String -> Html+obfuscateLink opts txt s | writerEmailObfuscation opts == NoObfuscation =+ H.a ! A.href (toValue s) $ txt+obfuscateLink opts (renderHtml -> txt) s =+ let meth = writerEmailObfuscation opts+ s' = map toLower (take 7 s) ++ drop 7 s+ in case parseMailto s' of+ (Just (name', domain)) ->+ let domain' = substitute "." " dot " domain+ at' = obfuscateChar '@'+ (linkText, altText) =+ if txt == drop 7 s' -- autolink+ then ("e", name' ++ " at " ++ domain')+ else ("'" ++ txt ++ "'", txt ++ " (" ++ name' ++ " at " +++ domain' ++ ")")+ in case meth of+ ReferenceObfuscation ->+ -- need to use preEscapedString or &'s are escaped to & in URL+ preEscapedString $ "<a href=\"" ++ (obfuscateString s')+ ++ "\" class=\"email\">" ++ (obfuscateString txt) ++ "</a>"+ JavascriptObfuscation ->+ (H.script ! A.type_ "text/javascript" $+ preEscapedString ("\n<!--\nh='" +++ obfuscateString domain ++ "';a='" ++ at' ++ "';n='" +++ obfuscateString name' ++ "';e=n+a+h;\n" +++ "document.write('<a h'+'ref'+'=\"ma'+'ilto'+':'+e+'\" clas'+'s=\"em' + 'ail\">'+" +++ linkText ++ "+'<\\/'+'a'+'>');\n// -->\n")) >>+ H.noscript (preEscapedString $ obfuscateString altText)+ _ -> error $ "Unknown obfuscation method: " ++ show meth+ _ -> H.a ! A.href (toValue s) $ toHtml txt -- malformed email++-- | Obfuscate character as entity.+obfuscateChar :: Char -> String+obfuscateChar char =+ let num = ord char+ numstr = if even num then show num else "x" ++ showHex num ""+ in "&#" ++ numstr ++ ";"++-- | Obfuscate string using entities.+obfuscateString :: String -> String+obfuscateString = concatMap obfuscateChar . fromEntities++addAttrs :: WriterOptions -> Attr -> Html -> Html+addAttrs opts attr h = foldl (!) h (attrsToHtml opts attr)++attrsToHtml :: WriterOptions -> Attr -> [Attribute]+attrsToHtml opts (id',classes',keyvals) =+ [prefixedId opts id' | not (null id')] +++ [A.class_ (toValue $ unwords classes') | not (null classes')] +++ map (\(x,y) -> customAttribute (fromString x) (toValue y)) keyvals++imageExts :: [String]+imageExts = [ "art", "bmp", "cdr", "cdt", "cpt", "cr2", "crw", "djvu", "erf",+ "gif", "ico", "ief", "jng", "jpg", "jpeg", "nef", "orf", "pat", "pbm",+ "pcx", "pdf", "pgm", "png", "pnm", "ppm", "psd", "ras", "rgb", "svg",+ "tiff", "wbmp", "xbm", "xpm", "xwd" ]++treatAsImage :: FilePath -> Bool+treatAsImage fp =+ let path = case uriPath `fmap` parseURIReference fp of+ Nothing -> fp+ Just up -> up+ ext = map toLower $ drop 1 $ takeExtension path+ in null ext || ext `elem` imageExts++setImageWidthFromHistory :: Inline -> State WriterState Inline+setImageWidthFromHistory (Image attr b c) = do+ let attrWidth = fromMaybe "" $ lookupKey "width" attr+ st <- get+ let lastWidth = fromMaybe "" $ stLastWidth st+ let replaceWidth = attrWidth == "same" || attrWidth == "^"+ let currWidth = if replaceWidth+ then lastWidth+ else attrWidth+ when (not $ null currWidth) $ put st { stLastWidth = Just currWidth }+ let attr' = insertReplaceKeyVal ("width",currWidth) attr+ return $ Image attr' b c+setImageWidthFromHistory x = return x++-- | Convert Pandoc block element to HTML.+blockToHtml :: WriterOptions -> Block -> State WriterState Html+blockToHtml _ Null = return mempty+blockToHtml opts (Plain lst) = inlineListToHtml opts lst+-- title beginning with fig: indicates that the image is a figure+blockToHtml opts (Para [Image attr txt (s,'f':'i':'g':':':tit)]) =+ imageGridToHtml opts attr [ImageGrid [[Image attr [] (s,tit)]]] noPrepContent txt+blockToHtml opts (Para lst) = do+ contents <- inlineListToHtml opts lst+ return $ H.p contents+blockToHtml opts (Div attr@(_,classes,_) bs) = do+ contents <- blockListToHtml opts bs+ let contents' = nl opts >> contents >> nl opts+ return $+ if "notes" `elem` classes+ then let opts' = opts{ writerIncremental = False } in+ -- we don't want incremental output inside speaker notes+ case writerSlideVariant opts of+ RevealJsSlides -> addAttrs opts' attr $ H5.aside $ contents'+ NoSlides -> addAttrs opts' attr $ H.div $ contents'+ _ -> mempty+ else addAttrs opts attr $ H.div $ contents'+blockToHtml _ (RawBlock f str)+ | f == Format "html" = return $ preEscapedString str+ | otherwise = return mempty+blockToHtml opts (HorizontalRule) = return $ if writerHtml5 opts then H5.hr else H.hr+blockToHtml opts (CodeBlock (id',classes,keyvals) rawCode) = do+ let tolhs = isEnabled Ext_literate_haskell opts &&+ any (\c -> map toLower c == "haskell") classes &&+ any (\c -> map toLower c == "literate") classes+ classes' = if tolhs+ then map (\c -> if map toLower c == "haskell"+ then "literatehaskell"+ else c) classes+ else classes+ adjCode = if tolhs+ then unlines . map ("> " ++) . lines $ rawCode+ else rawCode+ hlCode = if writerHighlight opts -- check highlighting options+ then highlight formatHtmlBlock (id',classes',keyvals) adjCode+ else Nothing+ case hlCode of+ Nothing -> return $ addAttrs opts (id',classes,keyvals)+ $ H.pre $ H.code $ toHtml adjCode+ Just h -> modify (\st -> st{ stHighlighting = True }) >>+ return (addAttrs opts (id',[],keyvals) h)+blockToHtml opts (BlockQuote blocks) =+ -- in S5, treat list in blockquote specially+ -- if default is incremental, make it nonincremental;+ -- otherwise incremental+ if writerSlideVariant opts /= NoSlides+ then let inc = not (writerIncremental opts) in+ case blocks of+ [BulletList lst] -> blockToHtml (opts {writerIncremental = inc})+ (BulletList lst)+ [OrderedList attribs lst] ->+ blockToHtml (opts {writerIncremental = inc})+ (OrderedList attribs lst)+ [DefinitionList lst] ->+ blockToHtml (opts {writerIncremental = inc})+ (DefinitionList lst)+ _ -> do contents <- blockListToHtml opts blocks+ return $ H.blockquote+ $ nl opts >> contents >> nl opts+ else do+ contents <- blockListToHtml opts blocks+ return $ H.blockquote $ nl opts >> contents >> nl opts+blockToHtml opts (Header level (_,classes,_) lst) = do+ contents <- inlineListToHtml opts lst+ secnum <- liftM stSecNum get+ let contents' = if writerNumberSections opts && not (null secnum)+ && "unnumbered" `notElem` classes+ then (H.span ! A.class_ "header-section-number" $ toHtml+ $ showSecNum secnum) >> strToHtml " " >> contents+ else contents+ return $ case level of+ 1 -> H.h1 contents'+ 2 -> H.h2 contents'+ 3 -> H.h3 contents'+ 4 -> H.h4 contents'+ 5 -> H.h5 contents'+ 6 -> H.h6 contents'+ _ -> H.p contents'+blockToHtml opts (BulletList lst) = do+ contents <- mapM (blockListToHtml opts) lst+ return $ unordList opts contents+blockToHtml opts (OrderedList (startnum, numstyle, _) lst) = do+ contents <- mapM (blockListToHtml opts) lst+ let numstyle' = camelCaseToHyphenated $ show numstyle+ let attribs = (if startnum /= 1+ then [A.start $ toValue startnum]+ else []) +++ (if numstyle /= DefaultStyle+ then if writerHtml5 opts+ then [A.type_ $+ case numstyle of+ Decimal -> "1"+ LowerAlpha -> "a"+ UpperAlpha -> "A"+ LowerRoman -> "i"+ UpperRoman -> "I"+ _ -> "1"]+ else [A.style $ toValue $ "list-style-type: " +++ numstyle']+ else [])+ return $ foldl (!) (ordList opts contents) attribs+blockToHtml opts (DefinitionList lst) = do+ contents <- mapM (\(term, defs) ->+ do term' <- if null term+ then return mempty+ else liftM H.dt $ inlineListToHtml opts term+ defs' <- mapM ((liftM (\x -> H.dd $ (x >> nl opts))) .+ blockListToHtml opts) defs+ return $ mconcat $ nl opts : term' : nl opts :+ intersperse (nl opts) defs') lst+ return $ defList opts contents+blockToHtml opts (Table capt aligns widths headers rows') = do+ captionDoc <- if null capt+ then return mempty+ else do+ cs <- inlineListToHtml opts capt+ return $ H.caption cs >> nl opts+ let percent w = show (truncate (100*w) :: Integer) ++ "%"+ let coltags = if all (== 0.0) widths+ then mempty+ else do+ H.colgroup $ do+ nl opts+ mapM_ (\w -> do+ if writerHtml5 opts+ then H.col ! A.style (toValue $ "width: " +++ percent w)+ else H.col ! A.width (toValue $ percent w)+ nl opts) widths+ nl opts+ head' <- if all null headers+ then return mempty+ else do+ contents <- tableRowToHtml opts aligns 0 headers+ return $ H.thead (nl opts >> contents) >> nl opts+ body' <- liftM (\x -> H.tbody (nl opts >> mconcat x)) $+ zipWithM (tableRowToHtml opts aligns) [1..] rows'+ return $ H.table $ nl opts >> captionDoc >> coltags >> head' >>+ body' >> nl opts+blockToHtml opts (Figure figType attr content pc caption) =+ figureToHtml figType opts attr content pc caption+blockToHtml _ (ImageGrid _) = return mempty+blockToHtml _ (Statement _ _) = return mempty+blockToHtml _ (Proof _ _) = return mempty++tableRowToHtml :: WriterOptions+ -> [Alignment]+ -> Int+ -> [[Block]]+ -> State WriterState Html+tableRowToHtml opts aligns rownum cols' = do+ let mkcell = if rownum == 0 then H.th else H.td+ let rowclass = case rownum of+ 0 -> "header"+ x | x `rem` 2 == 1 -> "odd"+ _ -> "even"+ cols'' <- sequence $ zipWith+ (\alignment item -> tableItemToHtml opts mkcell alignment item)+ aligns cols'+ return $ (H.tr ! A.class_ rowclass $ nl opts >> mconcat cols'')+ >> nl opts++alignmentToString :: Alignment -> [Char]+alignmentToString alignment = case alignment of+ AlignLeft -> "left"+ AlignRight -> "right"+ AlignCenter -> "center"+ AlignDefault -> "left"++tableItemToHtml :: WriterOptions+ -> (Html -> Html)+ -> Alignment+ -> [Block]+ -> State WriterState Html+tableItemToHtml opts tag' align' item = do+ contents <- blockListToHtml opts item+ let alignStr = alignmentToString align'+ let attribs = if writerHtml5 opts+ then A.style (toValue $ "text-align: " ++ alignStr ++ ";")+ else A.align (toValue alignStr)+ return $ (tag' ! attribs $ contents) >> nl opts++toListItems :: WriterOptions -> [Html] -> [Html]+toListItems opts items = map (toListItem opts) items ++ [nl opts]++toListItem :: WriterOptions -> Html -> Html+toListItem opts item = nl opts >> H.li item++blockListToHtml :: WriterOptions -> [Block] -> State WriterState Html+blockListToHtml opts lst =+ fmap (mconcat . intersperse (nl opts)) $ mapM (blockToHtml opts) lst++-- | Convert list of Pandoc inline elements to HTML.+inlineListToHtml :: WriterOptions -> [Inline] -> State WriterState Html+inlineListToHtml opts lst =+ mapM (inlineToHtml opts) (prependNbsp lst) >>= return . mconcat+ -- ## prependNbsp+ -- usually numbered cross-references should be prepended with+ -- a nonbreaking space, so we do that, except when a bunch of+ -- them appears in a comma-separated list+ where prependNbsp [] = []+ prependNbsp (Str "," : Space : NumRef a as : xs) =+ Str "," : Space : NumRef a as : prependNbsp xs+ prependNbsp (Str a : Space : NumRef b bs : xs) =+ Str (a ++ "\160") : NumRef b bs : prependNbsp xs+ prependNbsp (x:xs) = x : prependNbsp xs++-- | Annotates a MathML expression with the tex source+annotateMML :: XML.Element -> String -> XML.Element+annotateMML e tex = math (unode "semantics" [cs, unode "annotation" (annotAttrs, tex)])+ where+ cs = case elChildren e of+ [] -> unode "mrow" ()+ [x] -> x+ xs -> unode "mrow" xs+ math = add_attr (XML.Attr (unqual "xmlns") "http://www.w3.org/1998/Math/MathML") . unode "math"+ annotAttrs = [XML.Attr (unqual "encoding") "application/x-tex"]+++-- | Convert Pandoc inline element to HTML.+inlineToHtml :: WriterOptions -> Inline -> State WriterState Html+inlineToHtml opts inline =+ case inline of+ (Str str) -> return $ strToHtml str+ (Space) -> return $ strToHtml " "+ (LineBreak) -> return $ if writerHtml5 opts then H5.br else H.br+ (Span (id',classes,kvs) ils)+ -> inlineListToHtml opts ils >>=+ return . addAttrs opts attr' . H.span+ where attr' = (id',classes',kvs')+ classes' = filter (`notElem` ["csl-no-emph",+ "csl-no-strong",+ "csl-no-smallcaps"]) classes+ kvs' = if null styles+ then kvs+ else (("style", concat styles) : kvs)+ styles = ["font-style:normal;"+ | "csl-no-emph" `elem` classes]+ ++ ["font-weight:normal;"+ | "csl-no-strong" `elem` classes]+ ++ ["font-variant:normal;"+ | "csl-no-smallcaps" `elem` classes]+ (Emph lst) -> inlineListToHtml opts lst >>= return . H.em+ (Strong lst) -> inlineListToHtml opts lst >>= return . H.strong+ (Code attr str) -> case hlCode of+ Nothing -> return+ $ addAttrs opts attr+ $ H.code $ strToHtml str+ Just h -> do+ modify $ \st -> st{ stHighlighting = True }+ return $ addAttrs opts (id',[],keyvals) h+ where (id',_,keyvals) = attr+ hlCode = if writerHighlight opts+ then highlight formatHtmlInline attr str+ else Nothing+ (Strikeout lst) -> inlineListToHtml opts lst >>=+ return . H.del+ (SmallCaps lst) -> inlineListToHtml opts lst >>=+ return . (H.span ! A.style "font-variant: small-caps;")+ (Superscript lst) -> inlineListToHtml opts lst >>= return . H.sup+ (Subscript lst) -> inlineListToHtml opts lst >>= return . H.sub+ (Quoted quoteType lst) ->+ let (leftQuote, rightQuote) = case quoteType of+ SingleQuote -> (strToHtml "‘",+ strToHtml "’")+ DoubleQuote -> (strToHtml "“",+ strToHtml "”")+ in if writerHtmlQTags opts+ then do+ modify $ \st -> st{ stQuotes = True }+ H.q `fmap` inlineListToHtml opts lst+ else (\x -> leftQuote >> x >> rightQuote)+ `fmap` inlineListToHtml opts lst+ (Math t str) -> modify (\st -> st {stMath = True}) >>+ (case writerHTMLMathMethod opts of+ LaTeXMathML _ ->+ -- putting LaTeXMathML in container with class "LaTeX" prevents+ -- non-math elements on the page from being treated as math by+ -- the javascript+ return $ H.span ! A.class_ "LaTeX" $+ case t of+ InlineMath -> toHtml ("$" ++ str ++ "$")+ (DisplayMath _) -> toHtml ("$$" ++ str ++ "$$")+ JsMath _ -> do+ let m = preEscapedString str+ return $ case t of+ InlineMath -> H.span ! A.class_ "math" $ m+ (DisplayMath _) -> H.div ! A.class_ "math" $ m+ WebTeX url -> do+ let imtag = if writerHtml5 opts then H5.img else H.img+ let m = imtag ! A.style "vertical-align:middle"+ ! A.src (toValue $ url ++ urlEncode str)+ ! A.alt (toValue str)+ ! A.title (toValue str)+ let brtag = if writerHtml5 opts then H5.br else H.br+ return $ case t of+ InlineMath -> m+ (DisplayMath _) -> brtag >> m >> brtag+ GladTeX ->+ return $ case t of+ InlineMath -> preEscapedString $ "<EQ ENV=\"math\">" ++ str ++ "</EQ>"+ (DisplayMath _) -> preEscapedString $ "<EQ ENV=\"displaymath\">" ++ str ++ "</EQ>"+ MathML _ -> do+ let dt = if t == InlineMath+ then DisplayInline+ else DisplayBlock+ let conf = useShortEmptyTags (const False)+ defaultConfigPP+ case writeMathML dt <$> readTeX str of+ Right r -> return $ preEscapedString $+ ppcElement conf (annotateMML r str)+ Left _ -> inlineListToHtml opts+ (texMathToInlines t str) >>=+ return . (H.span ! A.class_ "math")+ MathJax _ -> if writerScholarly opts+ then return $ mathToMathJax opts t str+ else return $ H.span ! A.class_ "math" $ toHtml $+ case t of+ InlineMath -> "\\(" ++ str ++ "\\)"+ DisplayMath _ -> "\\[" ++ str ++ "\\]"+ KaTeX _ _ -> return $ H.span ! A.class_ "math" $+ toHtml (case t of+ InlineMath -> str+ DisplayMath _ -> "\\displaystyle " ++ str)+ PlainMath -> do+ x <- inlineListToHtml opts (texMathToInlines t str)+ let m = H.span ! A.class_ "math" $ x+ let brtag = if writerHtml5 opts then H5.br else H.br+ return $ case t of+ InlineMath -> m+ (DisplayMath _) -> brtag >> m >> brtag )+ (RawInline f str)+ | f == Format "latex" ->+ case writerHTMLMathMethod opts of+ LaTeXMathML _ -> do modify (\st -> st {stMath = True})+ return $ toHtml str+ _ -> return mempty+ | f == Format "html" -> return $ preEscapedString str+ | otherwise -> return mempty+ (Link txt (s,_)) | "mailto:" `isPrefixOf` s -> do+ linkText <- inlineListToHtml opts txt+ return $ obfuscateLink opts linkText s+ (Link txt (s,tit)) -> do+ linkText <- inlineListToHtml opts txt+ let s' = case s of+ '#':xs | writerSlideVariant opts ==+ RevealJsSlides -> '#':'/':xs+ _ -> s+ let link = H.a ! A.href (toValue s') $ linkText+ let link' = if txt == [Str (unEscapeString s)]+ then link ! A.class_ "uri"+ else link+ return $ if null tit+ then link'+ else link' ! A.title (toValue tit)+ (Image attr txt (s,tit)) | treatAsImage s -> do+ let alternate' = stringify txt+ let attributes = [A.src $ toValue s] +++ (if null tit+ then []+ else [A.title $ toValue tit]) +++ if null txt+ then []+ else [A.alt $ toValue alternate']+ let tag = if writerHtml5 opts then H5.img else H.img+ return $ addAttrs opts attr $ foldl (!) tag attributes+ -- note: null title included, as in Markdown.pl+ (Image attr _ (s,tit)) -> do+ let attributes = [A.src $ toValue s] +++ (if null tit+ then []+ else [A.title $ toValue tit])+ return $ addAttrs opts attr $ foldl (!) H5.embed attributes+ -- note: null title included, as in Markdown.pl+ (Note contents)+ | writerIgnoreNotes opts -> return mempty+ | otherwise -> do+ st <- get+ let notes = stNotes st+ let number = (length notes) + 1+ let ref = show number+ htmlContents <- blockListToNote opts ref contents+ -- push contents onto front of notes+ put $ st {stNotes = (htmlContents:notes)}+ let revealSlash = ['/' | writerSlideVariant opts+ == RevealJsSlides]+ let link = H.a ! A.href (toValue $ "#" +++ revealSlash +++ writerIdentifierPrefix opts ++ "fn" ++ ref)+ ! A.class_ "footnoteRef"+ ! prefixedId opts ("fnref" ++ ref)+ $ H.sup+ $ toHtml ref+ return $ case writerEpubVersion opts of+ Just EPUB3 -> link ! customAttribute "epub:type" "noteref"+ _ -> link+ (Cite cits il)-> do contents <- inlineListToHtml opts il+ let citationIds = unwords $ map citationId cits+ let citeClass = if writerScholarly opts+ then "scholmd-citation"+ else "citation"+ let result = H.span ! A.class_ citeClass $ contents+ return $ if writerHtml5 opts+ then result ! customAttribute "data-cites" (toValue citationIds)+ else result+ (NumRef numref _raw) -> do st <- get+ let toMath lab = mathToMathJax opts InlineMath lab+ let refId = numRefId numref+ let refLinkClass = "scholmd-crossref"+ let refText = case numRefStyle numref of+ PlainNumRef -> numRefLabel numref+ ParenthesesNumRef -> [Str "("] +++ numRefLabel numref ++ [Str ")"]+ refTextHtml <- inlineListToHtml opts refText+ let isMathId = refId `elem` (stMathIds st)+ let link = if isMathId+ then case numRefStyle numref of+ PlainNumRef -> toMath $ "\\ref{" ++ refId ++ "}"+ ParenthesesNumRef -> toMath $ "\\eqref{" ++ refId ++ "}"+ else H.a ! A.href (toValue $ '#' : refId) $ refTextHtml+ return $ H.span ! A.class_ refLinkClass $ link++blockListToNote :: WriterOptions -> String -> [Block] -> State WriterState Html+blockListToNote opts ref blocks =+ -- If last block is Para or Plain, include the backlink at the end of+ -- that block. Otherwise, insert a new Plain block with the backlink.+ let backlink = [Link [Str "↩"] ("#" ++ writerIdentifierPrefix opts ++ "fnref" ++ ref,[])]+ blocks' = if null blocks+ then []+ else let lastBlock = last blocks+ otherBlocks = init blocks+ in case lastBlock of+ (Para lst) -> otherBlocks +++ [Para (lst ++ backlink)]+ (Plain lst) -> otherBlocks +++ [Plain (lst ++ backlink)]+ _ -> otherBlocks ++ [lastBlock,+ Plain backlink]+ in do contents <- blockListToHtml opts blocks'+ let noteItem = H.li ! (prefixedId opts ("fn" ++ ref)) $ contents+ let noteItem' = case writerEpubVersion opts of+ Just EPUB3 -> noteItem ! customAttribute "epub:type" "footnote"+ _ -> noteItem+ return $ nl opts >> noteItem'++-- Javascript snippet to render all KaTeX elements+renderKaTeX :: String+renderKaTeX = unlines [+ "window.onload = function(){var mathElements = document.getElementsByClassName(\"math\");"+ , "for (var i=0; i < mathElements.length; i++)"+ , "{"+ , " var texText = mathElements[i].firstChild"+ , " katex.render(texText.data, mathElements[i])"+ , "}}"+ ]++mathToMathJax :: WriterOptions -> MathType -> String -> Html+mathToMathJax opts mathType mathCode =+ case mathType of+ InlineMath -> H.span ! A.class_ "math scholmd-math-inline" $ toHtml $ "\\(" ++ mathCode ++ "\\)"+ DisplayMath attr ->+ mconcat [nl opts,+ H.span ! A.class_ "math scholmd-math-display"+ ! A.style "display: block;" $+ mconcat [toHtml ("\\[" :: String), nl opts,+ toHtml $ dispMathToLaTeX attr mathCode,+ nl opts, toHtml ("\\]" :: String)],+ nl opts]++---+--- Scholarly Markdown floats+---++scholmdFloat :: WriterOptions -> String -> String -> Html -> Html+ -> State WriterState Html+scholmdFloat opts cls identifier content capt = do+ let content' = H.div ! A.class_ "scholmd-float-content" $ content+ return $ H5.figure ! A.class_ (toValue ("scholmd-float " ++ cls))+ !? (identifier /= "", prefixedId opts identifier)+ $ mconcat [nl opts, content', capt, nl opts]++scholmdFloatCaption :: WriterOptions -> String -> String -> Maybe String -> [Inline]+ -> State WriterState Html+scholmdFloatCaption opts cls prefix label text = do+ prefixHtml <- liftM (H.span ! A.class_ "scholmd-caption-head-prefix")+ $ inlineToHtml opts $ Str prefix+ labelHtml <- case label of+ Nothing -> return mempty+ Just lab -> liftM (H.span ! A.class_ "scholmd-caption-head-label")+ $ inlineToHtml opts $ Str lab+ let headerHtml = case label of+ Just _ -> H.span ! A.class_ "scholmd-caption-head"+ $ mconcat [prefixHtml, labelHtml]+ Nothing -> mempty+ textHtml <- if (null text)+ then return mempty+ else liftM (H.span ! A.class_ "scholmd-caption-text")+ $ inlineListToHtml opts text+ return $ if (isNothing label) && (null text)+ then mempty+ else mconcat [ nl opts,+ H.div ! A.class_ (toValue cls) $ H5.figcaption+ $ mconcat [headerHtml, textHtml] ]++-- | main caption for floats+scholmdFloatMainCaption :: WriterOptions -> String -> Maybe String -> [Inline]+ -> State WriterState Html+scholmdFloatMainCaption opts = scholmdFloatCaption opts "scholmd-float-caption"++-- | caption for subfigures+scholmdFloatSubfigCaption :: WriterOptions -> Maybe String -> [Inline]+ -> State WriterState Html+scholmdFloatSubfigCaption opts = scholmdFloatCaption opts "scholmd-float-subcaption" ""++-- | Main helper function for constructing a float with caption from a rendered content block+scholmdFloatFromAttr :: WriterOptions -> String -> String -> Attr -> [Inline] -> Html+ -> State WriterState Html+scholmdFloatFromAttr opts className captionPrefix attr caption content = do+ let ident = getIdentifier attr+ let numLabel = lookupKey "numLabel" attr+ let className' = if (hasClass "wide" attr)+ then className ++ " scholmd-widefloat"+ else className+ floatCaption <- scholmdFloatMainCaption opts captionPrefix numLabel caption+ scholmdFloat opts className' ident content floatCaption++figureToHtml :: FigureType -> WriterOptions -> Attr -> [Block] -> PreparedContent -> [Inline]+ -> State WriterState Html+figureToHtml ImageFigure = imageGridToHtml+figureToHtml TableFigure = tableFloatToHtml+figureToHtml LineBlockFigure = algorithmToHtml+figureToHtml ListingFigure = codeFloatToHtml++imageGridToHtml :: WriterOptions -> Attr -> [Block] -> PreparedContent -> [Inline]+ -> State WriterState Html+imageGridToHtml opts attr imageGrid _fallback caption = do+ -- check for single-image float figure, strip the subcaption if this is the case+ let subfigRows = case (head imageGrid) of+ -- get rid of any subcaption for single image+ ImageGrid [[Image a _ c]] -> [[Image a [] c]]+ ImageGrid a -> a+ _ -> [[]] -- should never happen+ let subfigIds = case (safeRead $ fromMaybe [] $ lookupKey "subfigIds" attr) :: Maybe [String] of+ Just a -> a+ Nothing -> [""]+ -- determine whether to show subfig enumeration labels (a), (b), etc+ let appendLabel = any (not . null) subfigIds && not (hasClass "nonumber" attr)+ let subfiglist = intercalate [LineBreak] subfigRows+ -- need to expand the "same" or "^" keyword for width+ subfiglist' <- mapM (setImageWidthFromHistory) subfiglist+ -- Enumerate all the subfigures+ let subfigs = evalState (mapM (subfigsToHtml opts appendLabel) subfiglist') 1+ subfigsHtml <- sequence subfigs -- Render all subfigs+ let figure = mconcat subfigsHtml+ scholmdFloatFromAttr opts "scholmd-figure" "Figure" attr caption figure++-- Transforms a (single-image) subfigure to HTML.+-- The State Int monad implements the counter for automatic subfigure enumeration+subfigsToHtml :: WriterOptions -> Bool -> Inline -> State Int (State WriterState Html)+subfigsToHtml opts _ LineBreak = do+ return $ return $ if writerHtml5 opts then H5.br else H.br+subfigsToHtml opts appendLabel (Image attr txt (s,tit)) = do+ currentIndex <- get+ put (currentIndex + 1)+ let ident = getIdentifier attr+ let size = case lookupKey "width" attr of+ Just width -> "width: " ++ width+ Nothing -> ""+ let sublabel = if appendLabel+ then Just $ "(" ++ (alphEnum currentIndex) ++ ")"+ else Nothing+ let subcap = scholmdFloatSubfigCaption opts sublabel txt+ let img = H5.img ! (A.src $ toValue s) !? (tit /="", A.title $ toValue tit)+ let content = liftM (\sc -> mconcat[nl opts, img, sc, nl opts]) subcap+ let subfigContext = H5.figure ! A.class_ "scholmd-subfig"+ !? (ident /= "", prefixedId opts ident)+ ! A.style (toValue ("display: inline-block; " ++ size :: String))+ return $ liftM subfigContext content+subfigsToHtml _ _ _ = return $ return mempty++algorithmToHtml :: WriterOptions -> Attr -> [Block] -> PreparedContent -> [Inline]+ -> State WriterState Html+algorithmToHtml opts attr alg _fallback caption = do+ algorithm <- blockListToHtml opts alg+ scholmdFloatFromAttr opts "scholmd-algorithm" "Algorithm" attr caption algorithm++tableFloatToHtml :: WriterOptions -> Attr -> [Block] -> PreparedContent -> [Inline]+ -> State WriterState Html+tableFloatToHtml opts attr tabl _fallback caption = do+ table <- blockListToHtml opts tabl+ scholmdFloatFromAttr opts "scholmd-table-float" "Table" attr caption table++codeFloatToHtml :: WriterOptions -> Attr -> [Block] -> PreparedContent -> [Inline]+ -> State WriterState Html+codeFloatToHtml opts attr codeblk _fallback caption = do+ codeblock <- blockListToHtml opts codeblk+ scholmdFloatFromAttr opts "scholmd-listing-float" "Listing" attr caption codeblock
@@ -0,0 +1,351 @@+{-# LANGUAGE OverloadedStrings, TupleSections, ScopedTypeVariables #-}+{-+Copyright (C) 2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.Haddock+ Copyright : Copyright (C) 2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to haddock markup.++Haddock: <http://www.haskell.org/haddock/doc/html/>+-}+module Text.Pandoc.Writers.Haddock (writeHaddock) where+import Text.Pandoc.Definition+import Text.Pandoc.Templates (renderTemplate')+import Text.Pandoc.Shared+import Text.Pandoc.Writers.Shared+import Text.Pandoc.Options+import Data.List ( intersperse, transpose )+import Text.Pandoc.Pretty+import Control.Monad.State+import Text.Pandoc.Readers.TeXMath (texMathToInlines)+import Network.URI (isURI)+import Data.Default++type Notes = [[Block]]+data WriterState = WriterState { stNotes :: Notes }+instance Default WriterState+ where def = WriterState{ stNotes = [] }++-- | Convert Pandoc to Haddock.+writeHaddock :: WriterOptions -> Pandoc -> String+writeHaddock opts document =+ evalState (pandocToHaddock opts{+ writerWrapText = writerWrapText opts } document) def++-- | Return haddock representation of document.+pandocToHaddock :: WriterOptions -> Pandoc -> State WriterState String+pandocToHaddock opts (Pandoc meta blocks) = do+ let colwidth = if writerWrapText opts+ then Just $ writerColumns opts+ else Nothing+ body <- blockListToHaddock opts blocks+ st <- get+ notes' <- notesToHaddock opts (reverse $ stNotes st)+ let render' :: Doc -> String+ render' = render colwidth+ let main = render' $ body <>+ (if isEmpty notes' then empty else blankline <> notes')+ metadata <- metaToJSON opts+ (fmap (render colwidth) . blockListToHaddock opts)+ (fmap (render colwidth) . inlineListToHaddock opts)+ meta+ let context = defField "body" main+ $ metadata+ if writerStandalone opts+ then return $ renderTemplate' (writerTemplate opts) context+ else return main++-- | Return haddock representation of notes.+notesToHaddock :: WriterOptions -> [[Block]] -> State WriterState Doc+notesToHaddock opts notes =+ if null notes+ then return empty+ else do+ contents <- blockToHaddock opts $ OrderedList (1,DefaultStyle,DefaultDelim) notes+ return $ text "#notes#" <> blankline <> contents++-- | Escape special characters for Haddock.+escapeString :: String -> String+escapeString = escapeStringUsing haddockEscapes+ where haddockEscapes = backslashEscapes "\\/'`\"@<"++-- | Convert Pandoc block element to haddock.+blockToHaddock :: WriterOptions -- ^ Options+ -> Block -- ^ Block element+ -> State WriterState Doc+blockToHaddock _ Null = return empty+blockToHaddock opts (Div _ ils) = do+ contents <- blockListToHaddock opts ils+ return $ contents <> blankline+blockToHaddock opts (Plain inlines) = do+ contents <- inlineListToHaddock opts inlines+ return $ contents <> cr+-- title beginning with fig: indicates figure+blockToHaddock opts (Para [Image _ alt (src,'f':'i':'g':':':tit)]) =+ blockToHaddock opts (Para [Image nullAttr alt (src,tit)])+blockToHaddock opts (Para inlines) =+ -- TODO: if it contains linebreaks, we need to use a @...@ block+ (<> blankline) `fmap` blockToHaddock opts (Plain inlines)+blockToHaddock _ (RawBlock f str)+ | f == "haddock" = do+ return $ text str <> text "\n"+ | otherwise = return empty+blockToHaddock opts HorizontalRule =+ return $ blankline <> text (replicate (writerColumns opts) '_') <> blankline+blockToHaddock opts (Header level (ident,_,_) inlines) = do+ contents <- inlineListToHaddock opts inlines+ let attr' = if null ident+ then empty+ else cr <> text "#" <> text ident <> text "#"+ return $ nowrap (text (replicate level '=') <> space <> contents)+ <> attr' <> blankline+blockToHaddock _ (CodeBlock (_,_,_) str) =+ return $ prefixed "> " (text str) <> blankline+-- Nothing in haddock corresponds to block quotes:+blockToHaddock opts (BlockQuote blocks) =+ blockListToHaddock opts blocks+-- Haddock doesn't have tables. Use haddock tables in code.+blockToHaddock opts (Table caption aligns widths headers rows) = do+ caption' <- inlineListToHaddock opts caption+ let caption'' = if null caption+ then empty+ else blankline <> caption' <> blankline+ rawHeaders <- mapM (blockListToHaddock opts) headers+ rawRows <- mapM (mapM (blockListToHaddock opts)) rows+ let isSimple = all (==0) widths+ let isPlainBlock (Plain _) = True+ isPlainBlock _ = False+ let hasBlocks = not (all isPlainBlock $ concat . concat $ headers:rows)+ (nst,tbl) <- case True of+ _ | isSimple -> fmap (nest 2,) $+ pandocTable opts (all null headers) aligns widths+ rawHeaders rawRows+ | not hasBlocks -> fmap (nest 2,) $+ pandocTable opts (all null headers) aligns widths+ rawHeaders rawRows+ | otherwise -> fmap (id,) $+ gridTable opts (all null headers) aligns widths+ rawHeaders rawRows+ return $ (prefixed "> " $ nst $ tbl $$ blankline $$ caption'') $$ blankline+blockToHaddock opts (BulletList items) = do+ contents <- mapM (bulletListItemToHaddock opts) items+ return $ cat contents <> blankline+blockToHaddock opts (OrderedList (start,_,delim) items) = do+ let attribs = (start, Decimal, delim)+ let markers = orderedListMarkers attribs+ let markers' = map (\m -> if length m < 3+ then m ++ replicate (3 - length m) ' '+ else m) markers+ contents <- mapM (\(item, num) -> orderedListItemToHaddock opts item num) $+ zip markers' items+ return $ cat contents <> blankline+blockToHaddock opts (DefinitionList items) = do+ contents <- mapM (definitionListItemToHaddock opts) items+ return $ cat contents <> blankline+blockToHaddock _ (Figure _ _ _ _ _) = return empty+blockToHaddock _ (ImageGrid _) = return empty+blockToHaddock _ (Statement _ _) = return empty+blockToHaddock _ (Proof _ _) = return empty++pandocTable :: WriterOptions -> Bool -> [Alignment] -> [Double]+ -> [Doc] -> [[Doc]] -> State WriterState Doc+pandocTable opts headless aligns widths rawHeaders rawRows = do+ let isSimple = all (==0) widths+ let alignHeader alignment = case alignment of+ AlignLeft -> lblock+ AlignCenter -> cblock+ AlignRight -> rblock+ AlignDefault -> lblock+ let numChars = maximum . map offset+ let widthsInChars = if isSimple+ then map ((+2) . numChars)+ $ transpose (rawHeaders : rawRows)+ else map+ (floor . (fromIntegral (writerColumns opts) *))+ widths+ let makeRow = hcat . intersperse (lblock 1 (text " ")) .+ (zipWith3 alignHeader aligns widthsInChars)+ let rows' = map makeRow rawRows+ let head' = makeRow rawHeaders+ let maxRowHeight = maximum $ map height (head':rows')+ let underline = cat $ intersperse (text " ") $+ map (\width -> text (replicate width '-')) widthsInChars+ let border = if maxRowHeight > 1+ then text (replicate (sum widthsInChars ++ length widthsInChars - 1) '-')+ else if headless+ then underline+ else empty+ let head'' = if headless+ then empty+ else border <> cr <> head'+ let body = if maxRowHeight > 1+ then vsep rows'+ else vcat rows'+ let bottom = if headless+ then underline+ else border+ return $ head'' $$ underline $$ body $$ bottom++gridTable :: WriterOptions -> Bool -> [Alignment] -> [Double]+ -> [Doc] -> [[Doc]] -> State WriterState Doc+gridTable opts headless _aligns widths headers' rawRows = do+ let numcols = length headers'+ let widths' = if all (==0) widths+ then replicate numcols (1.0 / fromIntegral numcols)+ else widths+ let widthsInChars = map (floor . (fromIntegral (writerColumns opts) *)) widths'+ let hpipeBlocks blocks = hcat [beg, middle, end]+ where h = maximum (map height blocks)+ sep' = lblock 3 $ vcat (map text $ replicate h " | ")+ beg = lblock 2 $ vcat (map text $ replicate h "| ")+ end = lblock 2 $ vcat (map text $ replicate h " |")+ middle = chomp $ hcat $ intersperse sep' blocks+ let makeRow = hpipeBlocks . zipWith lblock widthsInChars+ let head' = makeRow headers'+ let rows' = map (makeRow . map chomp) rawRows+ let border ch = char '+' <> char ch <>+ (hcat $ intersperse (char ch <> char '+' <> char ch) $+ map (\l -> text $ replicate l ch) widthsInChars) <>+ char ch <> char '+'+ let body = vcat $ intersperse (border '-') rows'+ let head'' = if headless+ then empty+ else head' $$ border '='+ return $ border '-' $$ head'' $$ body $$ border '-'++-- | Convert bullet list item (list of blocks) to haddock+bulletListItemToHaddock :: WriterOptions -> [Block] -> State WriterState Doc+bulletListItemToHaddock opts items = do+ contents <- blockListToHaddock opts items+ let sps = replicate (writerTabStop opts - 2) ' '+ let start = text ('-' : ' ' : sps)+ -- remove trailing blank line if it is a tight list+ let contents' = case reverse items of+ (BulletList xs:_) | isTightList xs ->+ chomp contents <> cr+ (OrderedList _ xs:_) | isTightList xs ->+ chomp contents <> cr+ _ -> contents+ return $ hang (writerTabStop opts) start $ contents' <> cr++-- | Convert ordered list item (a list of blocks) to haddock+orderedListItemToHaddock :: WriterOptions -- ^ options+ -> String -- ^ list item marker+ -> [Block] -- ^ list item (list of blocks)+ -> State WriterState Doc+orderedListItemToHaddock opts marker items = do+ contents <- blockListToHaddock opts items+ let sps = case length marker - writerTabStop opts of+ n | n > 0 -> text $ replicate n ' '+ _ -> text " "+ let start = text marker <> sps+ return $ hang (writerTabStop opts) start $ contents <> cr++-- | Convert definition list item (label, list of blocks) to haddock+definitionListItemToHaddock :: WriterOptions+ -> ([Inline],[[Block]])+ -> State WriterState Doc+definitionListItemToHaddock opts (label, defs) = do+ labelText <- inlineListToHaddock opts label+ defs' <- mapM (mapM (blockToHaddock opts)) defs+ let contents = vcat $ map (\d -> hang 4 empty $ vcat d <> cr) defs'+ return $ nowrap (brackets labelText) <> cr <> contents <> cr++-- | Convert list of Pandoc block elements to haddock+blockListToHaddock :: WriterOptions -- ^ Options+ -> [Block] -- ^ List of block elements+ -> State WriterState Doc+blockListToHaddock opts blocks =+ mapM (blockToHaddock opts) blocks >>= return . cat++-- | Convert list of Pandoc inline elements to haddock.+inlineListToHaddock :: WriterOptions -> [Inline] -> State WriterState Doc+inlineListToHaddock opts lst =+ mapM (inlineToHaddock opts) lst >>= return . cat++-- | Convert Pandoc inline element to haddock.+inlineToHaddock :: WriterOptions -> Inline -> State WriterState Doc+inlineToHaddock opts (Span (ident,_,_) ils) = do+ contents <- inlineListToHaddock opts ils+ if not (null ident) && null ils+ then return $ "#" <> text ident <> "#"+ else return contents+inlineToHaddock opts (Emph lst) = do+ contents <- inlineListToHaddock opts lst+ return $ "/" <> contents <> "/"+inlineToHaddock opts (Strong lst) = do+ contents <- inlineListToHaddock opts lst+ return $ "__" <> contents <> "__"+inlineToHaddock opts (Strikeout lst) = do+ contents <- inlineListToHaddock opts lst+ -- not supported in haddock, but we fake it:+ return $ "~~" <> contents <> "~~"+-- not supported in haddock:+inlineToHaddock opts (Superscript lst) = inlineListToHaddock opts lst+-- not supported in haddock:+inlineToHaddock opts (Subscript lst) = inlineListToHaddock opts lst+-- not supported in haddock:+inlineToHaddock opts (SmallCaps lst) = inlineListToHaddock opts lst+inlineToHaddock opts (Quoted SingleQuote lst) = do+ contents <- inlineListToHaddock opts lst+ return $ "‘" <> contents <> "’"+inlineToHaddock opts (Quoted DoubleQuote lst) = do+ contents <- inlineListToHaddock opts lst+ return $ "“" <> contents <> "”"+inlineToHaddock _ (Code _ str) =+ return $ "@" <> text (escapeString str) <> "@"+inlineToHaddock _ (Str str) = do+ return $ text $ escapeString str+inlineToHaddock opts (Math mt str) = do+ let adjust x = case mt of+ DisplayMath _ -> cr <> x <> cr+ InlineMath -> x+ adjust `fmap` (inlineListToHaddock opts $ texMathToInlines mt str)+inlineToHaddock _ (RawInline f str)+ | f == "haddock" = return $ text str+ | otherwise = return empty+-- no line break in haddock (see above on CodeBlock)+inlineToHaddock _ (LineBreak) = return cr+inlineToHaddock _ Space = return space+inlineToHaddock opts (Cite _ lst) = inlineListToHaddock opts lst+inlineToHaddock opts (Link txt (src, _)) = do+ linktext <- inlineListToHaddock opts txt+ let useAuto = isURI src &&+ case txt of+ [Str s] | escapeURI s == src -> True+ _ -> False+ return $ nowrap $ "<" <> text src <>+ (if useAuto then empty else space <> linktext) <> ">"+inlineToHaddock opts (Image _ alternate (source, tit)) = do+ linkhaddock <- inlineToHaddock opts (Link alternate (source, tit))+ return $ "<" <> linkhaddock <> ">"+-- haddock doesn't have notes, but we can fake it:+inlineToHaddock opts (Note contents) = do+ modify (\st -> st{ stNotes = contents : stNotes st })+ st <- get+ let ref = text $ writerIdentifierPrefix opts ++ show (length $ stNotes st)+ return $ "<#notes [" <> ref <> "]>"+inlineToHaddock _ (NumRef _ _) = return empty
@@ -0,0 +1,1226 @@+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables,+ PatternGuards #-}+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>+Copyright (C) 2014 Tim T.Y. Lin <timtylin@gmail.com>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.LaTeX+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' format into LaTeX.+-}+module Text.Pandoc.Writers.LaTeX ( writeLaTeX ) where+import Text.Pandoc.Definition+import Text.Pandoc.Walk+import Text.Pandoc.Shared+import Text.Pandoc.Writers.Shared+import Text.Pandoc.Options+import Text.Pandoc.Scholarly+import Text.Pandoc.Templates+import Text.Printf ( printf )+import Network.URI ( isURI, unEscapeString )+import System.FilePath ( dropExtension )+import Data.List ( (\\), isSuffixOf, isInfixOf, stripPrefix,+ isPrefixOf, intercalate, intersperse )+import Data.Char ( toLower, isPunctuation, isAscii, isLetter, isDigit, ord )+import Data.Maybe ( fromMaybe , isJust, fromJust )+import qualified Data.Map as M+import Control.Applicative ((<|>))+import Control.Monad.State+import Text.Pandoc.Pretty+import Text.Pandoc.Slides+import Text.Pandoc.Highlighting (highlight, styleToLaTeX,+ formatLaTeXInline, formatLaTeXBlock,+ toListingsLanguage)++data WriterState =+ WriterState { stInNote :: Bool -- true if we're in a note+ , stInQuote :: Bool -- true if in a blockquote+ , stInMinipage :: Bool -- true if in minipage+ , stInHeading :: Bool -- true if in a section heading+ , stNotes :: [Doc] -- notes in a minipage+ , stOLLevel :: Int -- level of ordered list nesting+ , stOptions :: WriterOptions -- writer options, so they don't have to be parameter+ , stVerbInNote :: Bool -- true if document has verbatim text in note+ , stTable :: Bool -- true if document has a table+ , stStrikeout :: Bool -- true if document has strikeout+ , stUrl :: Bool -- true if document has visible URL link+ , stGraphics :: Bool -- true if document contains images+ , stFloats :: Bool -- true if document contains floats+ , stSubfigs :: Bool -- true if document contains subfigures+ , stAlgorithms :: Bool -- true if document contains algorithm floats+ , stLHS :: Bool -- true if document has literate haskell code+ , stBook :: Bool -- true if document uses book or memoir class+ , stCsquotes :: Bool -- true if document uses csquotes+ , stHighlighting :: Bool -- true if document has highlighted code+ , stIncremental :: Bool -- true if beamer lists should be displayed bit by bit+ , stInternalLinks :: [String] -- list of internal link targets+ , stUsesEuro :: Bool -- true if euro symbol used+ , stMathIds :: [String] -- list of math identifiers,+ , stLastHeight :: Maybe String -- last img height value+ , stLastWidth :: Maybe String -- last img width value+ }++-- | Convert Pandoc to LaTeX.+writeLaTeX :: WriterOptions -> Pandoc -> String+writeLaTeX options document =+ evalState (pandocToLaTeX options document) $+ WriterState { stInNote = False, stInQuote = False,+ stInMinipage = False, stInHeading = False,+ stNotes = [], stOLLevel = 1,+ stOptions = options, stVerbInNote = False,+ stTable = False, stStrikeout = False,+ stUrl = False, stGraphics = False,+ stFloats = False, stSubfigs = False,+ stAlgorithms = False, stLHS = False,+ stBook = (writerChapters options) && not (writerScholarly options),+ stCsquotes = False, stHighlighting = False,+ stIncremental = writerIncremental options,+ stInternalLinks = [], stUsesEuro = False,+ stMathIds = [], stLastHeight = Nothing,+ stLastWidth = Nothing }++pandocToLaTeX :: WriterOptions -> Pandoc -> State WriterState String+pandocToLaTeX options (Pandoc meta blocks) = do+ -- Strip off final 'references' header if --natbib or --biblatex+ let method = writerCiteMethod options+ let blocks' = if method == Biblatex || method == Natbib+ then case reverse blocks of+ (Div (_,["references"],_) _):xs -> reverse xs+ _ -> blocks+ else blocks+ -- see if there are internal links+ let isInternalLink (Link _ ('#':xs,_)) = [xs]+ isInternalLink _ = []+ modify $ \s -> s{ stInternalLinks = query isInternalLink blocks' }+ -- see if there are images+ let isGraphic (Image _ _ _) = [True]+ isGraphic _ = []+ modify $ \s -> s{ stGraphics = not $ null $ query isGraphic blocks' }+ let template = writerTemplate options+ -- set stBook depending on documentclass+ let bookClasses = ["memoir","book","report","scrreprt","scrbook"]+ case lookup "documentclass" (writerVariables options) of+ Just x | x `elem` bookClasses -> modify $ \s -> s{stBook = True}+ | otherwise -> return ()+ Nothing | any (\x -> "\\documentclass" `isPrefixOf` x &&+ (any (`isSuffixOf` x) bookClasses))+ (lines template) -> modify $ \s -> s{stBook = True}+ | otherwise -> return ()+ -- check for \usepackage...{csquotes}; if present, we'll use+ -- \enquote{...} for smart quotes:+ when ("{csquotes}" `isInfixOf` template) $+ modify $ \s -> s{stCsquotes = True}+ let colwidth = if writerWrapText options+ then Just $ writerColumns options+ else Nothing+ metadata <- metaToJSON options+ (fmap (render colwidth) . blockListToLaTeX)+ (fmap (render colwidth) . inlineListToLaTeX)+ meta+ initSt <- get+ let mathIds = extractMetaStringList $ lookupMeta "identifiersForMath" meta+ put initSt{ stMathIds = mathIds }+ let mathDefs = lookupMeta "latexMacrosForMath" meta+ let (blocks'', lastHeader) = if writerCiteMethod options == Citeproc then+ (blocks', [])+ else case last blocks' of+ Header 2 _ il | writerChapters options+ && writerScholarly options+ -> (init blocks', il)+ Header 1 _ il -> (init blocks', il)+ _ -> (blocks', [])+ blocks''' <- if writerBeamer options+ then toSlides blocks''+ else return blocks''+ body <- mapM (elementToLaTeX options) $ hierarchicalize blocks'''+ (biblioTitle :: String) <- liftM (render colwidth) $ inlineListToLaTeX lastHeader+ let biblioFiles = extractMetaStringList $ lookupMeta "bibliography" meta+ let main = render colwidth $ vsep body+ st <- get+ titleMeta <- stringToLaTeX TextString $ stringify $ docTitle meta+ authorsMeta <- mapM (stringToLaTeX TextString . stringify) $ docAuthors meta+ let context = defField "toc" (writerTableOfContents options) $+ defField "toc-depth" (show (writerTOCDepth options -+ if stBook st+ then 1+ else 0)) $+ defField "body" main $+ defField "title-meta" titleMeta $+ defField "author-meta" (intercalate "; " authorsMeta) $+ defField "documentclass" (if writerBeamer options+ then ("beamer" :: String)+ else if stBook st+ then "book"+ else "article") $+ defField "verbatim-in-note" (stVerbInNote st) $+ defField "tables" (stTable st) $+ defField "strikeout" (stStrikeout st) $+ defField "url" (stUrl st) $+ defField "numbersections" (writerNumberSections options) $+ defField "lhs" (stLHS st) $+ defField "graphics" (stGraphics st) $+ defField "floats" (stFloats st) $+ defField "subfigures" (stSubfigs st) $+ defField "algorithms" (stAlgorithms st) $+ defField "book-class" (stBook st) $+ defField "euro" (stUsesEuro st) $+ defField "listings" (writerListings options+ || writerScholarly options+ || stLHS st ) $+ defField "beamer" (writerBeamer options) $+ defField "mainlang" (maybe "" (reverse . takeWhile (/=',') . reverse)+ (lookup "lang" $ writerVariables options)) $+ (if isJust mathDefs+ then defField "math-macros"+ (extractMetaString $ fromJust mathDefs)+ else id) $+ (if stHighlighting st+ then defField "highlighting-macros" (styleToLaTeX+ $ writerHighlightStyle options )+ else id) $+ (case writerCiteMethod options of+ Natbib -> defField "biblio-title" biblioTitle .+ defField "biblio-files"+ (intercalate "," $ map dropExtension $+ biblioFiles) .+ defField "natbib" True+ Biblatex -> defField "biblio-title" biblioTitle .+ defField "biblio-files"+ (intercalate "," biblioFiles) .+ defField "biblatex" True+ _ -> id) $+ metadata+ return $ if writerStandalone options+ then renderTemplate' template context+ else main++-- | Convert Elements to LaTeX+elementToLaTeX :: WriterOptions -> Element -> State WriterState Doc+elementToLaTeX _ (Blk block) = blockToLaTeX block+elementToLaTeX opts (Sec level _ (id',classes,_) title' elements) = do+ modify $ \s -> s{stInHeading = True}+ header' <- sectionHeader ("unnumbered" `elem` classes) id' level title'+ modify $ \s -> s{stInHeading = False}+ innerContents <- mapM (elementToLaTeX opts) elements+ return $ vsep (header' : innerContents)++data StringContext = TextString+ | URLString+ | CodeString+ deriving (Eq)++-- escape things as needed for LaTeX+stringToLaTeX :: StringContext -> String -> State WriterState String+stringToLaTeX _ [] = return ""+stringToLaTeX ctx (x:xs) = do+ opts <- gets stOptions+ rest <- stringToLaTeX ctx xs+ let ligatures = writerTeXLigatures opts && ctx == TextString+ let isUrl = ctx == URLString+ when (x == '€') $+ modify $ \st -> st{ stUsesEuro = True }+ return $+ case x of+ '€' -> "\\euro{}" ++ rest+ '{' -> "\\{" ++ rest+ '}' -> "\\}" ++ rest+ '$' -> "\\$" ++ rest+ '%' -> "\\%" ++ rest+ '&' -> "\\&" ++ rest+ '_' | not isUrl -> "\\_" ++ rest+ '#' -> "\\#" ++ rest+ '-' | not isUrl -> case xs of+ -- prevent adjacent hyphens from forming ligatures+ ('-':_) -> "-\\/" ++ rest+ _ -> '-' : rest+ '~' | not isUrl -> "\\textasciitilde{}" ++ rest+ '^' -> "\\^{}" ++ rest+ '\\'| isUrl -> '/' : rest -- NB. / works as path sep even on Windows+ | otherwise -> "\\textbackslash{}" ++ rest+ '|' -> "\\textbar{}" ++ rest+ '<' -> "\\textless{}" ++ rest+ '>' -> "\\textgreater{}" ++ rest+ '[' -> "{[}" ++ rest -- to avoid interpretation as+ ']' -> "{]}" ++ rest -- optional arguments+ '\'' | ctx == CodeString -> "\\textquotesingle{}" ++ rest+ '\160' -> "~" ++ rest+ '\x2026' -> "\\ldots{}" ++ rest+ '\x2018' | ligatures -> "`" ++ rest+ '\x2019' | ligatures -> "'" ++ rest+ '\x201C' | ligatures -> "``" ++ rest+ '\x201D' | ligatures -> "''" ++ rest+ '\x2014' | ligatures -> "---" ++ rest+ '\x2013' | ligatures -> "--" ++ rest+ _ -> x : rest++toLabel :: String -> State WriterState String+toLabel z = go `fmap` stringToLaTeX URLString z+ where go [] = ""+ go (x:xs)+ | (isLetter x || isDigit x) && isAscii x = x:go xs+ | elem x "-+=:;." = x:go xs+ | otherwise = "ux" ++ printf "%x" (ord x) ++ go xs++-- | Puts contents into LaTeX command.+inCmd :: String -> Doc -> Doc+inCmd cmd contents = char '\\' <> text cmd <> braces contents++toSlides :: [Block] -> State WriterState [Block]+toSlides bs = do+ opts <- gets stOptions+ let slideLevel = fromMaybe (getSlideLevel bs) $ writerSlideLevel opts+ let bs' = prepSlides slideLevel bs+ concat `fmap` (mapM (elementToBeamer slideLevel) $ hierarchicalize bs')++elementToBeamer :: Int -> Element -> State WriterState [Block]+elementToBeamer _slideLevel (Blk b) = return [b]+elementToBeamer slideLevel (Sec lvl _num (ident,classes,kvs) tit elts)+ | lvl > slideLevel = do+ bs <- concat `fmap` mapM (elementToBeamer slideLevel) elts+ return $ Para ( RawInline "latex" "\\begin{block}{"+ : tit ++ [RawInline "latex" "}"] )+ : bs ++ [RawBlock "latex" "\\end{block}"]+ | lvl < slideLevel = do+ bs <- concat `fmap` mapM (elementToBeamer slideLevel) elts+ return $ (Header lvl (ident,classes,kvs) tit) : bs+ | otherwise = do -- lvl == slideLevel+ -- note: [fragile] is required or verbatim breaks+ let hasCodeBlock (CodeBlock _ _) = [True]+ hasCodeBlock _ = []+ let hasCode (Code _ _) = [True]+ hasCode _ = []+ opts <- gets stOptions+ let fragile = not $ null $ query hasCodeBlock elts +++ if writerListings opts+ then query hasCode elts+ else []+ let allowframebreaks = "allowframebreaks" `elem` classes+ let optionslist = ["fragile" | fragile] +++ ["allowframebreaks" | allowframebreaks]+ let options = if null optionslist+ then ""+ else "[" ++ intercalate "," optionslist ++ "]"+ let slideStart = Para $ RawInline "latex" ("\\begin{frame}" ++ options) :+ if tit == [Str "\0"] -- marker for hrule+ then []+ else (RawInline "latex" "{") : tit ++ [RawInline "latex" "}"]+ let slideEnd = RawBlock "latex" "\\end{frame}"+ -- now carve up slide into blocks if there are sections inside+ bs <- concat `fmap` mapM (elementToBeamer slideLevel) elts+ return $ slideStart : bs ++ [slideEnd]++isListBlock :: Block -> Bool+isListBlock (BulletList _) = True+isListBlock (OrderedList _ _) = True+isListBlock (DefinitionList _) = True+isListBlock _ = False++isLineBreakOrSpace :: Inline -> Bool+isLineBreakOrSpace LineBreak = True+isLineBreakOrSpace Space = True+isLineBreakOrSpace _ = False++-- | Convert Pandoc block element to LaTeX.+blockToLaTeX :: Block -- ^ Block to convert+ -> State WriterState Doc+blockToLaTeX Null = return empty+blockToLaTeX (Div (identifier,classes,_) bs) = do+ beamer <- writerBeamer `fmap` gets stOptions+ ref <- toLabel identifier+ let linkAnchor = if null identifier+ then empty+ else "\\hyperdef{}" <> braces (text ref) <> "{}"+ contents <- blockListToLaTeX bs+ if beamer && "notes" `elem` classes -- speaker notes+ then return $ "\\note" <> braces contents+ else return (linkAnchor $$ contents)+blockToLaTeX (Plain lst) =+ inlineListToLaTeX $ dropWhile isLineBreakOrSpace lst+-- title beginning with fig: indicates that the image is a figure+-- the identifiers in attr will be lifted to the Figure block+blockToLaTeX (Para [Image attr txt (src,'f':'i':'g':':':tit)]) =+ imageGridToLaTeX attr [ImageGrid [[Image attr [] (src,tit)]]] noPrepContent txt+-- . . . indicates pause in beamer slides+blockToLaTeX (Para [Str ".",Space,Str ".",Space,Str "."]) = do+ beamer <- writerBeamer `fmap` gets stOptions+ if beamer+ then blockToLaTeX (RawBlock "latex" "\\pause")+ else inlineListToLaTeX [Str ".",Space,Str ".",Space,Str "."]+blockToLaTeX (Para lst) =+ inlineListToLaTeX $ dropWhile isLineBreakOrSpace lst+blockToLaTeX (BlockQuote lst) = do+ beamer <- writerBeamer `fmap` gets stOptions+ case lst of+ [b] | beamer && isListBlock b -> do+ oldIncremental <- gets stIncremental+ modify $ \s -> s{ stIncremental = not oldIncremental }+ result <- blockToLaTeX b+ modify $ \s -> s{ stIncremental = oldIncremental }+ return result+ _ -> do+ oldInQuote <- gets stInQuote+ modify (\s -> s{stInQuote = True})+ contents <- blockListToLaTeX lst+ modify (\s -> s{stInQuote = oldInQuote})+ return $ "\\begin{quote}" $$ contents $$ "\\end{quote}"+blockToLaTeX (CodeBlock (identifier,classes,keyvalAttr) str) = do+ opts <- gets stOptions+ ref <- toLabel identifier+ let linkAnchor = if null identifier+ then empty+ else "\\hyperdef{}" <> braces (text ref) <>+ braces ("\\label" <> braces (text ref))+ let lhsCodeBlock = do+ modify $ \s -> s{ stLHS = True }+ return $ flush (linkAnchor $$ "\\begin{code}" $$ text str $$+ "\\end{code}") $$ cr+ let rawCodeBlock = do+ st <- get+ env <- if stInNote st+ then modify (\s -> s{ stVerbInNote = True }) >>+ return "Verbatim"+ else return "verbatim"+ return $ flush (linkAnchor $$ text ("\\begin{" ++ env ++ "}") $$+ text str $$ text ("\\end{" ++ env ++ "}")) <> cr+ let listingsCodeBlock = do+ st <- get+ let params = if writerListings (stOptions st)+ then (case getListingsLanguage classes of+ Just l -> [ "language=" ++ l ]+ Nothing -> []) +++ [ "numbers=left" | "numberLines" `elem` classes+ || "number" `elem` classes+ || "number-lines" `elem` classes ] +++ [ (if key == "startFrom"+ then "firstnumber"+ else key) ++ "=" ++ attr |+ (key,attr) <- keyvalAttr ] +++ (if identifier == ""+ then []+ else [ "label=" ++ ref ])++ else []+ printParams+ | null params = empty+ | otherwise = brackets $ hcat (intersperse ", " (map text params))+ return $ flush ("\\begin{lstlisting}" <> printParams $$ text str $$+ "\\end{lstlisting}") $$ cr+ let highlightedCodeBlock =+ case highlight formatLaTeXBlock ("",classes,keyvalAttr) str of+ Nothing -> rawCodeBlock+ Just h -> modify (\st -> st{ stHighlighting = True }) >>+ return (flush $ linkAnchor $$ text h)+ case () of+ _ | isEnabled Ext_literate_haskell opts && "haskell" `elem` classes &&+ "literate" `elem` classes -> lhsCodeBlock+ | writerListings opts -> listingsCodeBlock+ | writerHighlight opts && not (null classes) -> highlightedCodeBlock+ | otherwise -> rawCodeBlock+blockToLaTeX (RawBlock f x)+ | f == Format "latex" || f == Format "tex"+ = return $ text x+ | otherwise = return empty+blockToLaTeX (BulletList []) = return empty -- otherwise latex error+blockToLaTeX (BulletList lst) = do+ incremental <- gets stIncremental+ let inc = if incremental then "[<+->]" else ""+ items <- mapM listItemToLaTeX lst+ let spacing = if isTightList lst+ then text "\\itemsep1pt\\parskip0pt\\parsep0pt"+ else empty+ return $ text ("\\begin{itemize}" ++ inc) $$ spacing $$ vcat items $$+ "\\end{itemize}"+blockToLaTeX (OrderedList _ []) = return empty -- otherwise latex error+blockToLaTeX (OrderedList (start, numstyle, numdelim) lst) = do+ st <- get+ let inc = if stIncremental st then "[<+->]" else ""+ let oldlevel = stOLLevel st+ put $ st {stOLLevel = oldlevel + 1}+ items <- mapM listItemToLaTeX lst+ modify (\s -> s {stOLLevel = oldlevel})+ let tostyle x = case numstyle of+ Decimal -> "\\arabic" <> braces x+ UpperRoman -> "\\Roman" <> braces x+ LowerRoman -> "\\roman" <> braces x+ UpperAlpha -> "\\Alph" <> braces x+ LowerAlpha -> "\\alph" <> braces x+ Example -> "\\arabic" <> braces x+ DefaultStyle -> "\\arabic" <> braces x+ let todelim x = case numdelim of+ OneParen -> x <> ")"+ TwoParens -> parens x+ Period -> x <> "."+ _ -> x <> "."+ let enum = text $ "enum" ++ map toLower (toRomanNumeral oldlevel)+ let stylecommand = if numstyle == DefaultStyle && numdelim == DefaultDelim+ then empty+ else "\\def" <> "\\label" <> enum <>+ braces (todelim $ tostyle enum)+ let resetcounter = if start == 1 || oldlevel > 4+ then empty+ else "\\setcounter" <> braces enum <>+ braces (text $ show $ start - 1)+ let spacing = if isTightList lst+ then text "\\itemsep1pt\\parskip0pt\\parsep0pt"+ else empty+ return $ text ("\\begin{enumerate}" ++ inc)+ $$ stylecommand+ $$ resetcounter+ $$ spacing+ $$ vcat items+ $$ "\\end{enumerate}"+blockToLaTeX (DefinitionList []) = return empty+blockToLaTeX (DefinitionList lst) = do+ incremental <- gets stIncremental+ let inc = if incremental then "[<+->]" else ""+ items <- mapM defListItemToLaTeX lst+ let spacing = if all isTightList (map snd lst)+ then text "\\itemsep1pt\\parskip0pt\\parsep0pt"+ else empty+ return $ text ("\\begin{description}" ++ inc) $$ spacing $$ vcat items $$+ "\\end{description}"+blockToLaTeX HorizontalRule = return $+ "\\begin{center}\\rule{0.5\\linewidth}{\\linethickness}\\end{center}"+blockToLaTeX (Header level (id',classes,_) lst) = do+ modify $ \s -> s{stInHeading = True}+ hdr <- sectionHeader ("unnumbered" `elem` classes) id' level lst+ modify $ \s -> s{stInHeading = False}+ return hdr+blockToLaTeX (Table caption aligns widths heads rows) = do+ headers <- if all null heads+ then return empty+ else ($$ "\\midrule\n") `fmap`+ (tableRowToLaTeX True aligns widths) heads+ let endhead = if all null heads+ then empty+ else text "\\endhead"+ captionText <- inlineListToLaTeX caption+ let capt = if isEmpty captionText+ then empty+ else text "\\caption" <> braces captionText+ <> "\\tabularnewline\n\\toprule\n"+ <> headers+ <> "\\endfirsthead"+ rows' <- mapM (tableRowToLaTeX False aligns widths) rows+ let colDescriptors = text $ concat $ map toColDescriptor aligns+ modify $ \s -> s{ stTable = True }+ return $ "\\begin{longtable}[c]" <>+ braces ("@{}" <> colDescriptors <> "@{}")+ -- the @{} removes extra space at beginning and end+ $$ capt+ $$ "\\toprule"+ $$ headers+ $$ endhead+ $$ vcat rows'+ $$ "\\bottomrule"+ $$ "\\end{longtable}"+blockToLaTeX (Figure figType attr content pc txt) =+ figureToLaTeXfloat figType attr content pc txt+blockToLaTeX (ImageGrid _) = return empty+blockToLaTeX (Statement _ _) = return empty+blockToLaTeX (Proof _ _) = return empty++toColDescriptor :: Alignment -> String+toColDescriptor align =+ case align of+ AlignLeft -> "l"+ AlignRight -> "r"+ AlignCenter -> "c"+ AlignDefault -> "l"++blockListToLaTeX :: [Block] -> State WriterState Doc+blockListToLaTeX lst = vsep `fmap` mapM blockToLaTeX lst++tableRowToLaTeX :: Bool+ -> [Alignment]+ -> [Double]+ -> [[Block]]+ -> State WriterState Doc+tableRowToLaTeX header aligns widths cols = do+ -- scale factor compensates for extra space between columns+ -- so the whole table isn't larger than columnwidth+ let scaleFactor = 0.97 ** fromIntegral (length aligns)+ let widths' = map (scaleFactor *) widths+ cells <- mapM (tableCellToLaTeX header) $ zip3 widths' aligns cols+ return $ hsep (intersperse "&" cells) <> "\\tabularnewline"++-- For simple latex tables (without minipages or parboxes),+-- we need to go to some lengths to get line breaks working:+-- as LineBreak bs = \vtop{\hbox{\strut as}\hbox{\strut bs}}.+fixLineBreaks :: Block -> Block+fixLineBreaks (Para ils) = Para $ fixLineBreaks' ils+fixLineBreaks (Plain ils) = Plain $ fixLineBreaks' ils+fixLineBreaks x = x++fixLineBreaks' :: [Inline] -> [Inline]+fixLineBreaks' ils = case splitBy (== LineBreak) ils of+ [] -> []+ [xs] -> xs+ chunks -> RawInline "tex" "\\vtop{" :+ concatMap tohbox chunks +++ [RawInline "tex" "}"]+ where tohbox ys = RawInline "tex" "\\hbox{\\strut " : ys +++ [RawInline "tex" "}"]++tableCellToLaTeX :: Bool -> (Double, Alignment, [Block])+ -> State WriterState Doc+tableCellToLaTeX _ (0, _, blocks) =+ blockListToLaTeX $ walk fixLineBreaks blocks+tableCellToLaTeX header (width, align, blocks) = do+ modify $ \st -> st{ stInMinipage = True, stNotes = [] }+ cellContents <- blockListToLaTeX blocks+ notes <- gets stNotes+ modify $ \st -> st{ stInMinipage = False, stNotes = [] }+ let valign = text $ if header then "[b]" else "[t]"+ let halign = case align of+ AlignLeft -> "\\raggedright"+ AlignRight -> "\\raggedleft"+ AlignCenter -> "\\centering"+ AlignDefault -> "\\raggedright"+ return $ ("\\begin{minipage}" <> valign <>+ braces (text (printf "%.2f\\hsize" width)) <>+ (halign <> "\\strut" <> cr <> cellContents <> cr) <>+ "\\strut\\end{minipage}")+ $$ case notes of+ [] -> empty+ ns -> (case length ns of+ n | n > 1 -> "\\addtocounter" <>+ braces "footnote" <>+ braces (text $ show $ 1 - n)+ | otherwise -> empty)+ $$+ vcat (intersperse+ ("\\addtocounter" <> braces "footnote" <> braces "1")+ $ map (\x -> "\\footnotetext" <> braces x)+ $ reverse ns)++listItemToLaTeX :: [Block] -> State WriterState Doc+listItemToLaTeX lst+ -- we need to put some text before a header if it's the first+ -- element in an item. This will look ugly in LaTeX regardless, but+ -- this will keep the typesetter from throwing an error.+ | ((Header _ _ _) :_) <- lst =+ blockListToLaTeX lst >>= return . (text "\\item ~" $$) . (nest 2)+ | otherwise = blockListToLaTeX lst >>= return . (text "\\item" $$) .+ (nest 2)++defListItemToLaTeX :: ([Inline], [[Block]]) -> State WriterState Doc+defListItemToLaTeX (term, defs) = do+ term' <- inlineListToLaTeX term+ -- put braces around term if it contains an internal link,+ -- since otherwise we get bad bracket interactions: \item[\hyperref[..]+ let isInternalLink (Link _ ('#':_,_)) = True+ isInternalLink _ = False+ let term'' = if any isInternalLink term+ then braces term'+ else term'+ def' <- liftM vsep $ mapM blockListToLaTeX defs+ return $ case defs of+ (((Header _ _ _) : _) : _) ->+ "\\item" <> brackets term'' <> " ~ " $$ def'+ _ ->+ "\\item" <> brackets term'' $$ def'++-- | Craft the section header, inserting the secton reference, if supplied.+sectionHeader :: Bool -- True for unnumbered+ -> [Char]+ -> Int+ -> [Inline]+ -> State WriterState Doc+sectionHeader unnumbered ref level lst = do+ txt <- inlineListToLaTeX lst+ lab <- text `fmap` toLabel ref+ let noNote (Note _) = Str ""+ noNote x = x+ let lstNoNotes = walk noNote lst+ txtNoNotes <- inlineListToLaTeX lstNoNotes+ let star = if unnumbered then text "*" else empty+ -- footnotes in sections don't work (except for starred variants)+ -- unless you specify an optional argument:+ -- \section[mysec]{mysec\footnote{blah}}+ optional <- if unnumbered || lstNoNotes == lst+ then return empty+ else do+ return $ brackets txtNoNotes+ let stuffing = star <> optional <> braces txt+ book <- gets stBook+ opts <- gets stOptions+ let level' = if book || writerChapters opts then level - 1 else level+ internalLinks <- gets stInternalLinks+ let refLabel x = (if ref `elem` internalLinks+ then text "\\hyperdef"+ <> braces empty+ <> braces lab+ <> braces x+ else x)+ let headerWith x y = refLabel $ text x <> y <>+ if null ref+ then empty+ else text "\\label" <> braces lab+ let sectionType = case level' of+ 0 | writerBeamer opts -> "part"+ | otherwise -> "chapter"+ 1 -> "section"+ 2 -> "subsection"+ 3 -> "subsubsection"+ 4 -> "paragraph"+ 5 -> "subparagraph"+ _ -> ""+ inQuote <- gets stInQuote+ let prefix = if inQuote && level' >= 4+ then text "\\mbox{}%"+ -- needed for \paragraph, \subparagraph in quote environment+ -- see http://tex.stackexchange.com/questions/169830/+ else empty+ return $ if level' > 5+ then txt+ else prefix $$+ headerWith ('\\':sectionType) stuffing+ $$ if unnumbered+ then "\\addcontentsline{toc}" <>+ braces (text sectionType) <>+ braces txtNoNotes+ else empty++-- | Convert list of inline elements to LaTeX.+inlineListToLaTeX :: [Inline] -- ^ Inlines to convert+ -> State WriterState Doc+inlineListToLaTeX lst =+ mapM inlineToLaTeX (prependNbsp $ fixLineInitialSpaces lst)+ >>= return . hcat+ -- ## fixLineInitialSpaces+ -- nonbreaking spaces (~) in LaTeX don't work after line breaks,+ -- so we turn nbsps after hard breaks to \hspace commands.+ -- this is mostly used in verse.+ -- ## prependNbsp+ -- usually numbered cross-references should be prepended with+ -- a nonbreaking space, so we do that, except when a bunch of+ -- them appears in a comma-separated list+ where fixLineInitialSpaces [] = []+ fixLineInitialSpaces (LineBreak : Str s@('\160':_) : xs) =+ LineBreak : fixNbsps s ++ fixLineInitialSpaces xs+ fixLineInitialSpaces (x:xs) = x : fixLineInitialSpaces xs+ fixNbsps s = let (ys,zs) = span (=='\160') s+ in replicate (length ys) hspace ++ [Str zs]+ hspace = RawInline "latex" "\\hspace*{0.333em}"+ prependNbsp [] = []+ prependNbsp (Str "," : Space : NumRef a as : xs) =+ Str "," : Space : NumRef a as : prependNbsp xs+ prependNbsp (Str a : Space : NumRef b bs : xs) =+ Str (a ++ "\160") : NumRef b bs : prependNbsp xs+ prependNbsp (x:xs) = x : prependNbsp xs++isQuoted :: Inline -> Bool+isQuoted (Quoted _ _) = True+isQuoted _ = False++-- | Convert inline element to LaTeX+inlineToLaTeX :: Inline -- ^ Inline to convert+ -> State WriterState Doc+inlineToLaTeX (Span (id',classes,_) ils) = do+ let noEmph = "csl-no-emph" `elem` classes+ let noStrong = "csl-no-strong" `elem` classes+ let noSmallCaps = "csl-no-smallcaps" `elem` classes+ ref <- toLabel id'+ let linkAnchor = if null id'+ then empty+ else "\\hyperdef{}" <> braces (text ref) <> "{}"+ fmap (linkAnchor <>)+ ((if noEmph then inCmd "textup" else id) .+ (if noStrong then inCmd "textnormal" else id) .+ (if noSmallCaps then inCmd "textnormal" else id) .+ (if not (noEmph || noStrong || noSmallCaps)+ then braces+ else id)) `fmap` inlineListToLaTeX ils+inlineToLaTeX (Emph lst) =+ inlineListToLaTeX lst >>= return . inCmd "emph"+inlineToLaTeX (Strong lst) =+ inlineListToLaTeX lst >>= return . inCmd "textbf"+inlineToLaTeX (Strikeout lst) = do+ -- we need to protect VERB in an mbox or we get an error+ -- see #1294+ contents <- inlineListToLaTeX $ protectCode lst+ modify $ \s -> s{ stStrikeout = True }+ return $ inCmd "sout" contents+inlineToLaTeX (Superscript lst) =+ inlineListToLaTeX lst >>= return . inCmd "textsuperscript"+inlineToLaTeX (Subscript lst) = do+ inlineListToLaTeX lst >>= return . inCmd "textsubscript"+inlineToLaTeX (SmallCaps lst) =+ inlineListToLaTeX lst >>= return . inCmd "textsc"+inlineToLaTeX (Cite cits lst) = do+ st <- get+ let opts = stOptions st+ case writerCiteMethod opts of+ Natbib -> citationsToNatbib cits+ Biblatex -> citationsToBiblatex cits+ _ -> inlineListToLaTeX lst+inlineToLaTeX (NumRef numref _raw) = do+ let refId = numRefId numref+ case numRefStyle numref of+ PlainNumRef -> return $ text $ "\\ref{" ++ refId ++ "}"+ ParenthesesNumRef -> return $ text $ "\\eqref{" ++ refId ++ "}"+inlineToLaTeX (Code (_,classes,_) str) = do+ opts <- gets stOptions+ case () of+ _ | writerListings opts -> listingsCode+ | writerHighlight opts && not (null classes) -> highlightCode+ | otherwise -> rawCode+ where listingsCode = do+ inNote <- gets stInNote+ when inNote $ modify $ \s -> s{ stVerbInNote = True }+ let chr = case "!\"&'()*,-./:;?@_" \\ str of+ (c:_) -> c+ [] -> '!'+ return $ text $ "\\lstinline" ++ [chr] ++ str ++ [chr]+ highlightCode = do+ case highlight formatLaTeXInline ("",classes,[]) str of+ Nothing -> rawCode+ Just h -> modify (\st -> st{ stHighlighting = True }) >>+ return (text h)+ rawCode = liftM (text . (\s -> "\\texttt{" ++ s ++ "}"))+ $ stringToLaTeX CodeString str+inlineToLaTeX (Quoted qt lst) = do+ contents <- inlineListToLaTeX lst+ csquotes <- liftM stCsquotes get+ opts <- gets stOptions+ if csquotes+ then return $ "\\enquote" <> braces contents+ else do+ let s1 = if (not (null lst)) && (isQuoted (head lst))+ then "\\,"+ else empty+ let s2 = if (not (null lst)) && (isQuoted (last lst))+ then "\\,"+ else empty+ let inner = s1 <> contents <> s2+ return $ case qt of+ DoubleQuote ->+ if writerTeXLigatures opts+ then text "``" <> inner <> text "''"+ else char '\x201C' <> inner <> char '\x201D'+ SingleQuote ->+ if writerTeXLigatures opts+ then char '`' <> inner <> char '\''+ else char '\x2018' <> inner <> char '\x2019'+inlineToLaTeX (Str str) = liftM text $ stringToLaTeX TextString str+inlineToLaTeX (Math InlineMath str) =+ return $ char '$' <> text str <> char '$'+inlineToLaTeX (Math (DisplayMath attr) str) =+ return $ cr <> char '%' <> cr+ <> text (dispMathToLaTeX attr str)+ <> cr <> char '%' <> cr+inlineToLaTeX (RawInline f str)+ | f == Format "latex" || f == Format "tex"+ = return $ text str+ | otherwise = return empty+inlineToLaTeX (LineBreak) = return "\\\\"+inlineToLaTeX Space = return space+inlineToLaTeX (Link txt ('#':ident, _)) = do+ contents <- inlineListToLaTeX txt+ lab <- toLabel ident+ return $ text "\\hyperref" <> brackets (text lab) <> braces contents+inlineToLaTeX (Link txt (src, _)) =+ case txt of+ [Str x] | escapeURI x == src -> -- autolink+ do modify $ \s -> s{ stUrl = True }+ src' <- stringToLaTeX URLString src+ return $ text $ "\\url{" ++ src' ++ "}"+ [Str x] | Just rest <- stripPrefix "mailto:" src,+ escapeURI x == rest -> -- email autolink+ do modify $ \s -> s{ stUrl = True }+ src' <- stringToLaTeX URLString src+ contents <- inlineListToLaTeX txt+ return $ "\\href" <> braces (text src') <>+ braces ("\\nolinkurl" <> braces contents)+ _ -> do contents <- inlineListToLaTeX txt+ src' <- stringToLaTeX URLString src+ return $ text ("\\href{" ++ src' ++ "}{") <>+ contents <> char '}'+inlineToLaTeX (Image attr _ (source, _)) = do+ modify $ \s -> s{ stGraphics = True }+ source' <- handleImageSrc source+ inHeading <- gets stInHeading+ return $ imageWithAttrToLatex "\\textwidth" attr source' inHeading+inlineToLaTeX (Note contents) = do+ inMinipage <- gets stInMinipage+ modify (\s -> s{stInNote = True})+ contents' <- blockListToLaTeX contents+ modify (\s -> s {stInNote = False})+ let optnl = case reverse contents of+ (CodeBlock _ _ : _) -> cr+ _ -> empty+ let noteContents = nest 2 contents' <> optnl+ opts <- gets stOptions+ -- in beamer slides, display footnote from current overlay forward+ let beamerMark = if writerBeamer opts+ then text "<.->"+ else empty+ modify $ \st -> st{ stNotes = noteContents : stNotes st }+ return $+ if inMinipage+ then "\\footnotemark{}"+ -- note: a \n before } needed when note ends with a Verbatim environment+ else "\\footnote" <> beamerMark <> braces noteContents++protectCode :: [Inline] -> [Inline]+protectCode [] = []+protectCode (x@(Code ("",[],[]) _) : xs) = x : protectCode xs+protectCode (x@(Code _ _) : xs) = ltx "\\mbox{" : x : ltx "}" : xs+ where ltx = RawInline (Format "latex")+protectCode (x : xs) = x : protectCode xs++citationsToNatbib :: [Citation] -> State WriterState Doc+citationsToNatbib (one:[])+ = citeCommand c p s k+ where+ Citation { citationId = k+ , citationPrefix = p+ , citationSuffix = s+ , citationMode = m+ }+ = one+ c = case m of+ AuthorInText -> "citet"+ SuppressAuthor -> "citeyearpar"+ NormalCitation -> "citep"++citationsToNatbib cits+ | noPrefix (tail cits) && noSuffix (init cits) && ismode NormalCitation cits+ = citeCommand "citep" p s ks+ where+ noPrefix = all (null . citationPrefix)+ noSuffix = all (null . citationSuffix)+ ismode m = all (((==) m) . citationMode)+ p = citationPrefix $ head $ cits+ s = citationSuffix $ last $ cits+ ks = intercalate ", " $ map citationId cits++citationsToNatbib (c:cs) | citationMode c == AuthorInText = do+ author <- citeCommand "citeauthor" [] [] (citationId c)+ cits <- citationsToNatbib (c { citationMode = SuppressAuthor } : cs)+ return $ author <+> cits++citationsToNatbib cits = do+ cits' <- mapM convertOne cits+ return $ text "\\citetext{" <> foldl combineTwo empty cits' <> text "}"+ where+ combineTwo a b | isEmpty a = b+ | otherwise = a <> text "; " <> b+ convertOne Citation { citationId = k+ , citationPrefix = p+ , citationSuffix = s+ , citationMode = m+ }+ = case m of+ AuthorInText -> citeCommand "citealt" p s k+ SuppressAuthor -> citeCommand "citeyear" p s k+ NormalCitation -> citeCommand "citealp" p s k++citeCommand :: String -> [Inline] -> [Inline] -> String -> State WriterState Doc+citeCommand c p s k = do+ args <- citeArguments p s k+ return $ text ("\\" ++ c) <> args++citeArguments :: [Inline] -> [Inline] -> String -> State WriterState Doc+citeArguments p s k = do+ let s' = case s of+ (Str (x:[]) : r) | isPunctuation x -> dropWhile (== Space) r+ (Str (x:xs) : r) | isPunctuation x -> Str xs : r+ _ -> s+ pdoc <- inlineListToLaTeX p+ sdoc <- inlineListToLaTeX s'+ let optargs = case (isEmpty pdoc, isEmpty sdoc) of+ (True, True ) -> empty+ (True, False) -> brackets sdoc+ (_ , _ ) -> brackets pdoc <> brackets sdoc+ return $ optargs <> braces (text k)++citationsToBiblatex :: [Citation] -> State WriterState Doc+citationsToBiblatex (one:[])+ = citeCommand cmd p s k+ where+ Citation { citationId = k+ , citationPrefix = p+ , citationSuffix = s+ , citationMode = m+ } = one+ cmd = case m of+ SuppressAuthor -> "autocite*"+ AuthorInText -> "textcite"+ NormalCitation -> "autocite"++citationsToBiblatex (c:cs) = do+ args <- mapM convertOne (c:cs)+ return $ text cmd <> foldl (<>) empty args+ where+ cmd = case citationMode c of+ AuthorInText -> "\\textcites"+ _ -> "\\autocites"+ convertOne Citation { citationId = k+ , citationPrefix = p+ , citationSuffix = s+ }+ = citeArguments p s k++citationsToBiblatex _ = return empty++-- Determine listings language from list of class attributes.+getListingsLanguage :: [String] -> Maybe String+getListingsLanguage [] = Nothing+getListingsLanguage (x:xs) = toListingsLanguage x <|> getListingsLanguage xs++--+-- ScholarlyMarkdown floating figures+--++-- Handles all float types+figureToLaTeXfloat :: FigureType -> Attr -> [Block] -> PreparedContent -> [Inline]+ -> State WriterState Doc+figureToLaTeXfloat ImageFigure = imageGridToLaTeX+figureToLaTeXfloat TableFigure = tableFloatToLaTeX+figureToLaTeXfloat LineBlockFigure = algorithmToLaTeX+figureToLaTeXfloat ListingFigure = codeFloatToLaTeX++-- Handles writing image figure floats+imageGridToLaTeX :: Attr -> [Block] -> PreparedContent -> [Inline] -> State WriterState Doc+imageGridToLaTeX attr imageGrid _fallback caption = do+ modify $ \s -> s{ stFloats = True }+ modify $ \s -> s{ stGraphics = True }+ let ident = getIdentifier attr+ let (subfigRows, snglImg) = case (head imageGrid) of+ -- get rid of any subcaption and label for single image+ ImageGrid [[Image a _ c]]+ -> ([[Image (setIdentifier "" a) [] c]], True)+ ImageGrid ig -> (ig, False)+ _ -> ([[]], True) -- should never happen+ when (not snglImg) $ modify $ \s -> s{ stSubfigs = True }+ let subfigIds = case (safeRead $ fromMaybe [] $ lookupKey "subfigIds" attr) :: Maybe [String] of+ Just a -> a+ Nothing -> [""]+ -- show subfig labels (a), (b), etc+ let showSubfigLabel = any (not . null) subfigIds && not (hasClass "nonumber" attr)+ let subfiglist = intercalate [LineBreak] subfigRows+ let myNumLabel = fromMaybe "0" $ lookupKey "numLabel" attr+ let addCaptPrefix = myNumLabel /= "0" -- infers that num. label is not needed+ -- this requires the "caption" package which is provided by "subfig"+ let capstar = if (not addCaptPrefix) then text "*" else empty+ let widestar = if hasClass "wide" attr then text "*" else empty+ let fullWidth = "\\hsize"+ capt <- if null caption+ then return empty+ else (\c -> "\\caption" <> capstar <> braces c) `fmap` inlineListToLaTeX caption+ let capt' = if null caption && not addCaptPrefix then empty else capt+ img <- mapM (subfigsToLaTeX fullWidth snglImg) subfiglist+ let label = if (not $ null ident) then ("\\label" <> braces (text ident)) else empty+ let disableSubfigLabel = if showSubfigLabel || snglImg+ then empty+ else "\\captionsetup" <> brackets (text "subfigure")+ <> braces (text "labelformat=empty")+ return $ "\\begin{figure" <> widestar <> "}" $$ "\\centering" $$ disableSubfigLabel+ $$ foldl ($$) empty img $$ capt' <> label $$ "\\end{figure" <> widestar <> "}"++-- Handles writing figure subfloats (using the subfig package)+-- (requires "fullWidth" argument, which is a command that defines 100% width+-- of container, such as @\\textwidth@)+subfigsToLaTeX :: String -> Bool -> Inline -> State WriterState Doc+subfigsToLaTeX _ _ LineBreak = inlineToLaTeX LineBreak+subfigsToLaTeX fullWidth singleImage (Image attr txt (src,_)) = do+ let ident = getIdentifier attr+ capt <- if null txt+ then return empty+ else inlineListToLaTeX txt+ let label = if (not $ null ident) then ("\\label" <> braces (text ident)) else empty+ src' <- handleImageSrc src+ attr' <- setWidthFromHistory attr+ let img = imageWithAttrToLatex fullWidth attr' src' False+ return $ if singleImage+ then img <> label+ else "\\subfloat" <> brackets (capt <> label) <> braces img+subfigsToLaTeX _ _ _ = return empty++handleImageSrc :: String -> State WriterState String+handleImageSrc source =+ let source' = if isURI source+ then source+ else unEscapeString source+ in stringToLaTeX URLString source'++setWidthFromHistory :: Attr -> State WriterState Attr+setWidthFromHistory attr = do+ let attrWidth = fromMaybe "" $ lookupKey "width" attr+ st <- get+ let lastWidth = fromMaybe "" $ stLastWidth st+ let replaceWidth = attrWidth == "same" || attrWidth == "^"+ let currWidth = if replaceWidth+ then lastWidth+ else attrWidth+ when (not $ null currWidth) $ put st { stLastWidth = Just currWidth }+ return $ insertReplaceKeyVal ("width",currWidth) attr++-- Extracts dimension attributes and include in the @includegraphics@ directive+-- (requires "fullWidth" argument, which is a command that defines 100% width+-- of container, such as @\\textwidth@)+imageWithAttrToLatex :: String -> Attr -> String -> Bool -> Doc+imageWithAttrToLatex fullWidth attr src needProtect =+ let keyval' = M.fromList $ getKeyVals attr+ width = case M.lookup "width" keyval' of+ Just len -> filterLength fullWidth len+ Nothing -> case M.lookup "max-width" keyval' of+ Just len -> filterLength fullWidth len+ Nothing -> ""+ hight = case M.lookup "height" keyval' of+ Just len -> filterLength fullWidth len+ Nothing -> case M.lookup "max-height" keyval' of+ Just len -> filterLength fullWidth len+ Nothing -> ""+ width' = if (null width) then "" else ("width=" ++ width)+ hight' = if (null hight) then "" else ("height=" ++ hight)+ keepAspectRatio = if (not (null width) && not (null hight))+ then "keepaspectratio=true"+ else ""+ graphicxAttr = intercalate ","+ [ x | x <- [width', hight', keepAspectRatio], not $ null x]+ graphicsCmd = if needProtect then "\\protect\\includegraphics" else "\\includegraphics"+ in graphicsCmd <> brackets (text graphicxAttr) <> braces (text src)++-- Ensures that dimension is understandable by LaTeX,+-- mostly converts unit of percentage @%@ to measure of relative width.+-- If unit not recognized, then returns empty string.+-- (required "fullWidth" argument, which is a command that defines 100% width+-- of container, such as @\\textwidth@)+filterLength :: String -> String -> String+filterLength fullWidth len =+ case reads len :: [(Float, String)] of+ (val,"%"):_ -> (printf "%.3f" (val/100)) ++ fullWidth+ (val,unit):_ | unit `elem` validLaTeXUnits ->+ (printf "%.3f" val) ++ unit+ _ -> ""+++validLaTeXUnits :: [String]+validLaTeXUnits = ["mm","cm","in","pt","em","ex","%"]++-- Handles writing algorithm/pseudocode floats+algorithmToLaTeX :: Attr -> [Block] -> PreparedContent -> [Inline] -> State WriterState Doc+algorithmToLaTeX attr alg _fallback caption = do+ modify $ \s -> s{ stAlgorithms = True, stFloats = True }+ let ident = getIdentifier attr+ let myNumLabel = fromMaybe "0" $ lookupKey "numLabel" attr+ let addCaptPrefix = myNumLabel /= "0" -- infers that num. label is not needed+ -- this requires the "caption" package which is provided by "subfig"+ let capstar = if (not addCaptPrefix) then text "*" else empty+ let widestar = if hasClass "wide" attr then text "*" else empty+ capt <- if null caption+ then return empty+ else (\c -> "\\caption" <> capstar <> braces c) `fmap` inlineListToLaTeX caption+ let capt' = if null caption && not addCaptPrefix then empty else capt+ algorithm <- blockListToLaTeX alg+ let label = if (not $ null ident) then ("\\label" <> braces (text ident)) else empty+ return $ "\\begin{scholmdAlgorithm" <> widestar <> "}" $$ algorithm+ $$ capt' <> label $$ "\\end{scholmdAlgorithm" <> widestar <> "}"++-- Handles writing algorithm/pseudocode floats+tableFloatToLaTeX :: Attr -> [Block] -> PreparedContent -> [Inline] -> State WriterState Doc+tableFloatToLaTeX attr tabl _fallback caption = do+ modify $ \s -> s{ stTable = True, stFloats = True }+ let ident = getIdentifier attr+ let myNumLabel = fromMaybe "0" $ lookupKey "numLabel" attr+ let addCaptPrefix = myNumLabel /= "0" -- infers that num. label is not needed+ -- this requires the "caption" package which is provided by "subfig"+ let capstar = if (not addCaptPrefix) then text "*" else empty+ let widestar = if hasClass "wide" attr then text "*" else empty+ capt <- if null caption+ then return empty+ else (\c -> "\\caption" <> capstar <> braces c) `fmap` inlineListToLaTeX caption+ let capt' = if null caption && not addCaptPrefix then empty else capt+ table <- mapM tableToTabular tabl+ let label = if (not $ null ident) then ("\\label" <> braces (text ident)) else empty+ return $ "\\begin{table" <> widestar <> "}" $$ "\\centering" $$ foldl ($$) empty table+ $$ capt' <> label $$ "\\end{table" <> widestar <> "}"++-- Specifically for table floats+tableToTabular :: Block -> State WriterState Doc+tableToTabular (Table _caption aligns widths heads rows) = do+ headers <- if all null heads+ then return empty+ else ($$ "\\midrule") `fmap`+ (tableRowToLaTeX True aligns widths) heads+ rows' <- mapM (tableRowToLaTeX False aligns widths) rows+ let colDescriptors = text $ concat $ map toColDescriptor aligns+ return $ "\\begin{tabular}" <>+ braces (colDescriptors)+ $$ "\\toprule\\addlinespace"+ $$ headers+ $$ vcat rows'+ $$ "\\bottomrule"+ $$ "\\end{tabular}"+tableToTabular _ = return empty++-- Handles writing code-block/listing floats+-- (Scholarly automatically uses Listings for floating block)+codeFloatToLaTeX :: Attr -> [Block] -> PreparedContent -> [Inline] -> State WriterState Doc+codeFloatToLaTeX attr codeblock _fallback caption = do+ modify $ \s -> s{ stFloats = True }+ let myNumLabel = fromMaybe "0" $ lookupKey "numLabel" attr+ let addCaptPrefix = myNumLabel /= "0" -- infers that num. label is not needed+ let codeblock' = dropWhile notCodeBlock codeblock+ codeToListingsFloat (head codeblock') attr caption addCaptPrefix++notCodeBlock :: Block -> Bool+notCodeBlock (CodeBlock _ _) = False+notCodeBlock _ = True++codeToListingsFloat :: Block -> Attr -> [Inline] -> Bool -> State WriterState Doc+codeToListingsFloat (CodeBlock (_,classes,keyvalAttr) str) attrib caption captPref = do+ ident <- toLabel $ getIdentifier attrib+ let params = (case getListingsLanguage classes of+ Just l -> [ "language=" ++ l ]+ Nothing -> []) +++ [ "numbers=left" | "numberLines" `elem` classes+ || "number" `elem` classes+ || "number-lines" `elem` classes ] +++ [ (if key == "startFrom"+ then "firstnumber"+ else key) ++ "=" ++ attr |+ (key,attr) <- keyvalAttr ] +++ (if ident == ""+ then []+ else [ "label=" ++ ident ]) +++ (if not captPref+ then [ "nolol=true" ]+ else []) +++ (if not (hasClass "wide" attrib)+ then [ "float=htbp" ]+ else [ "float=*htbp" ] )+ capt <- if null caption+ then return empty+ else (\c -> "caption=" <> braces c) `fmap` inlineListToLaTeX caption+ let printParams+ | null params = empty+ | otherwise = brackets $ hcat (intersperse ", " $ capt:(map text params) )+ return $ flush ("\\begin{lstlisting}" <> printParams $$ text str $$+ "\\end{lstlisting}") $$ cr+codeToListingsFloat _ _ _ _ = return empty
@@ -0,0 +1,370 @@+{-+Copyright (C) 2007-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.Man+ Copyright : Copyright (C) 2007-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to groff man page format.++-}+module Text.Pandoc.Writers.Man ( writeMan) where+import Text.Pandoc.Definition+import Text.Pandoc.Templates+import Text.Pandoc.Shared+import Text.Pandoc.Writers.Shared+import Text.Pandoc.Options+import Text.Pandoc.Readers.TeXMath+import Text.Printf ( printf )+import Data.List ( stripPrefix, intersperse, intercalate )+import Data.Maybe (fromMaybe)+import Text.Pandoc.Pretty+import Text.Pandoc.Builder (deleteMeta)+import Control.Monad.State+import Data.Char ( isDigit )++type Notes = [[Block]]+data WriterState = WriterState { stNotes :: Notes+ , stHasTables :: Bool }++-- | Convert Pandoc to Man.+writeMan :: WriterOptions -> Pandoc -> String+writeMan opts document = evalState (pandocToMan opts document) (WriterState [] False)++-- | Return groff man representation of document.+pandocToMan :: WriterOptions -> Pandoc -> State WriterState String+pandocToMan opts (Pandoc meta blocks) = do+ let colwidth = if writerWrapText opts+ then Just $ writerColumns opts+ else Nothing+ let render' = render colwidth+ titleText <- inlineListToMan opts $ docTitle meta+ let title' = render' titleText+ let setFieldsFromTitle =+ case break (== ' ') title' of+ (cmdName, rest) -> case reverse cmdName of+ (')':d:'(':xs) | isDigit d ->+ defField "title" (reverse xs) .+ defField "section" [d] .+ case splitBy (=='|') rest of+ (ft:hds) ->+ defField "footer" (trim ft) .+ defField "header"+ (trim $ concat hds)+ [] -> id+ _ -> defField "title" title'+ metadata <- metaToJSON opts+ (fmap (render colwidth) . blockListToMan opts)+ (fmap (render colwidth) . inlineListToMan opts)+ $ deleteMeta "title" meta+ body <- blockListToMan opts blocks+ notes <- liftM stNotes get+ notes' <- notesToMan opts (reverse notes)+ let main = render' $ body $$ notes' $$ text ""+ hasTables <- liftM stHasTables get+ let context = defField "body" main+ $ setFieldsFromTitle+ $ defField "has-tables" hasTables+ $ metadata+ if writerStandalone opts+ then return $ renderTemplate' (writerTemplate opts) context+ else return main++-- | Return man representation of notes.+notesToMan :: WriterOptions -> [[Block]] -> State WriterState Doc+notesToMan opts notes =+ if null notes+ then return empty+ else mapM (\(num, note) -> noteToMan opts num note) (zip [1..] notes) >>=+ return . (text ".SH NOTES" $$) . vcat++-- | Return man representation of a note.+noteToMan :: WriterOptions -> Int -> [Block] -> State WriterState Doc+noteToMan opts num note = do+ contents <- blockListToMan opts note+ let marker = cr <> text ".SS " <> brackets (text (show num))+ return $ marker $$ contents++-- | Association list of characters to escape.+manEscapes :: [(Char, String)]+manEscapes = [ ('\160', "\\ ")+ , ('\'', "\\[aq]")+ , ('’', "'")+ , ('\x2014', "\\[em]")+ , ('\x2013', "\\[en]")+ , ('\x2026', "\\&...")+ ] ++ backslashEscapes "-@\\"++-- | Escape special characters for Man.+escapeString :: String -> String+escapeString = escapeStringUsing manEscapes++-- | Escape a literal (code) section for Man.+escapeCode :: String -> String+escapeCode = concat . intersperse "\n" . map escapeLine . lines where+ escapeLine codeline =+ case escapeStringUsing (manEscapes ++ backslashEscapes "\t ") codeline of+ a@('.':_) -> "\\&" ++ a+ b -> b++-- We split inline lists into sentences, and print one sentence per+-- line. groff/troff treats the line-ending period differently.+-- See http://code.google.com/p/pandoc/issues/detail?id=148.++-- | Returns the first sentence in a list of inlines, and the rest.+breakSentence :: [Inline] -> ([Inline], [Inline])+breakSentence [] = ([],[])+breakSentence xs =+ let isSentenceEndInline (Str ys@(_:_)) | last ys == '.' = True+ isSentenceEndInline (Str ys@(_:_)) | last ys == '?' = True+ isSentenceEndInline (LineBreak) = True+ isSentenceEndInline _ = False+ (as, bs) = break isSentenceEndInline xs+ in case bs of+ [] -> (as, [])+ [c] -> (as ++ [c], [])+ (c:Space:cs) -> (as ++ [c], cs)+ (Str ".":Str (')':ys):cs) -> (as ++ [Str ".", Str (')':ys)], cs)+ (x@(Str ('.':')':_)):cs) -> (as ++ [x], cs)+ (LineBreak:x@(Str ('.':_)):cs) -> (as ++[LineBreak], x:cs)+ (c:cs) -> (as ++ [c] ++ ds, es)+ where (ds, es) = breakSentence cs++-- | Split a list of inlines into sentences.+splitSentences :: [Inline] -> [[Inline]]+splitSentences xs =+ let (sent, rest) = breakSentence xs+ in if null rest then [sent] else sent : splitSentences rest++-- | Convert Pandoc block element to man.+blockToMan :: WriterOptions -- ^ Options+ -> Block -- ^ Block element+ -> State WriterState Doc+blockToMan _ Null = return empty+blockToMan opts (Div _ bs) = blockListToMan opts bs+blockToMan opts (Plain inlines) =+ liftM vcat $ mapM (inlineListToMan opts) $ splitSentences inlines+blockToMan opts (Para inlines) = do+ contents <- liftM vcat $ mapM (inlineListToMan opts) $+ splitSentences inlines+ return $ text ".PP" $$ contents+blockToMan _ (RawBlock f str)+ | f == Format "man" = return $ text str+ | otherwise = return empty+blockToMan _ HorizontalRule = return $ text ".PP" $$ text " * * * * *"+blockToMan opts (Header level _ inlines) = do+ contents <- inlineListToMan opts inlines+ let heading = case level of+ 1 -> ".SH "+ _ -> ".SS "+ return $ text heading <> contents+blockToMan _ (CodeBlock _ str) = return $+ text ".IP" $$+ text ".nf" $$+ text "\\f[C]" $$+ text (escapeCode str) $$+ text "\\f[]" $$+ text ".fi"+blockToMan opts (BlockQuote blocks) = do+ contents <- blockListToMan opts blocks+ return $ text ".RS" $$ contents $$ text ".RE"+blockToMan opts (Table caption alignments widths headers rows) =+ let aligncode AlignLeft = "l"+ aligncode AlignRight = "r"+ aligncode AlignCenter = "c"+ aligncode AlignDefault = "l"+ in do+ caption' <- inlineListToMan opts caption+ modify $ \st -> st{ stHasTables = True }+ let iwidths = if all (== 0) widths+ then repeat ""+ else map (printf "w(%0.1fn)" . (70 *)) widths+ -- 78n default width - 8n indent = 70n+ let coldescriptions = text $ intercalate " "+ (zipWith (\align width -> aligncode align ++ width)+ alignments iwidths) ++ "."+ colheadings <- mapM (blockListToMan opts) headers+ let makeRow cols = text "T{" $$+ (vcat $ intersperse (text "T}@T{") cols) $$+ text "T}"+ let colheadings' = if all null headers+ then empty+ else makeRow colheadings $$ char '_'+ body <- mapM (\row -> do+ cols <- mapM (blockListToMan opts) row+ return $ makeRow cols) rows+ return $ text ".PP" $$ caption' $$+ text ".TS" $$ text "tab(@);" $$ coldescriptions $$+ colheadings' $$ vcat body $$ text ".TE"++blockToMan opts (BulletList items) = do+ contents <- mapM (bulletListItemToMan opts) items+ return (vcat contents)+blockToMan opts (OrderedList attribs items) = do+ let markers = take (length items) $ orderedListMarkers attribs+ let indent = 1 + (maximum $ map length markers)+ contents <- mapM (\(num, item) -> orderedListItemToMan opts num indent item) $+ zip markers items+ return (vcat contents)+blockToMan opts (DefinitionList items) = do+ contents <- mapM (definitionListItemToMan opts) items+ return (vcat contents)+blockToMan _ (Figure _ _ _ _ _) = return empty+blockToMan _ (ImageGrid _) = return empty+blockToMan _ (Statement _ _) = return empty+blockToMan _ (Proof _ _) = return empty++-- | Convert bullet list item (list of blocks) to man.+bulletListItemToMan :: WriterOptions -> [Block] -> State WriterState Doc+bulletListItemToMan _ [] = return empty+bulletListItemToMan opts ((Para first):rest) =+ bulletListItemToMan opts ((Plain first):rest)+bulletListItemToMan opts ((Plain first):rest) = do+ first' <- blockToMan opts (Plain first)+ rest' <- blockListToMan opts rest+ let first'' = text ".IP \\[bu] 2" $$ first'+ let rest'' = if null rest+ then empty+ else text ".RS 2" $$ rest' $$ text ".RE"+ return (first'' $$ rest'')+bulletListItemToMan opts (first:rest) = do+ first' <- blockToMan opts first+ rest' <- blockListToMan opts rest+ return $ text "\\[bu] .RS 2" $$ first' $$ rest' $$ text ".RE"++-- | Convert ordered list item (a list of blocks) to man.+orderedListItemToMan :: WriterOptions -- ^ options+ -> String -- ^ order marker for list item+ -> Int -- ^ number of spaces to indent+ -> [Block] -- ^ list item (list of blocks)+ -> State WriterState Doc+orderedListItemToMan _ _ _ [] = return empty+orderedListItemToMan opts num indent ((Para first):rest) =+ orderedListItemToMan opts num indent ((Plain first):rest)+orderedListItemToMan opts num indent (first:rest) = do+ first' <- blockToMan opts first+ rest' <- blockListToMan opts rest+ let num' = printf ("%" ++ show (indent - 1) ++ "s") num+ let first'' = text (".IP \"" ++ num' ++ "\" " ++ show indent) $$ first'+ let rest'' = if null rest+ then empty+ else text ".RS 4" $$ rest' $$ text ".RE"+ return $ first'' $$ rest''++-- | Convert definition list item (label, list of blocks) to man.+definitionListItemToMan :: WriterOptions+ -> ([Inline],[[Block]])+ -> State WriterState Doc+definitionListItemToMan opts (label, defs) = do+ labelText <- inlineListToMan opts label+ contents <- if null defs+ then return empty+ else liftM vcat $ forM defs $ \blocks -> do+ let (first, rest) = case blocks of+ ((Para x):y) -> (Plain x,y)+ (x:y) -> (x,y)+ [] -> error "blocks is null"+ rest' <- liftM vcat $+ mapM (\item -> blockToMan opts item) rest+ first' <- blockToMan opts first+ return $ first' $$ text ".RS" $$ rest' $$ text ".RE"+ return $ text ".TP" $$ nowrap (text ".B " <> labelText) $$ contents++-- | Convert list of Pandoc block elements to man.+blockListToMan :: WriterOptions -- ^ Options+ -> [Block] -- ^ List of block elements+ -> State WriterState Doc+blockListToMan opts blocks =+ mapM (blockToMan opts) blocks >>= (return . vcat)++-- | Convert list of Pandoc inline elements to man.+inlineListToMan :: WriterOptions -> [Inline] -> State WriterState Doc+-- if list starts with ., insert a zero-width character \& so it+-- won't be interpreted as markup if it falls at the beginning of a line.+inlineListToMan opts lst@(Str ('.':_) : _) = mapM (inlineToMan opts) lst >>=+ (return . (text "\\&" <>) . hcat)+inlineListToMan opts lst = mapM (inlineToMan opts) lst >>= (return . hcat)++-- | Convert Pandoc inline element to man.+inlineToMan :: WriterOptions -> Inline -> State WriterState Doc+inlineToMan opts (Span _ ils) = inlineListToMan opts ils+inlineToMan opts (Emph lst) = do+ contents <- inlineListToMan opts lst+ return $ text "\\f[I]" <> contents <> text "\\f[]"+inlineToMan opts (Strong lst) = do+ contents <- inlineListToMan opts lst+ return $ text "\\f[B]" <> contents <> text "\\f[]"+inlineToMan opts (Strikeout lst) = do+ contents <- inlineListToMan opts lst+ return $ text "[STRIKEOUT:" <> contents <> char ']'+inlineToMan opts (Superscript lst) = do+ contents <- inlineListToMan opts lst+ return $ char '^' <> contents <> char '^'+inlineToMan opts (Subscript lst) = do+ contents <- inlineListToMan opts lst+ return $ char '~' <> contents <> char '~'+inlineToMan opts (SmallCaps lst) = inlineListToMan opts lst -- not supported+inlineToMan opts (Quoted SingleQuote lst) = do+ contents <- inlineListToMan opts lst+ return $ char '`' <> contents <> char '\''+inlineToMan opts (Quoted DoubleQuote lst) = do+ contents <- inlineListToMan opts lst+ return $ text "\\[lq]" <> contents <> text "\\[rq]"+inlineToMan opts (Cite _ lst) =+ inlineListToMan opts lst+inlineToMan _ (Code _ str) =+ return $ text $ "\\f[C]" ++ escapeCode str ++ "\\f[]"+inlineToMan _ (Str str) = return $ text $ escapeString str+inlineToMan opts (Math InlineMath str) =+ inlineListToMan opts $ texMathToInlines InlineMath str+inlineToMan opts (Math (DisplayMath a) str) = do+ contents <- inlineListToMan opts $ texMathToInlines (DisplayMath a) str+ return $ cr <> text ".RS" $$ contents $$ text ".RE"+inlineToMan _ (RawInline f str)+ | f == Format "man" = return $ text str+ | otherwise = return empty+inlineToMan _ (LineBreak) = return $+ cr <> text ".PD 0" $$ text ".P" $$ text ".PD" <> cr+inlineToMan _ Space = return space+inlineToMan opts (Link txt (src, _)) = do+ linktext <- inlineListToMan opts txt+ let srcSuffix = fromMaybe src (stripPrefix "mailto:" src)+ return $ case txt of+ [Str s]+ | escapeURI s == srcSuffix ->+ char '<' <> text srcSuffix <> char '>'+ _ -> linktext <> text " (" <> text src <> char ')'+inlineToMan opts (Image _ alternate (source, tit)) = do+ let txt = if (null alternate) || (alternate == [Str ""]) ||+ (alternate == [Str source]) -- to prevent autolinks+ then [Str "image"]+ else alternate+ linkPart <- inlineToMan opts (Link txt (source, tit))+ return $ char '[' <> text "IMAGE: " <> linkPart <> char ']'+inlineToMan _ (Note contents) = do+ -- add to notes in state+ modify $ \st -> st{ stNotes = contents : stNotes st }+ notes <- liftM stNotes get+ let ref = show $ (length notes)+ return $ char '[' <> text ref <> char ']'+inlineToMan _ (NumRef _ _) = return empty
@@ -0,0 +1,887 @@+{-# LANGUAGE OverloadedStrings, TupleSections, ScopedTypeVariables #-}+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.Markdown+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to markdown-formatted plain text.++Markdown: <http://daringfireball.net/projects/markdown/>+-}+module Text.Pandoc.Writers.Markdown (writeMarkdown, writePlain) where+import Text.Pandoc.Definition+import Text.Pandoc.Walk+import Text.Pandoc.Templates (renderTemplate')+import Text.Pandoc.Shared+import Text.Pandoc.Writers.Shared+import Text.Pandoc.Options+import Text.Pandoc.Parsing hiding (blankline, blanklines, char, space)+import Data.Maybe (fromMaybe)+import Data.List ( group, stripPrefix, find, intersperse, transpose, sortBy )+import Data.Char ( isSpace, isPunctuation )+import Data.Ord ( comparing )+import Text.Pandoc.Pretty+import Control.Monad.State+import qualified Data.Set as Set+import Text.Pandoc.Writers.HTML (writeHtmlString)+import Text.Pandoc.Readers.TeXMath (texMathToInlines)+import Text.HTML.TagSoup (parseTags, isTagText, Tag(..))+import Network.URI (isURI)+import Data.Default+import Data.Yaml (Value(Object,String,Array,Bool,Number))+import qualified Data.HashMap.Strict as H+import qualified Data.Vector as V+import qualified Data.Text as T++type Notes = [[Block]]+type Refs = [([Inline], Target)]+data WriterState = WriterState { stNotes :: Notes+ , stRefs :: Refs+ , stIds :: [String]+ , stPlain :: Bool }+instance Default WriterState+ where def = WriterState{ stNotes = [], stRefs = [], stIds = [], stPlain = False }++-- | Convert Pandoc to Markdown.+writeMarkdown :: WriterOptions -> Pandoc -> String+writeMarkdown opts document =+ evalState (pandocToMarkdown opts{+ writerWrapText = writerWrapText opts &&+ not (isEnabled Ext_hard_line_breaks opts) }+ document) def++-- | Convert Pandoc to plain text (like markdown, but without links,+-- pictures, or inline formatting).+writePlain :: WriterOptions -> Pandoc -> String+writePlain opts document =+ evalState (pandocToMarkdown opts{+ writerExtensions = Set.delete Ext_escaped_line_breaks $+ Set.delete Ext_pipe_tables $+ Set.delete Ext_raw_html $+ Set.delete Ext_markdown_in_html_blocks $+ Set.delete Ext_raw_tex $+ Set.delete Ext_footnotes $+ Set.delete Ext_tex_math_dollars $+ Set.delete Ext_citations $+ writerExtensions opts }+ document) def{ stPlain = True }++pandocTitleBlock :: Doc -> [Doc] -> Doc -> Doc+pandocTitleBlock tit auths dat =+ hang 2 (text "% ") tit <> cr <>+ hang 2 (text "% ") (vcat $ map nowrap auths) <> cr <>+ hang 2 (text "% ") dat <> cr++mmdTitleBlock :: Value -> Doc+mmdTitleBlock (Object hashmap) =+ vcat $ map go $ sortBy (comparing fst) $ H.toList hashmap+ where go (k,v) =+ case (text (T.unpack k), v) of+ (k', Array vec)+ | V.null vec -> empty+ | otherwise -> k' <> ":" <> space <>+ hcat (intersperse "; "+ (map fromstr $ V.toList vec))+ (_, String "") -> empty+ (k', x) -> k' <> ":" <> space <> nest 2 (fromstr x)+ fromstr (String s) = text (removeBlankLines $ T.unpack s)+ fromstr (Bool b) = text (show b)+ fromstr (Number n) = text (show n)+ fromstr _ = empty+ -- blank lines not allowed in MMD metadata - we replace with .+ removeBlankLines = trimr . unlines . map (\x ->+ if all isSpace x then "." else x) . lines+mmdTitleBlock _ = empty++plainTitleBlock :: Doc -> [Doc] -> Doc -> Doc+plainTitleBlock tit auths dat =+ tit <> cr <>+ (hcat (intersperse (text "; ") auths)) <> cr <>+ dat <> cr++yamlMetadataBlock :: Value -> Doc+yamlMetadataBlock v = "---" $$ (jsonToYaml v) $$ "..."++jsonToYaml :: Value -> Doc+jsonToYaml (Object hashmap) =+ vcat $ map (\(k,v) ->+ case (text (T.unpack k), v, jsonToYaml v) of+ (k', Array vec, x)+ | V.null vec -> empty+ | otherwise -> (k' <> ":") $$ x+ (k', Object _, x) -> (k' <> ":") $$ nest 2 x+ (_, String "", _) -> empty+ (k', _, x) -> k' <> ":" <> space <> hang 2 "" x)+ $ sortBy (comparing fst) $ H.toList hashmap+jsonToYaml (Array vec) =+ vcat $ map (\v -> hang 2 "- " (jsonToYaml v)) $ V.toList vec+jsonToYaml (String "") = empty+jsonToYaml (String s) =+ case T.unpack s of+ x | '\n' `elem` x -> hang 2 ("|" <> cr) $ text x+ | not (any isPunctuation x) -> text x+ | otherwise -> text $ "'" ++ substitute "'" "''" x ++ "'"+jsonToYaml (Bool b) = text $ show b+jsonToYaml (Number n) = text $ show n+jsonToYaml _ = empty++-- | Return markdown representation of document.+pandocToMarkdown :: WriterOptions -> Pandoc -> State WriterState String+pandocToMarkdown opts (Pandoc meta blocks) = do+ let colwidth = if writerWrapText opts+ then Just $ writerColumns opts+ else Nothing+ isPlain <- gets stPlain+ metadata <- metaToJSON opts+ (fmap (render colwidth) . blockListToMarkdown opts)+ (fmap (render colwidth) . inlineListToMarkdown opts)+ meta+ let title' = maybe empty text $ getField "title" metadata+ let authors' = maybe [] (map text) $ getField "author" metadata+ let date' = maybe empty text $ getField "date" metadata+ let titleblock = case writerStandalone opts of+ True | isPlain ->+ plainTitleBlock title' authors' date'+ | isEnabled Ext_yaml_metadata_block opts ->+ yamlMetadataBlock metadata+ | isEnabled Ext_pandoc_title_block opts ->+ pandocTitleBlock title' authors' date'+ | isEnabled Ext_mmd_title_block opts ->+ mmdTitleBlock metadata+ | otherwise -> empty+ False -> empty+ let headerBlocks = filter isHeaderBlock blocks+ let toc = if writerTableOfContents opts+ then tableOfContents opts headerBlocks+ else empty+ -- Strip off final 'references' header if markdown citations enabled+ let blocks' = if isEnabled Ext_citations opts+ then case reverse blocks of+ (Div (_,["references"],_) _):xs -> reverse xs+ _ -> blocks+ else blocks+ body <- blockListToMarkdown opts blocks'+ st <- get+ notes' <- notesToMarkdown opts (reverse $ stNotes st)+ st' <- get -- note that the notes may contain refs+ refs' <- refsToMarkdown opts (reverse $ stRefs st')+ let render' :: Doc -> String+ render' = render colwidth+ let main = render' $ body <>+ (if isEmpty notes' then empty else blankline <> notes') <>+ (if isEmpty refs' then empty else blankline <> refs')+ let context = defField "toc" (render' toc)+ $ defField "body" main+ $ (if isNullMeta meta+ then id+ else defField "titleblock" (render' titleblock))+ $ metadata+ if writerStandalone opts+ then return $ renderTemplate' (writerTemplate opts) context+ else return main++-- | Return markdown representation of reference key table.+refsToMarkdown :: WriterOptions -> Refs -> State WriterState Doc+refsToMarkdown opts refs = mapM (keyToMarkdown opts) refs >>= return . vcat++-- | Return markdown representation of a reference key.+keyToMarkdown :: WriterOptions+ -> ([Inline], (String, String))+ -> State WriterState Doc+keyToMarkdown opts (label, (src, tit)) = do+ label' <- inlineListToMarkdown opts label+ let tit' = if null tit+ then empty+ else space <> "\"" <> text tit <> "\""+ return $ nest 2 $ hang 2+ ("[" <> label' <> "]:" <> space) (text src <> tit')++-- | Return markdown representation of notes.+notesToMarkdown :: WriterOptions -> [[Block]] -> State WriterState Doc+notesToMarkdown opts notes =+ mapM (\(num, note) -> noteToMarkdown opts num note) (zip [1..] notes) >>=+ return . vsep++-- | Return markdown representation of a note.+noteToMarkdown :: WriterOptions -> Int -> [Block] -> State WriterState Doc+noteToMarkdown opts num blocks = do+ contents <- blockListToMarkdown opts blocks+ let num' = text $ writerIdentifierPrefix opts ++ show num+ let marker = if isEnabled Ext_footnotes opts+ then text "[^" <> num' <> text "]:"+ else text "[" <> num' <> text "]"+ let markerSize = 4 + offset num'+ let spacer = case writerTabStop opts - markerSize of+ n | n > 0 -> text $ replicate n ' '+ _ -> text " "+ return $ if isEnabled Ext_footnotes opts+ then hang (writerTabStop opts) (marker <> spacer) contents+ else marker <> spacer <> contents++-- | Escape special characters for Markdown.+escapeString :: WriterOptions -> String -> String+escapeString opts = escapeStringUsing markdownEscapes+ where markdownEscapes = backslashEscapes specialChars+ specialChars =+ (if isEnabled Ext_superscript opts+ then ('^':)+ else id) .+ (if isEnabled Ext_subscript opts+ then ('~':)+ else id) .+ (if isEnabled Ext_tex_math_dollars opts+ then ('$':)+ else id) $+ "\\`*_<>#"++-- | Construct table of contents from list of header blocks.+tableOfContents :: WriterOptions -> [Block] -> Doc+tableOfContents opts headers =+ let opts' = opts { writerIgnoreNotes = True }+ contents = BulletList $ map (elementToListItem opts) $ hierarchicalize headers+ in evalState (blockToMarkdown opts' contents) def++-- | Converts an Element to a list item for a table of contents,+elementToListItem :: WriterOptions -> Element -> [Block]+elementToListItem opts (Sec lev _ _ headerText subsecs)+ = Plain headerText :+ [ BulletList (map (elementToListItem opts) subsecs) |+ not (null subsecs) && lev < writerTOCDepth opts ]+elementToListItem _ (Blk _) = []++attrsToMarkdown :: Attr -> Doc+attrsToMarkdown attribs = braces $ hsep [attribId, attribClasses, attribKeys]+ where attribId = case attribs of+ ([],_,_) -> empty+ (i,_,_) -> "#" <> text i+ attribClasses = case attribs of+ (_,[],_) -> empty+ (_,cs,_) -> hsep $+ map (text . ('.':))+ cs+ attribKeys = case attribs of+ (_,_,[]) -> empty+ (_,_,ks) -> hsep $+ map (\(k,v) -> text k+ <> "=\"" <> text v <> "\"") ks++-- | Ordered list start parser for use in Para below.+olMarker :: Parser [Char] ParserState Char+olMarker = do (start, style', delim) <- anyOrderedListMarker+ if delim == Period &&+ (style' == UpperAlpha || (style' == UpperRoman &&+ start `elem` [1, 5, 10, 50, 100, 500, 1000]))+ then spaceChar >> spaceChar+ else spaceChar++-- | True if string begins with an ordered list marker+beginsWithOrderedListMarker :: String -> Bool+beginsWithOrderedListMarker str =+ case runParser olMarker defaultParserState "para start" (take 10 str) of+ Left _ -> False+ Right _ -> True++-- | Convert Pandoc block element to markdown.+blockToMarkdown :: WriterOptions -- ^ Options+ -> Block -- ^ Block element+ -> State WriterState Doc+blockToMarkdown _ Null = return empty+blockToMarkdown opts (Div attrs ils) = do+ contents <- blockListToMarkdown opts ils+ return $ if isEnabled Ext_raw_html opts &&+ isEnabled Ext_markdown_in_html_blocks opts+ then tagWithAttrs "div" attrs <> blankline <>+ contents <> blankline <> "</div>" <> blankline+ else contents <> blankline+blockToMarkdown opts (Plain inlines) = do+ contents <- inlineListToMarkdown opts inlines+ -- escape if para starts with ordered list marker+ st <- get+ let colwidth = if writerWrapText opts+ then Just $ writerColumns opts+ else Nothing+ let rendered = render colwidth contents+ let escapeDelimiter (x:xs) | x `elem` ".()" = '\\':x:xs+ | otherwise = x : escapeDelimiter xs+ escapeDelimiter [] = []+ let contents' = if isEnabled Ext_all_symbols_escapable opts &&+ not (stPlain st) && beginsWithOrderedListMarker rendered+ then text $ escapeDelimiter rendered+ else contents+ return $ contents' <> cr+-- title beginning with fig: indicates figure+blockToMarkdown opts (Para [Image attr alt (src,'f':'i':'g':':':tit)]) =+ blockToMarkdown opts (Para [Image attr alt (src,tit)])+blockToMarkdown opts (Para inlines) =+ (<> blankline) `fmap` blockToMarkdown opts (Plain inlines)+blockToMarkdown opts (RawBlock f str)+ | f == "html" = do+ plain <- gets stPlain+ return $ if plain+ then empty+ else if isEnabled Ext_markdown_attribute opts+ then text (addMarkdownAttribute str) <> text "\n"+ else text str <> text "\n"+ | f `elem` ["latex", "tex", "markdown"] = do+ plain <- gets stPlain+ return $ if plain+ then empty+ else text str <> text "\n"+blockToMarkdown _ (RawBlock _ _) = return empty+blockToMarkdown opts HorizontalRule = do+ return $ blankline <> text (replicate (writerColumns opts) '-') <> blankline+blockToMarkdown opts (Header level attr inlines) = do+ plain <- gets stPlain+ -- we calculate the id that would be used by auto_identifiers+ -- so we know whether to print an explicit identifier+ ids <- gets stIds+ let autoId = uniqueIdent inlines ids+ modify $ \st -> st{ stIds = autoId : ids }+ let attr' = case attr of+ ("",[],[]) -> empty+ (id',[],[]) | isEnabled Ext_auto_identifiers opts+ && id' == autoId -> empty+ (id',_,_) | isEnabled Ext_mmd_header_identifiers opts ->+ space <> brackets (text id')+ _ | isEnabled Ext_header_attributes opts ->+ space <> attrsToMarkdown attr+ | otherwise -> empty+ contents <- inlineListToMarkdown opts $+ if level == 1 && plain+ then capitalize inlines+ else inlines+ let setext = writerSetextHeaders opts+ return $ nowrap+ $ case level of+ 1 | plain -> blanklines 3 <> contents <> blanklines 2+ | setext ->+ contents <> attr' <> cr <> text (replicate (offset contents) '=') <>+ blankline+ 2 | plain -> blanklines 2 <> contents <> blankline+ | setext ->+ contents <> attr' <> cr <> text (replicate (offset contents) '-') <>+ blankline+ -- ghc interprets '#' characters in column 1 as linenum specifiers.+ _ | plain || isEnabled Ext_literate_haskell opts ->+ contents <> blankline+ _ -> text (replicate level '#') <> space <> contents <> attr' <> blankline+blockToMarkdown opts (CodeBlock (_,classes,_) str)+ | "haskell" `elem` classes && "literate" `elem` classes &&+ isEnabled Ext_literate_haskell opts =+ return $ prefixed "> " (text str) <> blankline+blockToMarkdown opts (CodeBlock attribs str) = return $+ case attribs == nullAttr of+ False | isEnabled Ext_backtick_code_blocks opts ->+ backticks <> attrs <> cr <> text str <> cr <> backticks <> blankline+ | isEnabled Ext_fenced_code_blocks opts ->+ tildes <> attrs <> cr <> text str <> cr <> tildes <> blankline+ _ -> nest (writerTabStop opts) (text str) <> blankline+ where tildes = text $ case [ln | ln <- lines str, all (=='~') ln] of+ [] -> "~~~~"+ xs -> case maximum $ map length xs of+ n | n < 3 -> "~~~~"+ | otherwise -> replicate (n+1) '~'+ backticks = text $ case [ln | ln <- lines str, all (=='`') ln] of+ [] -> "```"+ xs -> case maximum $ map length xs of+ n | n < 3 -> "```"+ | otherwise -> replicate (n+1) '`'+ attrs = if isEnabled Ext_fenced_code_attributes opts+ then nowrap $ " " <> attrsToMarkdown attribs+ else case attribs of+ (_,(cls:_),_) -> " " <> text cls+ _ -> empty+blockToMarkdown opts (BlockQuote blocks) = do+ plain <- gets stPlain+ -- if we're writing literate haskell, put a space before the bird tracks+ -- so they won't be interpreted as lhs...+ let leader = if isEnabled Ext_literate_haskell opts+ then " > "+ else if plain then " " else "> "+ contents <- blockListToMarkdown opts blocks+ return $ (prefixed leader contents) <> blankline+blockToMarkdown opts t@(Table caption aligns widths headers rows) = do+ caption' <- inlineListToMarkdown opts caption+ let caption'' = if null caption || not (isEnabled Ext_table_captions opts)+ then empty+ else blankline <> ": " <> caption' <> blankline+ rawHeaders <- mapM (blockListToMarkdown opts) headers+ rawRows <- mapM (mapM (blockListToMarkdown opts)) rows+ let isSimple = all (==0) widths+ let isPlainBlock (Plain _) = True+ isPlainBlock _ = False+ let hasBlocks = not (all isPlainBlock $ concat . concat $ headers:rows)+ (nst,tbl) <- case True of+ _ | isSimple &&+ isEnabled Ext_simple_tables opts -> fmap (nest 2,) $+ pandocTable opts (all null headers) aligns widths+ rawHeaders rawRows+ | isSimple &&+ isEnabled Ext_pipe_tables opts -> fmap (id,) $+ pipeTable (all null headers) aligns rawHeaders rawRows+ | not hasBlocks &&+ isEnabled Ext_multiline_tables opts -> fmap (nest 2,) $+ pandocTable opts (all null headers) aligns widths+ rawHeaders rawRows+ | isEnabled Ext_grid_tables opts -> fmap (id,) $+ gridTable opts (all null headers) aligns widths+ rawHeaders rawRows+ | otherwise -> fmap (id,) $+ return $ text $ writeHtmlString def+ $ Pandoc nullMeta [t]+ return $ nst $ tbl $$ blankline $$ caption'' $$ blankline+blockToMarkdown opts (BulletList items) = do+ contents <- mapM (bulletListItemToMarkdown opts) items+ return $ cat contents <> blankline+blockToMarkdown opts (OrderedList (start,sty,delim) items) = do+ let start' = if isEnabled Ext_startnum opts then start else 1+ let sty' = if isEnabled Ext_fancy_lists opts then sty else DefaultStyle+ let delim' = if isEnabled Ext_fancy_lists opts then delim else DefaultDelim+ let attribs = (start', sty', delim')+ let markers = orderedListMarkers attribs+ let markers' = map (\m -> if length m < 3+ then m ++ replicate (3 - length m) ' '+ else m) markers+ contents <- mapM (\(item, num) -> orderedListItemToMarkdown opts item num) $+ zip markers' items+ return $ cat contents <> blankline+blockToMarkdown opts (DefinitionList items) = do+ contents <- mapM (definitionListItemToMarkdown opts) items+ return $ cat contents <> blankline+blockToMarkdown _ (Figure _ _ _ _ _) = return empty+blockToMarkdown _ (ImageGrid _) = return empty+blockToMarkdown _ (Statement _ _) = return empty+blockToMarkdown _ (Proof _ _) = return empty+++addMarkdownAttribute :: String -> String+addMarkdownAttribute s =+ case span isTagText $ reverse $ parseTags s of+ (xs,(TagOpen t attrs:rest)) ->+ renderTags' $ reverse rest ++ (TagOpen t attrs' : reverse xs)+ where attrs' = ("markdown","1"):[(x,y) | (x,y) <- attrs,+ x /= "markdown"]+ _ -> s++pipeTable :: Bool -> [Alignment] -> [Doc] -> [[Doc]] -> State WriterState Doc+pipeTable headless aligns rawHeaders rawRows = do+ let sp = text " "+ let blockFor AlignLeft x y = lblock (x + 2) (sp <> y) <> lblock 0 empty+ blockFor AlignCenter x y = cblock (x + 2) (sp <> y) <> lblock 0 empty+ blockFor AlignRight x y = rblock (x + 2) (sp <> y) <> lblock 0 empty+ blockFor _ x y = lblock (x + 2) (sp <> y) <> lblock 0 empty+ let widths = map (max 3 . maximum . map offset) $ transpose (rawHeaders : rawRows)+ let torow cs = nowrap $ text "|" <>+ hcat (intersperse (text "|") $+ zipWith3 blockFor aligns widths (map chomp cs))+ <> text "|"+ let toborder (a, w) = text $ case a of+ AlignLeft -> ':':replicate (w + 1) '-'+ AlignCenter -> ':':replicate w '-' ++ ":"+ AlignRight -> replicate (w + 1) '-' ++ ":"+ AlignDefault -> replicate (w + 2) '-'+ let header = if headless then empty else torow rawHeaders+ let border = nowrap $ text "|" <> hcat (intersperse (text "|") $+ map toborder $ zip aligns widths) <> text "|"+ let body = vcat $ map torow rawRows+ return $ header $$ border $$ body++pandocTable :: WriterOptions -> Bool -> [Alignment] -> [Double]+ -> [Doc] -> [[Doc]] -> State WriterState Doc+pandocTable opts headless aligns widths rawHeaders rawRows = do+ let isSimple = all (==0) widths+ let alignHeader alignment = case alignment of+ AlignLeft -> lblock+ AlignCenter -> cblock+ AlignRight -> rblock+ AlignDefault -> lblock+ let numChars = maximum . map offset+ let widthsInChars = if isSimple+ then map ((+2) . numChars)+ $ transpose (rawHeaders : rawRows)+ else map+ (floor . (fromIntegral (writerColumns opts) *))+ widths+ let makeRow = hcat . intersperse (lblock 1 (text " ")) .+ (zipWith3 alignHeader aligns widthsInChars)+ let rows' = map makeRow rawRows+ let head' = makeRow rawHeaders+ let maxRowHeight = maximum $ map height (head':rows')+ let underline = cat $ intersperse (text " ") $+ map (\width -> text (replicate width '-')) widthsInChars+ let border = if maxRowHeight > 1+ then text (replicate (sum widthsInChars ++ length widthsInChars - 1) '-')+ else if headless+ then underline+ else empty+ let head'' = if headless+ then empty+ else border <> cr <> head'+ let body = if maxRowHeight > 1+ then vsep rows'+ else vcat rows'+ let bottom = if headless+ then underline+ else border+ return $ head'' $$ underline $$ body $$ bottom++gridTable :: WriterOptions -> Bool -> [Alignment] -> [Double]+ -> [Doc] -> [[Doc]] -> State WriterState Doc+gridTable opts headless _aligns widths headers' rawRows = do+ let numcols = length headers'+ let widths' = if all (==0) widths+ then replicate numcols (1.0 / fromIntegral numcols)+ else widths+ let widthsInChars = map (floor . (fromIntegral (writerColumns opts) *)) widths'+ let hpipeBlocks blocks = hcat [beg, middle, end]+ where h = maximum (map height blocks)+ sep' = lblock 3 $ vcat (map text $ replicate h " | ")+ beg = lblock 2 $ vcat (map text $ replicate h "| ")+ end = lblock 2 $ vcat (map text $ replicate h " |")+ middle = chomp $ hcat $ intersperse sep' blocks+ let makeRow = hpipeBlocks . zipWith lblock widthsInChars+ let head' = makeRow headers'+ let rows' = map (makeRow . map chomp) rawRows+ let border ch = char '+' <> char ch <>+ (hcat $ intersperse (char ch <> char '+' <> char ch) $+ map (\l -> text $ replicate l ch) widthsInChars) <>+ char ch <> char '+'+ let body = vcat $ intersperse (border '-') rows'+ let head'' = if headless+ then empty+ else head' $$ border '='+ return $ border '-' $$ head'' $$ body $$ border '-'++-- | Convert bullet list item (list of blocks) to markdown.+bulletListItemToMarkdown :: WriterOptions -> [Block] -> State WriterState Doc+bulletListItemToMarkdown opts items = do+ contents <- blockListToMarkdown opts items+ let sps = replicate (writerTabStop opts - 2) ' '+ let start = text ('-' : ' ' : sps)+ -- remove trailing blank line if it is a tight list+ let contents' = case reverse items of+ (BulletList xs:_) | isTightList xs ->+ chomp contents <> cr+ (OrderedList _ xs:_) | isTightList xs ->+ chomp contents <> cr+ _ -> contents+ return $ hang (writerTabStop opts) start $ contents' <> cr++-- | Convert ordered list item (a list of blocks) to markdown.+orderedListItemToMarkdown :: WriterOptions -- ^ options+ -> String -- ^ list item marker+ -> [Block] -- ^ list item (list of blocks)+ -> State WriterState Doc+orderedListItemToMarkdown opts marker items = do+ contents <- blockListToMarkdown opts items+ let sps = case length marker - writerTabStop opts of+ n | n > 0 -> text $ replicate n ' '+ _ -> text " "+ let start = text marker <> sps+ return $ hang (writerTabStop opts) start $ contents <> cr++-- | Convert definition list item (label, list of blocks) to markdown.+definitionListItemToMarkdown :: WriterOptions+ -> ([Inline],[[Block]])+ -> State WriterState Doc+definitionListItemToMarkdown opts (label, defs) = do+ labelText <- inlineListToMarkdown opts label+ defs' <- mapM (mapM (blockToMarkdown opts)) defs+ if isEnabled Ext_definition_lists opts+ then do+ let tabStop = writerTabStop opts+ st <- get+ let leader = if stPlain st then " " else ": "+ let sps = case writerTabStop opts - 3 of+ n | n > 0 -> text $ replicate n ' '+ _ -> text " "+ if isEnabled Ext_compact_definition_lists opts+ then do+ let contents = vcat $ map (\d -> hang tabStop (leader <> sps)+ $ vcat d <> cr) defs'+ return $ nowrap labelText <> cr <> contents <> cr+ else do+ let contents = vcat $ map (\d -> hang tabStop (leader <> sps)+ $ vcat d <> cr) defs'+ let isTight = case defs of+ ((Plain _ : _): _) -> True+ _ -> False+ return $ blankline <> nowrap labelText <>+ (if isTight then cr else blankline) <> contents <> blankline+ else do+ return $ nowrap labelText <> text " " <> cr <>+ vsep (map vsep defs') <> blankline++-- | Convert list of Pandoc block elements to markdown.+blockListToMarkdown :: WriterOptions -- ^ Options+ -> [Block] -- ^ List of block elements+ -> State WriterState Doc+blockListToMarkdown opts blocks =+ mapM (blockToMarkdown opts) (fixBlocks blocks) >>= return . cat+ -- insert comment between list and indented code block, or the+ -- code block will be treated as a list continuation paragraph+ where fixBlocks (b : CodeBlock attr x : rest)+ | (not (isEnabled Ext_fenced_code_blocks opts) || attr == nullAttr)+ && isListBlock b = b : commentSep : CodeBlock attr x :+ fixBlocks rest+ fixBlocks (b1@(BulletList _) : b2@(BulletList _) : bs) =+ b1 : commentSep : fixBlocks (b2:bs)+ fixBlocks (b1@(OrderedList _ _) : b2@(OrderedList _ _) : bs) =+ b1 : commentSep : fixBlocks (b2:bs)+ fixBlocks (b1@(DefinitionList _) : b2@(DefinitionList _) : bs) =+ b1 : commentSep : fixBlocks (b2:bs)+ fixBlocks (x : xs) = x : fixBlocks xs+ fixBlocks [] = []+ isListBlock (BulletList _) = True+ isListBlock (OrderedList _ _) = True+ isListBlock (DefinitionList _) = True+ isListBlock _ = False+ commentSep = RawBlock "html" "<!-- -->\n"++-- | Get reference for target; if none exists, create unique one and return.+-- Prefer label if possible; otherwise, generate a unique key.+getReference :: [Inline] -> Target -> State WriterState [Inline]+getReference label (src, tit) = do+ st <- get+ case find ((== (src, tit)) . snd) (stRefs st) of+ Just (ref, _) -> return ref+ Nothing -> do+ let label' = case find ((== label) . fst) (stRefs st) of+ Just _ -> -- label is used; generate numerical label+ case find (\n -> notElem [Str (show n)]+ (map fst (stRefs st)))+ [1..(10000 :: Integer)] of+ Just x -> [Str (show x)]+ Nothing -> error "no unique label"+ Nothing -> label+ modify (\s -> s{ stRefs = (label', (src,tit)) : stRefs st })+ return label'++-- | Convert list of Pandoc inline elements to markdown.+inlineListToMarkdown :: WriterOptions -> [Inline] -> State WriterState Doc+inlineListToMarkdown opts lst =+ mapM (inlineToMarkdown opts) (avoidBadWraps lst) >>= return . cat+ where avoidBadWraps [] = []+ avoidBadWraps (Space:Str (c:cs):xs)+ | c `elem` "-*+>" = Str (' ':c:cs) : avoidBadWraps xs+ avoidBadWraps (x:xs) = x : avoidBadWraps xs++escapeSpaces :: Inline -> Inline+escapeSpaces (Str s) = Str $ substitute " " "\\ " s+escapeSpaces Space = Str "\\ "+escapeSpaces x = x++-- | Convert Pandoc inline element to markdown.+inlineToMarkdown :: WriterOptions -> Inline -> State WriterState Doc+inlineToMarkdown opts (Span attrs ils) = do+ contents <- inlineListToMarkdown opts ils+ return $ if isEnabled Ext_raw_html opts+ then tagWithAttrs "span" attrs <> contents <> text "</span>"+ else contents+inlineToMarkdown opts (Emph lst) = do+ plain <- gets stPlain+ contents <- inlineListToMarkdown opts lst+ return $ if plain+ then "_" <> contents <> "_"+ else "*" <> contents <> "*"+inlineToMarkdown opts (Strong lst) = do+ plain <- gets stPlain+ if plain+ then inlineListToMarkdown opts $ capitalize lst+ else do+ contents <- inlineListToMarkdown opts lst+ return $ "**" <> contents <> "**"+inlineToMarkdown opts (Strikeout lst) = do+ contents <- inlineListToMarkdown opts lst+ return $ if isEnabled Ext_strikeout opts+ then "~~" <> contents <> "~~"+ else "<s>" <> contents <> "</s>"+inlineToMarkdown opts (Superscript lst) = do+ contents <- inlineListToMarkdown opts $ walk escapeSpaces lst+ return $ if isEnabled Ext_superscript opts+ then "^" <> contents <> "^"+ else "<sup>" <> contents <> "</sup>"+inlineToMarkdown opts (Subscript lst) = do+ contents <- inlineListToMarkdown opts $ walk escapeSpaces lst+ return $ if isEnabled Ext_subscript opts+ then "~" <> contents <> "~"+ else "<sub>" <> contents <> "</sub>"+inlineToMarkdown opts (SmallCaps lst) = do+ plain <- gets stPlain+ if plain+ then inlineListToMarkdown opts $ capitalize lst+ else do+ contents <- inlineListToMarkdown opts lst+ return $ tagWithAttrs "span"+ ("",[],[("style","font-variant:small-caps;")])+ <> contents <> text "</span>"+inlineToMarkdown opts (Quoted SingleQuote lst) = do+ contents <- inlineListToMarkdown opts lst+ return $ "‘" <> contents <> "’"+inlineToMarkdown opts (Quoted DoubleQuote lst) = do+ contents <- inlineListToMarkdown opts lst+ return $ "“" <> contents <> "”"+inlineToMarkdown opts (Code attr str) = do+ let tickGroups = filter (\s -> '`' `elem` s) $ group str+ let longest = if null tickGroups+ then 0+ else maximum $ map length tickGroups+ let marker = replicate (longest + 1) '`'+ let spacer = if (longest == 0) then "" else " "+ let attrs = if isEnabled Ext_inline_code_attributes opts && attr /= nullAttr+ then attrsToMarkdown attr+ else empty+ plain <- gets stPlain+ if plain+ then return $ text str+ else return $ text (marker ++ spacer ++ str ++ spacer ++ marker) <> attrs+inlineToMarkdown opts (Str str) = do+ st <- get+ if stPlain st+ then return $ text str+ else return $ text $ escapeString opts str+inlineToMarkdown opts (Math InlineMath str)+ | isEnabled Ext_scholarly_markdown opts =+ return $ "``" <> text (trim str) <> "``"+ | isEnabled Ext_tex_math_dollars opts =+ return $ "$" <> text str <> "$"+ | isEnabled Ext_tex_math_single_backslash opts =+ return $ "\\(" <> text str <> "\\)"+ | isEnabled Ext_tex_math_double_backslash opts =+ return $ "\\\\(" <> text str <> "\\\\)"+ | otherwise = do+ plain <- gets stPlain+ inlineListToMarkdown opts $+ (if plain then makeMathPlainer else id) $+ texMathToInlines InlineMath str+inlineToMarkdown opts (Math (DisplayMath a) str)+ | isEnabled Ext_tex_math_dollars opts =+ return $ "$$" <> text str <> "$$"+ | isEnabled Ext_tex_math_single_backslash opts =+ return $ "\\[" <> text str <> "\\]"+ | isEnabled Ext_tex_math_double_backslash opts =+ return $ "\\\\[" <> text str <> "\\\\]"+ | otherwise = (\x -> cr <> x <> cr) `fmap`+ inlineListToMarkdown opts (texMathToInlines (DisplayMath a) str)+inlineToMarkdown opts (RawInline f str) = do+ plain <- gets stPlain+ if not plain &&+ ( f == "markdown" ||+ (isEnabled Ext_raw_tex opts && (f == "latex" || f == "tex")) ||+ (isEnabled Ext_raw_html opts && f == "html") )+ then return $ text str+ else return empty+inlineToMarkdown opts (LineBreak) = do+ plain <- gets stPlain+ if plain || isEnabled Ext_hard_line_breaks opts+ then return cr+ else return $+ if isEnabled Ext_escaped_line_breaks opts+ then "\\" <> cr+ else " " <> cr+inlineToMarkdown _ Space = return space+inlineToMarkdown opts (Cite [] lst) = inlineListToMarkdown opts lst+inlineToMarkdown opts (Cite (c:cs) lst)+ | not (isEnabled Ext_citations opts) = inlineListToMarkdown opts lst+ | otherwise =+ if citationMode c == AuthorInText+ then do+ suffs <- inlineListToMarkdown opts $ citationSuffix c+ rest <- mapM convertOne cs+ let inbr = suffs <+> joincits rest+ br = if isEmpty inbr then empty else char '[' <> inbr <> char ']'+ return $ text ("@" ++ citationId c) <+> br+ else do+ cits <- mapM convertOne (c:cs)+ return $ text "[" <> joincits cits <> text "]"+ where+ joincits = hcat . intersperse (text "; ") . filter (not . isEmpty)+ convertOne Citation { citationId = k+ , citationPrefix = pinlines+ , citationSuffix = sinlines+ , citationMode = m }+ = do+ pdoc <- inlineListToMarkdown opts pinlines+ sdoc <- inlineListToMarkdown opts sinlines+ let k' = text (modekey m ++ "@" ++ k)+ r = case sinlines of+ Str (y:_):_ | y `elem` ",;]@" -> k' <> sdoc+ _ -> k' <+> sdoc+ return $ pdoc <+> r+ modekey SuppressAuthor = "-"+ modekey _ = ""+inlineToMarkdown opts (Link txt (src, tit)) = do+ plain <- gets stPlain+ linktext <- inlineListToMarkdown opts txt+ let linktitle = if null tit+ then empty+ else text $ " \"" ++ tit ++ "\""+ let srcSuffix = fromMaybe src (stripPrefix "mailto:" src)+ let useAuto = isURI src &&+ case txt of+ [Str s] | escapeURI s == srcSuffix -> True+ _ -> False+ let useRefLinks = writerReferenceLinks opts && not useAuto+ ref <- if useRefLinks then getReference txt (src, tit) else return []+ reftext <- inlineListToMarkdown opts ref+ return $ if useAuto+ then if plain+ then text srcSuffix+ else "<" <> text srcSuffix <> ">"+ else if useRefLinks+ then let first = "[" <> linktext <> "]"+ second = if txt == ref+ then "[]"+ else "[" <> reftext <> "]"+ in first <> second+ else if plain+ then linktext+ else "[" <> linktext <> "](" <>+ text src <> linktitle <> ")"+inlineToMarkdown opts (Image _ alternate (source, tit)) = do+ plain <- gets stPlain+ let txt = if null alternate || alternate == [Str source]+ -- to prevent autolinks+ then [Str ""]+ else alternate+ linkPart <- inlineToMarkdown opts (Link txt (source, tit))+ return $ if plain+ then "[" <> linkPart <> "]"+ else "!" <> linkPart+inlineToMarkdown opts (Note contents) = do+ modify (\st -> st{ stNotes = contents : stNotes st })+ st <- get+ let ref = text $ writerIdentifierPrefix opts ++ show (length $ stNotes st)+ if isEnabled Ext_footnotes opts+ then return $ "[^" <> ref <> "]"+ else return $ "[" <> ref <> "]"+inlineToMarkdown _ (NumRef _ _) = return empty++makeMathPlainer :: [Inline] -> [Inline]+makeMathPlainer = walk go+ where+ go (Emph xs) = Span nullAttr xs+ go x = x
@@ -0,0 +1,78 @@+{-# LANGUAGE OverloadedStrings #-}+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.Native+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of a 'Pandoc' document to a string representation.++Note: If @writerStandalone@ is @False@, only the document body+is represented; otherwise, the full 'Pandoc' document, including the+metadata.+-}+module Text.Pandoc.Writers.Native ( writeNative )+where+import Text.Pandoc.Options ( WriterOptions(..) )+import Data.List ( intersperse )+import Text.Pandoc.Definition+import Text.Pandoc.Pretty++prettyList :: [Doc] -> Doc+prettyList ds =+ "[" <> (cat $ intersperse (cr <> ",") $ map (nest 1) ds) <> "]"++-- | Prettyprint Pandoc block element.+prettyBlock :: Block -> Doc+prettyBlock (BlockQuote blocks) =+ "BlockQuote" $$ prettyList (map prettyBlock blocks)+prettyBlock (OrderedList attribs blockLists) =+ "OrderedList" <> space <> text (show attribs) $$+ (prettyList $ map (prettyList . map prettyBlock) blockLists)+prettyBlock (BulletList blockLists) =+ "BulletList" $$+ (prettyList $ map (prettyList . map prettyBlock) blockLists)+prettyBlock (DefinitionList items) = "DefinitionList" $$+ (prettyList $ map deflistitem items)+ where deflistitem (term, defs) = "(" <> text (show term) <> "," <> cr <>+ nest 1 (prettyList $ map (prettyList . map prettyBlock) defs) <> ")"+prettyBlock (Table caption aligns widths header rows) =+ "Table " <> text (show caption) <> " " <> text (show aligns) <> " " <>+ text (show widths) $$+ prettyRow header $$+ prettyList (map prettyRow rows)+ where prettyRow cols = prettyList (map (prettyList . map prettyBlock) cols)+prettyBlock block = text $ show block++-- | Prettyprint Pandoc document.+writeNative :: WriterOptions -> Pandoc -> String+writeNative opts (Pandoc meta blocks) =+ let colwidth = if writerWrapText opts+ then Just $ writerColumns opts+ else Nothing+ withHead = if writerStandalone opts+ then \bs -> text ("Pandoc (" ++ show meta ++ ")") $$+ bs $$ cr+ else id+ in render colwidth $ withHead $ prettyList $ map prettyBlock blocks
@@ -0,0 +1,165 @@+{-# LANGUAGE OverloadedStrings #-}+{-+Copyright (C) 2013-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.Shared+ Copyright : Copyright (C) 2013-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Shared utility functions for pandoc writers.+-}+module Text.Pandoc.Writers.Shared (+ metaToJSON+ , getField+ , setField+ , defField+ , tagWithAttrs+ , fixDisplayMath+ )+where+import Text.Pandoc.Definition+import Text.Pandoc.Pretty+import Text.Pandoc.XML (escapeStringForXML)+import Control.Monad (liftM)+import Text.Pandoc.Options (WriterOptions(..))+import qualified Data.HashMap.Strict as H+import qualified Data.Map as M+import qualified Data.Text as T+import Data.Aeson (FromJSON(..), fromJSON, ToJSON (..), Value(Object), Result(..))+import qualified Data.Traversable as Traversable+import Data.List ( groupBy )++-- | Create JSON value for template from a 'Meta' and an association list+-- of variables, specified at the command line or in the writer.+-- Variables overwrite metadata fields with the same names.+-- If multiple variables are set with the same name, a list is+-- assigned.+metaToJSON :: Monad m+ => WriterOptions+ -> ([Block] -> m String)+ -> ([Inline] -> m String)+ -> Meta+ -> m Value+metaToJSON opts blockWriter inlineWriter (Meta metamap)+ | writerStandalone opts = do+ let baseContext = foldl (\acc (x,y) -> setField x y acc) (Object H.empty)+ $ writerVariables opts+ renderedMap <- Traversable.mapM+ (metaValueToJSON blockWriter inlineWriter)+ metamap+ return $ M.foldWithKey defField baseContext renderedMap+ | otherwise = return (Object H.empty)++metaValueToJSON :: Monad m+ => ([Block] -> m String)+ -> ([Inline] -> m String)+ -> MetaValue+ -> m Value+metaValueToJSON blockWriter inlineWriter (MetaMap metamap) = liftM toJSON $+ Traversable.mapM (metaValueToJSON blockWriter inlineWriter) metamap+metaValueToJSON blockWriter inlineWriter (MetaList xs) = liftM toJSON $+ Traversable.mapM (metaValueToJSON blockWriter inlineWriter) xs+metaValueToJSON _ _ (MetaBool b) = return $ toJSON b+metaValueToJSON _ _ (MetaString s) = return $ toJSON s+metaValueToJSON blockWriter _ (MetaBlocks bs) = liftM toJSON $ blockWriter bs+metaValueToJSON _ inlineWriter (MetaInlines bs) = liftM toJSON $ inlineWriter bs++-- | Retrieve a field value from a JSON object.+getField :: FromJSON a+ => String+ -> Value+ -> Maybe a+getField field (Object hashmap) = do+ result <- H.lookup (T.pack field) hashmap+ case fromJSON result of+ Success x -> return x+ _ -> fail "Could not convert from JSON"+getField _ _ = fail "Not a JSON object"++setField :: ToJSON a+ => String+ -> a+ -> Value+ -> Value+-- | Set a field of a JSON object. If the field already has a value,+-- convert it into a list with the new value appended to the old value(s).+-- This is a utility function to be used in preparing template contexts.+setField field val (Object hashmap) =+ Object $ H.insertWith combine (T.pack field) (toJSON val) hashmap+ where combine newval oldval =+ case fromJSON oldval of+ Success xs -> toJSON $ xs ++ [newval]+ _ -> toJSON [oldval, newval]+setField _ _ x = x++defField :: ToJSON a+ => String+ -> a+ -> Value+ -> Value+-- | Set a field of a JSON object if it currently has no value.+-- If it has a value, do nothing.+-- This is a utility function to be used in preparing template contexts.+defField field val (Object hashmap) =+ Object $ H.insertWith f (T.pack field) (toJSON val) hashmap+ where f _newval oldval = oldval+defField _ _ x = x++-- Produce an HTML tag with the given pandoc attributes.+tagWithAttrs :: String -> Attr -> Doc+tagWithAttrs tag (ident,classes,kvs) = hsep+ ["<" <> text tag+ ,if null ident+ then empty+ else "id=" <> doubleQuotes (text ident)+ ,if null classes+ then empty+ else "class=" <> doubleQuotes (text (unwords classes))+ ,hsep (map (\(k,v) -> text k <> "=" <>+ doubleQuotes (text (escapeStringForXML v))) kvs)+ ] <> ">"++isDisplayMath :: Inline -> Bool+isDisplayMath (Math (DisplayMath _) _) = True+isDisplayMath _ = False++stripLeadingTrailingSpace :: [Inline] -> [Inline]+stripLeadingTrailingSpace = go . reverse . go . reverse+ where go (Space:xs) = xs+ go xs = xs++-- Put display math in its own block (for ODT/DOCX).+fixDisplayMath :: Block -> Block+fixDisplayMath (Plain lst)+ | any isDisplayMath lst && not (all isDisplayMath lst) =+ -- chop into several paragraphs so each displaymath is its own+ Div ("",["math"],[]) $ map (Plain . stripLeadingTrailingSpace) $+ groupBy (\x y -> (isDisplayMath x && isDisplayMath y) ||+ not (isDisplayMath x || isDisplayMath y)) lst+fixDisplayMath (Para lst)+ | any isDisplayMath lst && not (all isDisplayMath lst) =+ -- chop into several paragraphs so each displaymath is its own+ Div ("",["math"],[]) $ map (Para . stripLeadingTrailingSpace) $+ groupBy (\x y -> (isDisplayMath x && isDisplayMath y) ||+ not (isDisplayMath x || isDisplayMath y)) lst+fixDisplayMath x = x
@@ -0,0 +1,110 @@+{-+Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.XML+ Copyright : Copyright (C) 2006-2014 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Functions for escaping and formatting XML.+-}+module Text.Pandoc.XML ( escapeCharForXML,+ escapeStringForXML,+ inTags,+ selfClosingTag,+ inTagsSimple,+ inTagsIndented,+ toEntities,+ fromEntities ) where++import Text.Pandoc.Pretty+import Data.Char (ord, isAscii, isSpace)+import Text.Pandoc.Compat.TagSoupEntity (lookupEntity)++-- | Escape one character as needed for XML.+escapeCharForXML :: Char -> String+escapeCharForXML x = case x of+ '&' -> "&"+ '<' -> "<"+ '>' -> ">"+ '"' -> """+ c -> [c]++-- | Escape string as needed for XML. Entity references are not preserved.+escapeStringForXML :: String -> String+escapeStringForXML = concatMap escapeCharForXML++-- | Escape newline characters as +escapeNls :: String -> String+escapeNls (x:xs)+ | x == '\n' = " " ++ escapeNls xs+ | otherwise = x : escapeNls xs+escapeNls [] = []++-- | Return a text object with a string of formatted XML attributes.+attributeList :: [(String, String)] -> Doc+attributeList = hcat . map+ (\(a, b) -> text (' ' : escapeStringForXML a ++ "=\"" +++ escapeNls (escapeStringForXML b) ++ "\""))++-- | Put the supplied contents between start and end tags of tagType,+-- with specified attributes and (if specified) indentation.+inTags:: Bool -> String -> [(String, String)] -> Doc -> Doc+inTags isIndented tagType attribs contents =+ let openTag = char '<' <> text tagType <> attributeList attribs <>+ char '>'+ closeTag = text "</" <> text tagType <> char '>'+ in if isIndented+ then openTag $$ nest 2 contents $$ closeTag+ else openTag <> contents <> closeTag++-- | Return a self-closing tag of tagType with specified attributes+selfClosingTag :: String -> [(String, String)] -> Doc+selfClosingTag tagType attribs =+ char '<' <> text tagType <> attributeList attribs <> text " />"++-- | Put the supplied contents between start and end tags of tagType.+inTagsSimple :: String -> Doc -> Doc+inTagsSimple tagType = inTags False tagType []++-- | Put the supplied contents in indented block btw start and end tags.+inTagsIndented :: String -> Doc -> Doc+inTagsIndented tagType = inTags True tagType []++-- | Escape all non-ascii characters using numerical entities.+toEntities :: String -> String+toEntities [] = ""+toEntities (c:cs)+ | isAscii c = c : toEntities cs+ | otherwise = "&#" ++ show (ord c) ++ ";" ++ toEntities cs++-- Unescapes XML entities+fromEntities :: String -> String+fromEntities ('&':xs) =+ case lookupEntity ent of+ Just c -> c : fromEntities rest+ Nothing -> '&' : fromEntities xs+ where (ent, rest) = case break (\c -> isSpace c || c == ';') xs of+ (zs,';':ys) -> (zs,ys)+ _ -> ("",xs)+fromEntities (x:xs) = x : fromEntities xs+fromEntities [] = []
@@ -0,0 +1,193 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, ScopedTypeVariables #-}+-- provides Arbitrary instance for Pandoc types+module Tests.Arbitrary ()+where+import Test.QuickCheck.Gen+import Test.QuickCheck.Arbitrary+import Control.Monad (liftM, liftM2)+import Text.Pandoc.Definition+import Text.Pandoc.Shared (normalize, escapeURI)+import Text.Pandoc.Builder++realString :: Gen String+realString = resize 8 $ listOf $ frequency [ (9, elements [' '..'\127'])+ , (1, elements ['\128'..'\9999']) ]++arbAttr :: Gen Attr+arbAttr = do+ id' <- elements ["","loc"]+ classes <- elements [[],["haskell"],["c","numberLines"]]+ keyvals <- elements [[],[("start","22")],[("a","11"),("b_2","a b c")]]+ return (id',classes,keyvals)++instance Arbitrary Inlines where+ arbitrary = liftM (fromList :: [Inline] -> Inlines) arbitrary++instance Arbitrary Blocks where+ arbitrary = liftM (fromList :: [Block] -> Blocks) arbitrary++instance Arbitrary Inline where+ arbitrary = resize 3 $ arbInline 2++arbInlines :: Int -> Gen [Inline]+arbInlines n = listOf1 (arbInline n) `suchThat` (not . startsWithSpace)+ where startsWithSpace (Space:_) = True+ startsWithSpace _ = False++-- restrict to 3 levels of nesting max; otherwise we get+-- bogged down in indefinitely large structures+arbInline :: Int -> Gen Inline+arbInline n = frequency $ [ (60, liftM Str realString)+ , (60, return Space)+ , (10, liftM2 Code arbAttr realString)+ , (5, elements [ RawInline (Format "html") "<a id=\"eek\">"+ , RawInline (Format "latex") "\\my{command}" ])+ ] ++ [ x | x <- nesters, n > 1]+ where nesters = [ (10, liftM Emph $ arbInlines (n-1))+ , (10, liftM Strong $ arbInlines (n-1))+ , (10, liftM Strikeout $ arbInlines (n-1))+ , (10, liftM Superscript $ arbInlines (n-1))+ , (10, liftM Subscript $ arbInlines (n-1))+ , (10, liftM SmallCaps $ arbInlines (n-1))+ , (10, do x1 <- arbitrary+ x2 <- arbInlines (n-1)+ return $ Quoted x1 x2)+ , (10, do x1 <- arbitrary+ x2 <- realString+ return $ Math x1 x2)+ , (10, do x1 <- arbInlines (n-1)+ x3 <- realString+ x2 <- liftM escapeURI realString+ return $ Link x1 (x2,x3))+ , (10, do x1 <- arbInlines (n-1)+ x3 <- realString+ x2 <- liftM escapeURI realString+ atr <- arbAttr+ return $ Image atr x1 (x2,x3))+ , (2, liftM2 Cite arbitrary (arbInlines 1))+ , (2, liftM Note $ resize 3 $ listOf1 $ arbBlock (n-1))+ ]++instance Arbitrary Block where+ arbitrary = resize 3 $ arbBlock 2++arbBlock :: Int -> Gen Block+arbBlock n = frequency $ [ (10, liftM Plain $ arbInlines (n-1))+ , (15, liftM Para $ arbInlines (n-1))+ , (5, liftM2 CodeBlock arbAttr realString)+ , (2, elements [ RawBlock (Format "html")+ "<div>\n*&*\n</div>"+ , RawBlock (Format "latex")+ "\\begin[opt]{env}\nhi\n{\\end{env}"+ ])+ , (5, do x1 <- choose (1 :: Int, 6)+ x2 <- arbInlines (n-1)+ return (Header x1 nullAttr x2))+ , (2, return HorizontalRule)+ ] ++ [x | x <- nesters, n > 0]+ where nesters = [ (5, liftM BlockQuote $ listOf1 $ arbBlock (n-1))+ , (5, do x2 <- arbitrary+ x3 <- arbitrary+ x1 <- arbitrary `suchThat` (> 0)+ x4 <- listOf1 $ listOf1 $ arbBlock (n-1)+ return $ OrderedList (x1,x2,x3) x4 )+ , (5, liftM BulletList $ (listOf1 $ listOf1 $ arbBlock (n-1)))+ , (5, do items <- listOf1 $ do+ x1 <- listOf1 $ listOf1 $ arbBlock (n-1)+ x2 <- arbInlines (n-1)+ return (x2,x1)+ return $ DefinitionList items)+ , (2, do rs <- choose (1 :: Int, 4)+ cs <- choose (1 :: Int, 4)+ x1 <- arbInlines (n-1)+ x2 <- vector cs+ x3 <- vectorOf cs $ elements [0, 0.25]+ x4 <- vectorOf cs $ listOf $ arbBlock (n-1)+ x5 <- vectorOf rs $ vectorOf cs+ $ listOf $ arbBlock (n-1)+ return (Table x1 x2 x3 x4 x5))+ ]++instance Arbitrary Pandoc where+ arbitrary = resize 8 $ liftM normalize+ $ liftM2 Pandoc arbitrary arbitrary++instance Arbitrary CitationMode where+ arbitrary+ = do x <- choose (0 :: Int, 2)+ case x of+ 0 -> return AuthorInText+ 1 -> return SuppressAuthor+ 2 -> return NormalCitation+ _ -> error "FATAL ERROR: Arbitrary instance, logic bug"++instance Arbitrary Citation where+ arbitrary+ = do x1 <- listOf $ elements $ ['a'..'z'] ++ ['0'..'9'] ++ ['_']+ x2 <- arbInlines 1+ x3 <- arbInlines 1+ x4 <- arbitrary+ x5 <- arbitrary+ x6 <- arbitrary+ return (Citation x1 x2 x3 x4 x5 x6)++instance Arbitrary MathType where+ arbitrary+ = do x <- choose (0 :: Int, 1)+ case x of+ 0 -> liftM DisplayMath arbAttr+ 1 -> return InlineMath+ _ -> error "FATAL ERROR: Arbitrary instance, logic bug"++instance Arbitrary QuoteType where+ arbitrary+ = do x <- choose (0 :: Int, 1)+ case x of+ 0 -> return SingleQuote+ 1 -> return DoubleQuote+ _ -> error "FATAL ERROR: Arbitrary instance, logic bug"++instance Arbitrary Meta where+ arbitrary+ = do (x1 :: Inlines) <- arbitrary+ (x2 :: [Inlines]) <- liftM (filter (not . isNull)) arbitrary+ (x3 :: Inlines) <- arbitrary+ return $ setMeta "title" x1+ $ setMeta "author" x2+ $ setMeta "date" x3+ $ nullMeta++instance Arbitrary Alignment where+ arbitrary+ = do x <- choose (0 :: Int, 3)+ case x of+ 0 -> return AlignLeft+ 1 -> return AlignRight+ 2 -> return AlignCenter+ 3 -> return AlignDefault+ _ -> error "FATAL ERROR: Arbitrary instance, logic bug"++instance Arbitrary ListNumberStyle where+ arbitrary+ = do x <- choose (0 :: Int, 6)+ case x of+ 0 -> return DefaultStyle+ 1 -> return Example+ 2 -> return Decimal+ 3 -> return LowerRoman+ 4 -> return UpperRoman+ 5 -> return LowerAlpha+ 6 -> return UpperAlpha+ _ -> error "FATAL ERROR: Arbitrary instance, logic bug"++instance Arbitrary ListNumberDelim where+ arbitrary+ = do x <- choose (0 :: Int, 3)+ case x of+ 0 -> return DefaultDelim+ 1 -> return Period+ 2 -> return OneParen+ 3 -> return TwoParens+ _ -> error "FATAL ERROR: Arbitrary instance, logic bug"+
@@ -0,0 +1,85 @@+{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}+-- Utility functions for the test suite.++module Tests.Helpers ( test+ , (=?>)+ , property+ , ToString(..)+ , ToPandoc(..)+ )+ where++import Text.Pandoc.Definition+import Text.Pandoc.Builder (Inlines, Blocks, doc, plain)+import Test.Framework+import Test.Framework.Providers.HUnit+import Test.Framework.Providers.QuickCheck2+import Test.HUnit (assertBool)+import Text.Pandoc.Shared (normalize, trimr)+import Text.Pandoc.Options+import Text.Pandoc.Writers.Native (writeNative)+import qualified Test.QuickCheck.Property as QP+import Data.Algorithm.Diff+import qualified Data.Map as M++test :: (ToString a, ToString b, ToString c)+ => (a -> b) -- ^ function to test+ -> String -- ^ name of test case+ -> (a, c) -- ^ (input, expected value)+ -> Test+test fn name (input, expected) =+ testCase name $ assertBool msg (actual' == expected')+ where msg = nl ++ dashes "input" ++ nl ++ input' ++ nl +++ dashes "result" ++ nl +++ unlines (map vividize diff) +++ dashes ""+ nl = "\n"+ input' = toString input+ actual' = lines $ toString $ fn input+ expected' = lines $ toString expected+ diff = getDiff expected' actual'+ dashes "" = replicate 72 '-'+ dashes x = replicate (72 - length x - 5) '-' ++ " " ++ x ++ " ---"++vividize :: Diff String -> String+vividize (Both s _) = " " ++ s+vividize (First s) = "- " ++ s+vividize (Second s) = "+ " ++ s++property :: QP.Testable a => TestName -> a -> Test+property = testProperty++infix 5 =?>+(=?>) :: a -> b -> (a,b)+x =?> y = (x, y)++class ToString a where+ toString :: a -> String++instance ToString Pandoc where+ toString d = writeNative def{ writerStandalone = s } $ toPandoc d+ where s = case d of+ (Pandoc (Meta m) _)+ | M.null m -> False+ | otherwise -> True++instance ToString Blocks where+ toString = writeNative def . toPandoc++instance ToString Inlines where+ toString = trimr . writeNative def . toPandoc++instance ToString String where+ toString = id++class ToPandoc a where+ toPandoc :: a -> Pandoc++instance ToPandoc Pandoc where+ toPandoc = normalize++instance ToPandoc Blocks where+ toPandoc = normalize . doc++instance ToPandoc Inlines where+ toPandoc = normalize . doc . plain
@@ -0,0 +1,193 @@+module Tests.Old (tests) where++import Test.Framework (testGroup, Test )+import Test.Framework.Providers.HUnit+import Test.HUnit ( assertBool )+import System.Environment.Executable (getExecutablePath)+import System.IO ( openTempFile, stderr )+import System.Process ( runProcess, waitForProcess )+import System.FilePath ( (</>), (<.>), takeDirectory, splitDirectories, joinPath )+import System.Directory+import System.Exit+import Data.Algorithm.Diff+import Text.Pandoc.Shared ( normalize )+import Text.Pandoc.Options+import Text.Pandoc.Writers.Native ( writeNative )+import Text.Pandoc.Readers.Native ( readNative )+import Prelude hiding ( readFile )+import qualified Data.ByteString.Lazy as B+import Text.Pandoc.UTF8 (toStringLazy)+import Text.Printf++readFileUTF8 :: FilePath -> IO String+readFileUTF8 f = B.readFile f >>= return . toStringLazy++data TestResult = TestPassed+ | TestError ExitCode+ | TestFailed String FilePath [Diff String]+ deriving (Eq)++instance Show TestResult where+ show TestPassed = "PASSED"+ show (TestError ec) = "ERROR " ++ show ec+ show (TestFailed cmd file d) = '\n' : dash +++ "\n--- " ++ file +++ "\n+++ " ++ cmd ++ "\n" ++ showDiff (1,1) d +++ dash+ where dash = replicate 72 '-'++showDiff :: (Int,Int) -> [Diff String] -> String+showDiff _ [] = ""+showDiff (l,r) (First ln : ds) =+ printf "+%4d " l ++ ln ++ "\n" ++ showDiff (l+1,r) ds+showDiff (l,r) (Second ln : ds) =+ printf "-%4d " r ++ ln ++ "\n" ++ showDiff (l,r+1) ds+showDiff (l,r) (Both _ _ : ds) =+ showDiff (l+1,r+1) ds++tests :: [Test]+tests = [ testGroup "markdown"+ [ testGroup "writer"+ $ writerTests "markdown" ++ lhsWriterTests "markdown"+ , testGroup "reader"+ [ test "basic" ["-r", "markdown", "-w", "native", "-s", "-S"]+ "testsuite.txt" "testsuite.native"+ , test "tables" ["-r", "markdown", "-w", "native", "--columns=80"]+ "tables.txt" "tables.native"+ , test "pipe tables" ["-r", "markdown", "-w", "native", "--columns=80"]+ "pipe-tables.txt" "pipe-tables.native"+ , test "more" ["-r", "markdown", "-w", "native", "-S"]+ "markdown-reader-more.txt" "markdown-reader-more.native"+ , test "scholdoc" ["-r", "markdown_scholarly", "-w", "native", "-s", "-S", "-R"]+ "scholdoc.txt" "scholdoc.native"+ , lhsReaderTest "markdown+lhs"+ ]+ , testGroup "citations"+ [ test "citations" ["-r", "markdown", "-w", "native"]+ "markdown-citations.txt" "markdown-citations.native"+ ]+ ]+ , testGroup "latex"+ [ testGroup "writer" (writerTests "latex" ++ lhsWriterTests "latex" +++ [ test "scholdoc" ["-r", "markdown_scholarly", "-w", "latex", "-S", "-R",+ "--chapters", "--columns=72"]+ "scholdoc.txt" "scholdoc.latex"+ ])+ ]+ , testGroup "html"+ [ testGroup "writer" (writerTests "html" ++ lhsWriterTests "html" +++ [ test "scholdoc" ["-r", "markdown_scholarly", "-w", "html5", "-S", "-R",+ "--template=scholmdTemplate_bodyOnly.html5",+ "--mathjax", "--no-mathjax-cdn", "--columns=72"]+ "scholdoc.txt" "scholdoc.html"+ ])+ ]+ , testGroup "s5"+ [ s5WriterTest "basic" ["-s"] "s5"+ , s5WriterTest "fancy" ["-s","-m","-i"] "s5"+ , s5WriterTest "fragment" [] "html"+ , s5WriterTest "inserts" ["-s", "-H", "insert",+ "-B", "insert", "-A", "insert", "-c", "main.css"] "html"+ ]+ , testGroup "native"+ [ testGroup "writer" $ writerTests "native"+ , test "reader" ["-r", "native", "-w", "native", "-s"]+ "testsuite.native" "testsuite.native"+ ]+ , testGroup "haddock"+ [ testGroup "writer" $ writerTests "haddock"+ ]+ , testGroup "other writers" $ map (\f -> testGroup f $ writerTests f)+ [ "man" , "plain"+ ]+ ]++-- makes sure file is fully closed after reading+readFile' :: FilePath -> IO String+readFile' f = do s <- readFileUTF8 f+ return $! (length s `seq` s)++lhsWriterTests :: String -> [Test]+lhsWriterTests format+ = [ t "lhs to normal" format+ , t "lhs to lhs" (format ++ "+lhs")+ ]+ where+ t n f = test n ["--columns=78", "-r", "native", "-s", "-w", f]+ "lhs-test.native" ("lhs-test" <.> f)++lhsReaderTest :: String -> Test+lhsReaderTest format =+ testWithNormalize normalizer "lhs" ["-r", format, "-w", "native"]+ ("lhs-test" <.> format) norm+ where normalizer = writeNative def . normalize . readNative+ norm = if format == "markdown+lhs"+ then "lhs-test-markdown.native"+ else "lhs-test.native"++writerTests :: String -> [Test]+writerTests format+ = [ test "basic" (opts ++ ["-s"]) "testsuite.native" ("writer" <.> format)+ , test "tables" opts "tables.native" ("tables" <.> format)+ ]+ where+ opts = ["-r", "native", "-w", format, "--columns=78"]++s5WriterTest :: String -> [String] -> String -> Test+s5WriterTest modifier opts format+ = test (format ++ " writer (" ++ modifier ++ ")")+ (["-r", "native", "-w", format] ++ opts)+ "s5.native" ("s5-" ++ modifier <.> "html")++-- | Run a test without normalize function, return True if test passed.+test :: String -- ^ Title of test+ -> [String] -- ^ Options to pass to scholdoc+ -> String -- ^ Input filepath+ -> FilePath -- ^ Norm (for test results) filepath+ -> Test+test = testWithNormalize id++-- | Run a test with normalize function, return True if test passed.+testWithNormalize :: (String -> String) -- ^ Normalize function for output+ -> String -- ^ Title of test+ -> [String] -- ^ Options to pass to scholdoc+ -> String -- ^ Input filepath+ -> FilePath -- ^ Norm (for test results) filepath+ -> Test+testWithNormalize normalizer testname opts inp norm = testCase testname $ do+ -- find scholdoc executable relative to test-scholdoc+ -- First, try in same directory (e.g. if both in ~/.cabal/bin)+ -- Second, try ../scholdoc (e.g. if in dist/XXX/build/test-scholdoc)+ scholdocPath <- do+ testExePath <- getExecutablePath+ let testExeDir = takeDirectory testExePath+ found <- doesFileExist (testExeDir </> "scholdoc")+ return $ if found+ then testExeDir </> "scholdoc"+ else case splitDirectories testExeDir of+ [] -> error "test-scholdoc: empty testExeDir"+ xs -> joinPath (init xs) </> "scholdoc" </> "scholdoc"+ (outputPath, hOut) <- openTempFile "" "scholdoc-test"+ let inpPath = inp+ let normPath = norm+ let options = ["--emulate-pandoc", "--data-dir", ".." </> "data"] ++ [inpPath] ++ opts+ let cmd = scholdocPath ++ " " ++ unwords options+ ph <- runProcess scholdocPath options Nothing+ (Just [("TMP","."),("LANG","en_US.UTF-8"),("HOME", "./")]) Nothing (Just hOut)+ (Just stderr)+ ec <- waitForProcess ph+ result <- if ec == ExitSuccess+ then do+ -- filter \r so the tests will work on Windows machines+ outputContents <- readFile' outputPath >>=+ return . filter (/='\r') . normalizer+ normContents <- readFile' normPath >>=+ return . filter (/='\r') . normalizer+ if outputContents == normContents+ then return TestPassed+ else return+ $ TestFailed cmd normPath+ $ getDiff (lines outputContents) (lines normContents)+ else return $ TestError ec+ removeFile outputPath+ assertBool (show result) (result == TestPassed)
@@ -0,0 +1,177 @@+{-# LANGUAGE OverloadedStrings #-}+module Tests.Readers.LaTeX (tests) where++import Text.Pandoc.Definition+import Test.Framework+import Tests.Helpers+import Tests.Arbitrary()+import Text.Pandoc.Builder+import Text.Pandoc++latex :: String -> Pandoc+latex = readLaTeX def++infix 4 =:+(=:) :: ToString c+ => String -> (String, c) -> Test+(=:) = test latex++tests :: [Test]+tests = [ testGroup "basic"+ [ "simple" =:+ "word" =?> para "word"+ , "space" =:+ "some text" =?> para "some text"+ , "emphasized" =:+ "\\emph{emphasized}" =?> para (emph "emphasized")+ ]++ , testGroup "headers"+ [ "level 1" =:+ "\\section{header}" =?> headerWith ("header",[],[]) 1 "header"+ , "level 2" =:+ "\\subsection{header}" =?> headerWith ("header",[],[]) 2 "header"+ , "level 3" =:+ "\\subsubsection{header}" =?> headerWith ("header",[],[]) 3 "header"+ , "emph" =:+ "\\section{text \\emph{emph}}" =?>+ headerWith ("text-emph",[],[]) 1 ("text" <> space <> emph "emph")+ , "link" =:+ "\\section{text \\href{/url}{link}}" =?>+ headerWith ("text-link",[],[]) 1 ("text" <> space <> link "/url" "" "link")+ ]++ , testGroup "math"+ [ "escaped $" =:+ "$x=\\$4$" =?> para (math "x=\\$4")+ ]++ , testGroup "space and comments"+ [ "blank lines + space at beginning" =:+ "\n \n hi" =?> para "hi"+ , "blank lines + space + comments" =:+ "% my comment\n\n \n % another\n\nhi" =?> para "hi"+ , "comment in paragraph" =:+ "hi % this is a comment\nthere\n" =?> para "hi there"+ ]++ , testGroup "code blocks"+ [ "identifier" =:+ "\\begin{lstlisting}[label=test]\\end{lstlisting}" =?> codeBlockWith ("test", [], [("label","test")]) ""+ , "no identifier" =:+ "\\begin{lstlisting}\\end{lstlisting}" =?> codeBlock ""+ ]++ , testGroup "citations"+ [ natbibCitations+ , biblatexCitations+ ]+ ]++baseCitation :: Citation+baseCitation = Citation{ citationId = "item1"+ , citationPrefix = []+ , citationSuffix = []+ , citationMode = AuthorInText+ , citationNoteNum = 0+ , citationHash = 0+ }++rt :: String -> Inlines+rt = rawInline "latex"++natbibCitations :: Test+natbibCitations = testGroup "natbib"+ [ "citet" =: "\\citet{item1}"+ =?> para (cite [baseCitation] (rt "\\citet{item1}"))+ , "suffix" =: "\\citet[p.~30]{item1}"+ =?> para+ (cite [baseCitation{ citationSuffix = toList $ text "p.\160\&30" }] (rt "\\citet[p.~30]{item1}"))+ , "suffix long" =: "\\citet[p.~30, with suffix]{item1}"+ =?> para (cite [baseCitation{ citationSuffix =+ toList $ text "p.\160\&30, with suffix" }] (rt "\\citet[p.~30, with suffix]{item1}"))+ , "multiple" =: "\\citeauthor{item1} \\citetext{\\citeyear{item1}; \\citeyear[p.~30]{item2}; \\citealp[see also][]{item3}}"+ =?> para (cite [baseCitation{ citationMode = AuthorInText }+ ,baseCitation{ citationMode = SuppressAuthor+ , citationSuffix = [Str "p.\160\&30"]+ , citationId = "item2" }+ ,baseCitation{ citationId = "item3"+ , citationPrefix = [Str "see",Space,Str "also"]+ , citationMode = NormalCitation }+ ] (rt "\\citetext{\\citeyear{item1}; \\citeyear[p.~30]{item2}; \\citealp[see also][]{item3}}"))+ , "group" =: "\\citetext{\\citealp[see][p.~34--35]{item1}; \\citealp[also][chap. 3]{item3}}"+ =?> para (cite [baseCitation{ citationMode = NormalCitation+ , citationPrefix = [Str "see"]+ , citationSuffix = [Str "p.\160\&34\8211\&35"] }+ ,baseCitation{ citationMode = NormalCitation+ , citationId = "item3"+ , citationPrefix = [Str "also"]+ , citationSuffix = [Str "chap.",Space,Str "3"] }+ ] (rt "\\citetext{\\citealp[see][p.~34--35]{item1}; \\citealp[also][chap. 3]{item3}}"))+ , "suffix and locator" =: "\\citep[pp.~33, 35--37, and nowhere else]{item1}"+ =?> para (cite [baseCitation{ citationMode = NormalCitation+ , citationSuffix = [Str "pp.\160\&33,",Space,Str "35\8211\&37,",Space,Str "and",Space,Str "nowhere",Space, Str "else"] }] (rt "\\citep[pp.~33, 35--37, and nowhere else]{item1}"))+ , "suffix only" =: "\\citep[and nowhere else]{item1}"+ =?> para (cite [baseCitation{ citationMode = NormalCitation+ , citationSuffix = toList $ text "and nowhere else" }] (rt "\\citep[and nowhere else]{item1}"))+ , "no author" =: "\\citeyearpar{item1}, and now Doe with a locator \\citeyearpar[p.~44]{item2}"+ =?> para (cite [baseCitation{ citationMode = SuppressAuthor }] (rt "\\citeyearpar{item1}") <>+ text ", and now Doe with a locator " <>+ cite [baseCitation{ citationMode = SuppressAuthor+ , citationSuffix = [Str "p.\160\&44"]+ , citationId = "item2" }] (rt "\\citeyearpar[p.~44]{item2}"))+ , "markup" =: "\\citep[\\emph{see}][p. \\textbf{32}]{item1}"+ =?> para (cite [baseCitation{ citationMode = NormalCitation+ , citationPrefix = [Emph [Str "see"]]+ , citationSuffix = [Str "p.",Space,+ Strong [Str "32"]] }] (rt "\\citep[\\emph{see}][p. \\textbf{32}]{item1}"))+ ]++biblatexCitations :: Test+biblatexCitations = testGroup "biblatex"+ [ "textcite" =: "\\textcite{item1}"+ =?> para (cite [baseCitation] (rt "\\textcite{item1}"))+ , "suffix" =: "\\textcite[p.~30]{item1}"+ =?> para+ (cite [baseCitation{ citationSuffix = toList $ text "p.\160\&30" }] (rt "\\textcite[p.~30]{item1}"))+ , "suffix long" =: "\\textcite[p.~30, with suffix]{item1}"+ =?> para (cite [baseCitation{ citationSuffix =+ toList $ text "p.\160\&30, with suffix" }] (rt "\\textcite[p.~30, with suffix]{item1}"))+ , "multiple" =: "\\textcites{item1}[p.~30]{item2}[see also][]{item3}"+ =?> para (cite [baseCitation{ citationMode = AuthorInText }+ ,baseCitation{ citationMode = NormalCitation+ , citationSuffix = [Str "p.\160\&30"]+ , citationId = "item2" }+ ,baseCitation{ citationId = "item3"+ , citationPrefix = [Str "see",Space,Str "also"]+ , citationMode = NormalCitation }+ ] (rt "\\textcites{item1}[p.~30]{item2}[see also][]{item3}"))+ , "group" =: "\\autocites[see][p.~34--35]{item1}[also][chap. 3]{item3}"+ =?> para (cite [baseCitation{ citationMode = NormalCitation+ , citationPrefix = [Str "see"]+ , citationSuffix = [Str "p.\160\&34\8211\&35"] }+ ,baseCitation{ citationMode = NormalCitation+ , citationId = "item3"+ , citationPrefix = [Str "also"]+ , citationSuffix = [Str "chap.",Space,Str "3"] }+ ] (rt "\\autocites[see][p.~34--35]{item1}[also][chap. 3]{item3}"))+ , "suffix and locator" =: "\\autocite[pp.~33, 35--37, and nowhere else]{item1}"+ =?> para (cite [baseCitation{ citationMode = NormalCitation+ , citationSuffix = [Str "pp.\160\&33,",Space,Str "35\8211\&37,",Space,Str "and",Space,Str "nowhere",Space, Str "else"] }] (rt "\\autocite[pp.~33, 35--37, and nowhere else]{item1}"))+ , "suffix only" =: "\\autocite[and nowhere else]{item1}"+ =?> para (cite [baseCitation{ citationMode = NormalCitation+ , citationSuffix = toList $ text "and nowhere else" }] (rt "\\autocite[and nowhere else]{item1}"))+ , "no author" =: "\\autocite*{item1}, and now Doe with a locator \\autocite*[p.~44]{item2}"+ =?> para (cite [baseCitation{ citationMode = SuppressAuthor }] (rt "\\autocite*{item1}") <>+ text ", and now Doe with a locator " <>+ cite [baseCitation{ citationMode = SuppressAuthor+ , citationSuffix = [Str "p.\160\&44"]+ , citationId = "item2" }] (rt "\\autocite*[p.~44]{item2}"))+ , "markup" =: "\\autocite[\\emph{see}][p. \\textbf{32}]{item1}"+ =?> para (cite [baseCitation{ citationMode = NormalCitation+ , citationPrefix = [Emph [Str "see"]]+ , citationSuffix = [Str "p.",Space,+ Strong [Str "32"]] }] (rt "\\autocite[\\emph{see}][p. \\textbf{32}]{item1}"))+ , "parencite" =: "\\parencite{item1}"+ =?> para (cite [baseCitation{ citationMode = NormalCitation }] (rt "\\parencite{item1}"))+ ]
@@ -0,0 +1,290 @@+{-# LANGUAGE OverloadedStrings #-}+module Tests.Readers.Markdown (tests) where++import Text.Pandoc.Definition+import Test.Framework+import Tests.Helpers+import Tests.Arbitrary()+import Text.Pandoc.Builder+import qualified Data.Set as Set+-- import Text.Pandoc.Shared ( normalize )+import Text.Pandoc++markdown :: String -> Pandoc+markdown = readMarkdown def++markdownSmart :: String -> Pandoc+markdownSmart = readMarkdown def { readerSmart = True }++markdownCDL :: String -> Pandoc+markdownCDL = readMarkdown def { readerExtensions = Set.insert+ Ext_compact_definition_lists $ readerExtensions def }++infix 4 =:+(=:) :: ToString c+ => String -> (String, c) -> Test+(=:) = test markdown++testBareLink :: (String, Inlines) -> Test+testBareLink (inp, ils) =+ test (readMarkdown def{ readerExtensions =+ Set.fromList [Ext_autolink_bare_uris, Ext_raw_html] })+ inp (inp, doc $ para ils)++autolink :: String -> Inlines+autolink s = link s "" (str s)++bareLinkTests :: [(String, Inlines)]+bareLinkTests =+ [ ("http://google.com is a search engine.",+ autolink "http://google.com" <> " is a search engine.")+ , ("<a href=\"http://foo.bar.baz\">http://foo.bar.baz</a>",+ rawInline "html" "<a href=\"http://foo.bar.baz\">" <>+ "http://foo.bar.baz" <> rawInline "html" "</a>")+ , ("Try this query: http://google.com?search=fish&time=hour.",+ "Try this query: " <> autolink "http://google.com?search=fish&time=hour" <> ".")+ , ("HTTPS://GOOGLE.COM,",+ autolink "HTTPS://GOOGLE.COM" <> ",")+ , ("http://el.wikipedia.org/wiki/Τεχνολογία,",+ autolink "http://el.wikipedia.org/wiki/Τεχνολογία" <> ",")+ , ("doi:10.1000/182,",+ autolink "doi:10.1000/182" <> ",")+ , ("git://github.com/foo/bar.git,",+ autolink "git://github.com/foo/bar.git" <> ",")+ , ("file:///Users/joe/joe.txt, and",+ autolink "file:///Users/joe/joe.txt" <> ", and")+ , ("mailto:someone@somedomain.com.",+ autolink "mailto:someone@somedomain.com" <> ".")+ , ("Use http: this is not a link!",+ "Use http: this is not a link!")+ , ("(http://google.com).",+ "(" <> autolink "http://google.com" <> ").")+ , ("http://en.wikipedia.org/wiki/Sprite_(computer_graphics)",+ autolink "http://en.wikipedia.org/wiki/Sprite_(computer_graphics)")+ , ("http://en.wikipedia.org/wiki/Sprite_[computer_graphics]",+ autolink "http://en.wikipedia.org/wiki/Sprite_[computer_graphics]")+ , ("http://en.wikipedia.org/wiki/Sprite_{computer_graphics}",+ autolink "http://en.wikipedia.org/wiki/Sprite_{computer_graphics}")+ , ("http://example.com/Notification_Center-GitHub-20101108-140050.jpg",+ autolink "http://example.com/Notification_Center-GitHub-20101108-140050.jpg")+ , ("https://github.com/github/hubot/blob/master/scripts/cream.js#L20-20",+ autolink "https://github.com/github/hubot/blob/master/scripts/cream.js#L20-20")+ , ("http://www.rubyonrails.com",+ autolink "http://www.rubyonrails.com")+ , ("http://www.rubyonrails.com:80",+ autolink "http://www.rubyonrails.com:80")+ , ("http://www.rubyonrails.com/~minam",+ autolink "http://www.rubyonrails.com/~minam")+ , ("https://www.rubyonrails.com/~minam",+ autolink "https://www.rubyonrails.com/~minam")+ , ("http://www.rubyonrails.com/~minam/url%20with%20spaces",+ autolink "http://www.rubyonrails.com/~minam/url%20with%20spaces")+ , ("http://www.rubyonrails.com/foo.cgi?something=here",+ autolink "http://www.rubyonrails.com/foo.cgi?something=here")+ , ("http://www.rubyonrails.com/foo.cgi?something=here&and=here",+ autolink "http://www.rubyonrails.com/foo.cgi?something=here&and=here")+ , ("http://www.rubyonrails.com/contact;new",+ autolink "http://www.rubyonrails.com/contact;new")+ , ("http://www.rubyonrails.com/contact;new%20with%20spaces",+ autolink "http://www.rubyonrails.com/contact;new%20with%20spaces")+ , ("http://www.rubyonrails.com/contact;new?with=query&string=params",+ autolink "http://www.rubyonrails.com/contact;new?with=query&string=params")+ , ("http://www.rubyonrails.com/~minam/contact;new?with=query&string=params",+ autolink "http://www.rubyonrails.com/~minam/contact;new?with=query&string=params")+ , ("http://en.wikipedia.org/wiki/Wikipedia:Today%27s_featured_picture_%28animation%29/January_20%2C_2007",+ autolink "http://en.wikipedia.org/wiki/Wikipedia:Today%27s_featured_picture_%28animation%29/January_20%2C_2007")+ , ("http://www.mail-archive.com/rails@lists.rubyonrails.org/",+ autolink "http://www.mail-archive.com/rails@lists.rubyonrails.org/")+ , ("http://www.amazon.com/Testing-Equal-Sign-In-Path/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1198861734&sr=8-1",+ autolink "http://www.amazon.com/Testing-Equal-Sign-In-Path/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1198861734&sr=8-1")+ , ("http://en.wikipedia.org/wiki/Texas_hold%27em",+ autolink "http://en.wikipedia.org/wiki/Texas_hold%27em")+ , ("https://www.google.com/doku.php?id=gps:resource:scs:start",+ autolink "https://www.google.com/doku.php?id=gps:resource:scs:start")+ , ("http://www.rubyonrails.com",+ autolink "http://www.rubyonrails.com")+ , ("http://manuals.ruby-on-rails.com/read/chapter.need_a-period/103#page281",+ autolink "http://manuals.ruby-on-rails.com/read/chapter.need_a-period/103#page281")+ , ("http://foo.example.com/controller/action?parm=value&p2=v2#anchor123",+ autolink "http://foo.example.com/controller/action?parm=value&p2=v2#anchor123")+ , ("http://foo.example.com:3000/controller/action",+ autolink "http://foo.example.com:3000/controller/action")+ , ("http://foo.example.com:3000/controller/action+pack",+ autolink "http://foo.example.com:3000/controller/action+pack")+ , ("http://business.timesonline.co.uk/article/0,,9065-2473189,00.html",+ autolink "http://business.timesonline.co.uk/article/0,,9065-2473189,00.html")+ , ("http://www.mail-archive.com/ruby-talk@ruby-lang.org/",+ autolink "http://www.mail-archive.com/ruby-talk@ruby-lang.org/")+ ]++{-+p_markdown_round_trip :: Block -> Bool+p_markdown_round_trip b = matches d' d''+ where d' = normalize $ Pandoc (Meta [] [] []) [b]+ d'' = normalize+ $ readMarkdown def { readerSmart = True }+ $ writeMarkdown def d'+ matches (Pandoc _ [Plain []]) (Pandoc _ []) = True+ matches (Pandoc _ [Para []]) (Pandoc _ []) = True+ matches (Pandoc _ [Plain xs]) (Pandoc _ [Para xs']) = xs == xs'+ matches x y = x == y+-}++tests :: [Test]+tests = [ testGroup "inline code"+ [ "with attribute" =:+ "`document.write(\"Hello\");`{.javascript}"+ =?> para+ (codeWith ("",["javascript"],[]) "document.write(\"Hello\");")+ , "with attribute space" =:+ "`*` {.haskell .special x=\"7\"}"+ =?> para (codeWith ("",["haskell","special"],[("x","7")]) "*")+ , test (readMarkdown def{ readerExtensions = Set.insert+ Ext_scholarly_markdown $ readerExtensions def })+ "double-backtick is inline math" $+ "what part of ``\\mathbf{x_s}_\\frac{\\omega}{x \\delta}`` don't you understand? Also there's ``(V * \\rho)`` and ``y = Ax`` as well"+ =?> para ( "what part of " <> math "\\mathbf{x_s}_\\frac{\\omega}{x \\delta}" <> " don't you understand? Also there's " <> math "(V * \\rho)" <> " and " <> math "y = Ax" <> " as well")+ , test (readMarkdown def{ readerExtensions = Set.insert+ Ext_scholarly_markdown $ readerExtensions def })+ "double-backtick is inline math except followed by whitespace" $+ "what part of `` \\mathbf{x_s}_\\frac{\\omega}{x \\delta} `` don't you understand?"+ =?> para ( "what part of " <> codeWith ([],[],[]) "\\mathbf{x_s}_\\frac{\\omega}{x \\delta}" <> " don't you understand?" )+ , test (readMarkdown def{ readerExtensions = Set.insert+ Ext_scholarly_markdown $ readerExtensions def })+ "long backticks with Ext_tex_math_double_backtick enabled" $+ "what part of ````\\mathbf{x_s}_\\frac{\\omega}{x \\delta} ```` don't you understand?"+ =?> para ( "what part of " <> codeWith ([],[],[]) "\\mathbf{x_s}_\\frac{\\omega}{x \\delta}" <> " don't you understand?" )+ ]+ , testGroup "emph and strong"+ [ "two strongs in emph" =:+ "***a**b **c**d*" =?> para (emph (strong (str "a") <> str "b" <> space+ <> strong (str "c") <> str "d"))+ , "emph and strong emph alternating" =:+ "*xxx* ***xxx*** xxx\n*xxx* ***xxx*** xxx"+ =?> para (emph "xxx" <> space <> strong (emph "xxx") <>+ space <> "xxx" <> space <>+ emph "xxx" <> space <> strong (emph "xxx") <>+ space <> "xxx")+ , "emph with spaced strong" =:+ "*x **xx** x*"+ =?> para (emph ("x" <> space <> strong "xx" <> space <> "x"))+ , "intraword underscore with opening underscore (#1121)" =:+ "_foot_ball_" =?> para (emph (text "foot_ball"))+ ]+ , testGroup "raw LaTeX"+ [ "in URL" =:+ "\\begin\n" =?> para (text "\\begin")+ ]+ , testGroup "raw HTML"+ [ "nesting (issue #1330)" =:+ "<del>test</del>" =?>+ rawBlock "html" "<del>" <> plain (str "test") <>+ rawBlock "html" "</del>"+ ]+ , "unbalanced brackets" =:+ "[[[[[[[[[[[[[[[hi" =?> para (text "[[[[[[[[[[[[[[[hi")+ , testGroup "backslash escapes"+ [ "in URL" =:+ "[hi](/there\\))"+ =?> para (link "/there)" "" "hi")+ , "in title" =:+ "[hi](/there \"a\\\"a\")"+ =?> para (link "/there" "a\"a" "hi")+ , "in reference link title" =:+ "[hi]\n\n[hi]: /there (a\\)a)"+ =?> para (link "/there" "a)a" "hi")+ , "in reference link URL" =:+ "[hi]\n\n[hi]: /there\\.0"+ =?> para (link "/there.0" "" "hi")+ ]+ , testGroup "bare URIs"+ (map testBareLink bareLinkTests)+ , testGroup "Headers"+ [ "blank line before header" =:+ "\n# Header\n"+ =?> headerWith ("header",[],[]) 1 "Header"+ ]+ , testGroup "smart punctuation"+ [ test markdownSmart "quote before ellipses"+ ("'...hi'"+ =?> para (singleQuoted "…hi"))+ , test markdownSmart "apostrophe before emph"+ ("D'oh! A l'*aide*!"+ =?> para ("D’oh! A l’" <> emph "aide" <> "!"))+ , test markdownSmart "apostrophe in French"+ ("À l'arrivée de la guerre, le thème de l'«impossibilité du socialisme»"+ =?> para "À l’arrivée de la guerre, le thème de l’«impossibilité du socialisme»")+ ]+ , testGroup "footnotes"+ [ "indent followed by newline and flush-left text" =:+ "[^1]\n\n[^1]: my note\n\n \nnot in note\n"+ =?> para (note (para "my note")) <> para "not in note"+ , "indent followed by newline and indented text" =:+ "[^1]\n\n[^1]: my note\n \n in note\n"+ =?> para (note (para "my note" <> para "in note"))+ , "recursive note" =:+ "[^1]\n\n[^1]: See [^1]\n"+ =?> para (note (para "See [^1]"))+ ]+ , testGroup "lhs"+ [ test (readMarkdown def{ readerExtensions = Set.insert+ Ext_literate_haskell $ readerExtensions def })+ "inverse bird tracks and html" $+ "> a\n\n< b\n\n<div>\n"+ =?> codeBlockWith ("",["sourceCode","literate","haskell"],[]) "a"+ <>+ codeBlockWith ("",["sourceCode","haskell"],[]) "b"+ <>+ rawBlock "html" "<div>\n\n"+ ]+-- the round-trip properties frequently fail+-- , testGroup "round trip"+-- [ property "p_markdown_round_trip" p_markdown_round_trip+-- ]+ , testGroup "definition lists"+ [ "no blank space" =:+ "foo1\n : bar\n\nfoo2\n : bar2\n : bar3\n" =?>+ definitionList [ (text "foo1", [plain (text "bar")])+ , (text "foo2", [plain (text "bar2"),+ plain (text "bar3")])+ ]+ , "blank space before first def" =:+ "foo1\n\n : bar\n\nfoo2\n\n : bar2\n : bar3\n" =?>+ definitionList [ (text "foo1", [para (text "bar")])+ , (text "foo2", [para (text "bar2"),+ plain (text "bar3")])+ ]+ , "blank space before second def" =:+ "foo1\n : bar\n\nfoo2\n : bar2\n\n : bar3\n" =?>+ definitionList [ (text "foo1", [plain (text "bar")])+ , (text "foo2", [plain (text "bar2"),+ para (text "bar3")])+ ]+ , "laziness" =:+ "foo1\n : bar\nbaz\n : bar2\n" =?>+ definitionList [ (text "foo1", [plain (text "bar baz"),+ plain (text "bar2")])+ ]+ , "no blank space before first of two paragraphs" =:+ "foo1\n : bar\n\n baz\n" =?>+ definitionList [ (text "foo1", [para (text "bar") <>+ para (text "baz")])+ ]+ ]+ , testGroup "+compact_definition_lists"+ [ test markdownCDL "basic compact list" $+ "foo1\n: bar\n baz\nfoo2\n: bar2\n" =?>+ definitionList [ (text "foo1", [plain (text "bar baz")])+ , (text "foo2", [plain (text "bar2")])+ ]+ ]+ , testGroup "lists"+ [ "issue #1154" =:+ " - <div>\n first div breaks\n </div>\n\n <button>if this button exists</button>\n\n <div>\n with this div too.\n </div>\n"+ =?> bulletList [divWith nullAttr (para $ text "first div breaks") <>+ rawBlock "html" "<button>" <>+ plain (text "if this button exists") <>+ rawBlock "html" "</button>" <>+ divWith nullAttr (para $ text "with this div too.")]+ ]+ ]
@@ -0,0 +1,61 @@+module Tests.Shared (tests) where++import Text.Pandoc.Definition+import Text.Pandoc.Shared+import Test.Framework+import Tests.Helpers+import Tests.Arbitrary()+import Test.Framework.Providers.HUnit+import Test.HUnit ( assertBool, (@?=) )+import Text.Pandoc.Builder+import Data.Monoid+import System.FilePath (joinPath)++tests :: [Test]+tests = [ testGroup "normalize"+ [ property "p_normalize_blocks_rt" p_normalize_blocks_rt+ , property "p_normalize_inlines_rt" p_normalize_inlines_rt+ , property "p_normalize_no_trailing_spaces"+ p_normalize_no_trailing_spaces+ ]+ , testGroup "compactify'DL"+ [ testCase "compactify'DL with empty def" $+ assertBool "compactify'DL"+ (let x = [(str "word", [para (str "def"), mempty])]+ in compactify'DL x == x)+ ]+ , testGroup "collapseFilePath" testCollapse+ ]++p_normalize_blocks_rt :: [Block] -> Bool+p_normalize_blocks_rt bs =+ normalizeBlocks bs == normalizeBlocks (normalizeBlocks bs)++p_normalize_inlines_rt :: [Inline] -> Bool+p_normalize_inlines_rt ils =+ normalizeInlines ils == normalizeInlines (normalizeInlines ils)++p_normalize_no_trailing_spaces :: [Inline] -> Bool+p_normalize_no_trailing_spaces ils = null ils' || last ils' /= Space+ where ils' = normalizeInlines $ ils ++ [Space]++testCollapse :: [Test]+testCollapse = map (testCase "collapse")+ [ (collapseFilePath (joinPath [ ""]) @?= (joinPath [ ""]))+ , (collapseFilePath (joinPath [ ".","foo"]) @?= (joinPath [ "foo"]))+ , (collapseFilePath (joinPath [ ".",".","..","foo"]) @?= (joinPath [ joinPath ["..", "foo"]]))+ , (collapseFilePath (joinPath [ "..","foo"]) @?= (joinPath [ "..","foo"]))+ , (collapseFilePath (joinPath [ "","bar","..","baz"]) @?= (joinPath [ "","baz"]))+ , (collapseFilePath (joinPath [ "","..","baz"]) @?= (joinPath [ "","..","baz"]))+ , (collapseFilePath (joinPath [ ".","foo","..",".","bar","..",".",".","baz"]) @?= (joinPath [ "baz"]))+ , (collapseFilePath (joinPath [ ".",""]) @?= (joinPath [ ""]))+ , (collapseFilePath (joinPath [ ".",".",""]) @?= (joinPath [ ""]))+ , (collapseFilePath (joinPath [ "..",""]) @?= (joinPath [ ".."]))+ , (collapseFilePath (joinPath [ "..",".",""]) @?= (joinPath [ ".."]))+ , (collapseFilePath (joinPath [ ".","..",""]) @?= (joinPath [ ".."]))+ , (collapseFilePath (joinPath [ "..","..",""]) @?= (joinPath [ "..",".."]))+ , (collapseFilePath (joinPath [ "parent","foo","baz","..","bar"]) @?= (joinPath [ "parent","foo","bar"]))+ , (collapseFilePath (joinPath [ "parent","foo","baz","..","..","bar"]) @?= (joinPath [ "parent","bar"]))+ , (collapseFilePath (joinPath [ "parent","foo",".."]) @?= (joinPath [ "parent"]))+ , (collapseFilePath (joinPath [ "","parent","foo","..","..","bar"]) @?= (joinPath [ "","bar"]))+ , (collapseFilePath (joinPath [ "",".","parent","foo"]) @?= (joinPath [ "","parent","foo"]))]
@@ -0,0 +1,47 @@+{-# LANGUAGE ScopedTypeVariables, FlexibleContexts #-}+module Tests.Walk (tests) where++import Text.Pandoc.Definition+import Text.Pandoc.Walk+import Test.Framework+import Tests.Helpers+import Data.Char (toUpper)+import Tests.Arbitrary()+import Data.Generics+import Data.Monoid++tests :: [Test]+tests = [ testGroup "Walk"+ [ property "p_walk inlineTrans" (p_walk inlineTrans)+ , property "p_walk blockTrans" (p_walk blockTrans)+ , property "p_query inlineQuery" (p_query inlineQuery)+ , property "p_query blockQuery" (p_query blockQuery)+ ]+ ]++p_walk :: (Typeable a, Walkable a Pandoc)+ => (a -> a) -> Pandoc -> Bool+p_walk f d = everywhere (mkT f) d == walk f d++p_query :: (Eq a, Typeable a1, Monoid a, Walkable a1 Pandoc)+ => (a1 -> a) -> Pandoc -> Bool+p_query f d = everything mappend (mempty `mkQ` f) d == query f d++inlineTrans :: Inline -> Inline+inlineTrans (Str xs) = Str $ map toUpper xs+inlineTrans (Emph xs) = Strong xs+inlineTrans x = x++blockTrans :: Block -> Block+blockTrans (Plain xs) = Para xs+blockTrans (BlockQuote xs) = Div ("",["special"],[]) xs+blockTrans x = x++inlineQuery :: Inline -> String+inlineQuery (Str xs) = xs+inlineQuery _ = ""++blockQuery :: Block -> [Int]+blockQuery (Header lev _ _) = [lev]+blockQuery _ = []+
@@ -0,0 +1,43 @@+{-# LANGUAGE OverloadedStrings #-}+module Tests.Writers.HTML (tests) where++import Test.Framework+import Text.Pandoc.Builder+import Text.Pandoc+import Tests.Helpers+import Tests.Arbitrary()++html :: (ToString a, ToPandoc a) => a -> String+html = writeHtmlString def{ writerWrapText = False } . toPandoc++{-+ "my test" =: X =?> Y++is shorthand for++ test html "my test" $ X =?> Y++which is in turn shorthand for++ test html "my test" (X,Y)+-}++infix 4 =:+(=:) :: (ToString a, ToPandoc a)+ => String -> (a, String) -> Test+(=:) = test html++tests :: [Test]+tests = [ testGroup "inline code"+ [ "basic" =: code "@&" =?> "<code>@&</code>"+ , "haskell" =: codeWith ("",["haskell"],[]) ">>="+ =?> "<code class=\"haskell\">>>=</code>"+ , "nolanguage" =: codeWith ("",["nolanguage"],[]) ">>="+ =?> "<code class=\"nolanguage\">>>=</code>"+ ]+ , testGroup "images"+ [ "alt with formatting" =:+ image "/url" "title" ("my " <> emph "image")+ =?> "<img src=\"/url\" title=\"title\" alt=\"my image\" />"+ ]+ ]
@@ -0,0 +1,79 @@+{-# LANGUAGE OverloadedStrings #-}+module Tests.Writers.LaTeX (tests) where++import Test.Framework+import Text.Pandoc.Builder+import Text.Pandoc+import Tests.Helpers+import Tests.Arbitrary()++latex :: (ToString a, ToPandoc a) => a -> String+latex = writeLaTeX def{ writerHighlight = True } . toPandoc++latexListing :: (ToString a, ToPandoc a) => a -> String+latexListing = writeLaTeX def{ writerListings = True } . toPandoc++{-+ "my test" =: X =?> Y++is shorthand for++ test latex "my test" $ X =?> Y++which is in turn shorthand for++ test latex "my test" (X,Y)+-}++infix 4 =:+(=:) :: (ToString a, ToPandoc a)+ => String -> (a, String) -> Test+(=:) = test latex++tests :: [Test]+tests = [ testGroup "code blocks"+ [ "in footnotes" =: note (para "hi" <> codeBlock "hi") =?>+ "\\footnote{hi\n\n\\begin{Verbatim}\nhi\n\\end{Verbatim}\n}"+ , test latexListing "identifier" $ codeBlockWith ("id",[],[]) "hi" =?>+ ("\\begin{lstlisting}[label=id]\nhi\n\\end{lstlisting}" :: String)+ , test latexListing "no identifier" $ codeBlock "hi" =?>+ ("\\begin{lstlisting}\nhi\n\\end{lstlisting}" :: String)+ ]+ , testGroup "definition lists"+ [ "with internal link" =: definitionList [(link "#go" "" (str "testing"),+ [plain (text "hi there")])] =?>+ "\\begin{description}\n\\itemsep1pt\\parskip0pt\\parsep0pt\n\\item[{\\hyperref[go]{testing}}]\nhi there\n\\end{description}"+ ]+ , testGroup "math"+ [ "escape |" =: para (math "\\sigma|_{\\{x\\}}") =?>+ "$\\sigma|_{\\{x\\}}$"+ ]+ , testGroup "headers"+ [ "unnumbered header" =:+ headerWith ("foo",["unnumbered"],[]) 1+ (text "Header 1" <> note (plain $ text "note")) =?>+ "\\section*{Header 1\\footnote{note}}\\label{foo}\n\\addcontentsline{toc}{section}{Header 1}\n"+ , "in list item" =:+ bulletList [header 2 (text "foo")] =?>+ "\\begin{itemize}\n\\item ~\n \\subsection{foo}\n\\end{itemize}"+ , "in definition list item" =:+ definitionList [(text "foo", [header 2 (text "bar"),+ para $ text "baz"])] =?>+ "\\begin{description}\n\\item[foo] ~ \n\\subsection{bar}\n\nbaz\n\\end{description}"+ , "containing image" =:+ header 1 (image "imgs/foo.jpg" "" (text "Alt text")) =?>+ "\\section{\\protect\\includegraphics[]{imgs/foo.jpg}}"+ ]+ , testGroup "inline code"+ [ "struck out and highlighted" =:+ strikeout (codeWith ("",["haskell"],[]) "foo" <> space+ <> str "bar") =?>+ "\\sout{\\mbox{\\VERB|\\NormalTok{foo}|} bar}"+ , "struck out and not highlighted" =:+ strikeout (code "foo" <> space+ <> str "bar") =?>+ "\\sout{\\texttt{foo} bar}"+ , "single quotes" =:+ code "dog's" =?> "\\texttt{dog\\textquotesingle{}s}"+ ]+ ]
@@ -0,0 +1,38 @@+{-# LANGUAGE OverloadedStrings #-}+module Tests.Writers.Markdown (tests) where++import Test.Framework+import Text.Pandoc.Builder+import Text.Pandoc+import Tests.Helpers+import Tests.Arbitrary()++markdown :: (ToString a, ToPandoc a) => a -> String+markdown = writeMarkdown def . toPandoc++{-+ "my test" =: X =?> Y++is shorthand for++ test markdown "my test" $ X =?> Y++which is in turn shorthand for++ test markdown "my test" (X,Y)+-}++infix 4 =:+(=:) :: (ToString a, ToPandoc a)+ => String -> (a, String) -> Test+(=:) = test markdown++tests :: [Test]+tests = [ "indented code after list"+ =: (orderedList [ para "one" <> para "two" ] <> codeBlock "test")+ =?> "1. one\n\n two\n\n<!-- -->\n\n test"+ , "list with tight sublist"+ =: bulletList [ plain "foo" <> bulletList [ plain "bar" ],+ plain "baz" ]+ =?> "- foo\n - bar\n- baz\n"+ ]
@@ -0,0 +1,21 @@+module Tests.Writers.Native (tests) where++import Test.Framework+import Text.Pandoc.Builder+import Text.Pandoc+import Tests.Helpers+import Tests.Arbitrary()++p_write_rt :: Pandoc -> Bool+p_write_rt d =+ read (writeNative def{ writerStandalone = True } d) == d++p_write_blocks_rt :: [Block] -> Bool+p_write_blocks_rt bs = length bs > 20 ||+ read (writeNative def (Pandoc nullMeta bs)) ==+ bs++tests :: [Test]+tests = [ property "p_write_rt" p_write_rt+ , property "p_write_blocks_rt" p_write_blocks_rt+ ]
@@ -0,0 +1,21 @@+{-# LANGUAGE OverloadedStrings #-}+module Tests.Writers.Plain (tests) where++import Test.Framework+import Text.Pandoc.Builder+import Text.Pandoc+import Tests.Helpers+import Tests.Arbitrary()+++infix 4 =:+(=:) :: (ToString a, ToPandoc a)+ => String -> (a, String) -> Test+(=:) = test (writePlain def . toPandoc)+++tests :: [Test]+tests = [ "strongly emphasized text to uppercase"+ =: strong "Straße"+ =?> "STRASSE"+ ]
binary file changed (absent → 10119 bytes)
@@ -0,0 +1,1 @@+STUFF INSERTED
binary file changed (absent → 16270 bytes)
@@ -0,0 +1,8 @@+[Header 1 ("lhs-test",[],[]) [Str "lhs",Space,Str "test"]+,Para [Code ("",[],[]) "unsplit",Space,Str "is",Space,Str "an",Space,Str "arrow",Space,Str "that",Space,Str "takes",Space,Str "a",Space,Str "pair",Space,Str "of",Space,Str "values",Space,Str "and",Space,Str "combines",Space,Str "them",Space,Str "to",Space,Str "return",Space,Str "a",Space,Str "single",Space,Str "value:"]+,CodeBlock ("",["sourceCode","literate","haskell"],[]) "unsplit :: (Arrow a) => (b -> c -> d) -> a (b, c) d\nunsplit = arr . uncurry\n -- arr (\\op (x,y) -> x `op` y)"+,Para [Code ("",[],[]) "(***)",Space,Str "combines",Space,Str "two",Space,Str "arrows",Space,Str "into",Space,Str "a",Space,Str "new",Space,Str "arrow",Space,Str "by",Space,Str "running",Space,Str "the",Space,Str "two",Space,Str "arrows",Space,Str "on",Space,Str "a",Space,Str "pair",Space,Str "of",Space,Str "values",Space,Str "(one",Space,Str "arrow",Space,Str "on",Space,Str "the",Space,Str "first",Space,Str "item",Space,Str "of",Space,Str "the",Space,Str "pair",Space,Str "and",Space,Str "one",Space,Str "arrow",Space,Str "on",Space,Str "the",Space,Str "second",Space,Str "item",Space,Str "of",Space,Str "the",Space,Str "pair)."]+,CodeBlock ("",[],[]) "f *** g = first f >>> second g"+,Para [Str "Block",Space,Str "quote:"]+,BlockQuote+ [Para [Str "foo",Space,Str "bar"]]]
@@ -0,0 +1,42 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html xmlns="http://www.w3.org/1999/xhtml">+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+ <title></title>+ <style type="text/css">code{white-space: pre;}</style>+ <style type="text/css">+table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {+ margin: 0; padding: 0; vertical-align: baseline; border: none; }+table.sourceCode { width: 100%; line-height: 100%; }+td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }+td.sourceCode { padding-left: 5px; }+code > span.kw { color: #007020; font-weight: bold; }+code > span.dt { color: #902000; }+code > span.dv { color: #40a070; }+code > span.bn { color: #40a070; }+code > span.fl { color: #40a070; }+code > span.ch { color: #4070a0; }+code > span.st { color: #4070a0; }+code > span.co { color: #60a0b0; font-style: italic; }+code > span.ot { color: #007020; }+code > span.al { color: #ff0000; font-weight: bold; }+code > span.fu { color: #06287e; }+code > span.er { color: #ff0000; font-weight: bold; }+ </style>+</head>+<body>+<h1 id="lhs-test">lhs test</h1>+<p><code>unsplit</code> is an arrow that takes a pair of values and combines them to return a single value:</p>+<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="ot">unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=></span> (b <span class="ot">-></span> c <span class="ot">-></span> d) <span class="ot">-></span> a (b, c) d+unsplit <span class="fu">=</span> arr <span class="fu">.</span> uncurry+ <span class="co">-- arr (\op (x,y) -> x `op` y)</span></code></pre>+<p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a pair of values (one arrow on the first item of the pair and one arrow on the second item of the pair).</p>+<pre><code>f *** g = first f >>> second g</code></pre>+<p>Block quote:</p>+<blockquote>+<p>foo bar</p>+</blockquote>+</body>+</html>
@@ -0,0 +1,42 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html xmlns="http://www.w3.org/1999/xhtml">+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+ <title></title>+ <style type="text/css">code{white-space: pre;}</style>+ <style type="text/css">+table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {+ margin: 0; padding: 0; vertical-align: baseline; border: none; }+table.sourceCode { width: 100%; line-height: 100%; }+td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }+td.sourceCode { padding-left: 5px; }+code > span.kw { color: #007020; font-weight: bold; }+code > span.dt { color: #902000; }+code > span.dv { color: #40a070; }+code > span.bn { color: #40a070; }+code > span.fl { color: #40a070; }+code > span.ch { color: #4070a0; }+code > span.st { color: #4070a0; }+code > span.co { color: #60a0b0; font-style: italic; }+code > span.ot { color: #007020; }+code > span.al { color: #ff0000; font-weight: bold; }+code > span.fu { color: #06287e; }+code > span.er { color: #ff0000; font-weight: bold; }+ </style>+</head>+<body>+<h1 id="lhs-test">lhs test</h1>+<p><code>unsplit</code> is an arrow that takes a pair of values and combines them to return a single value:</p>+<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">> unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=></span> (b <span class="ot">-></span> c <span class="ot">-></span> d) <span class="ot">-></span> a (b, c) d+<span class="ot">></span> unsplit <span class="fu">=</span> arr <span class="fu">.</span> uncurry+<span class="ot">></span> <span class="co">-- arr (\op (x,y) -> x `op` y)</span></code></pre>+<p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a pair of values (one arrow on the first item of the pair and one arrow on the second item of the pair).</p>+<pre><code>f *** g = first f >>> second g</code></pre>+<p>Block quote:</p>+<blockquote>+<p>foo bar</p>+</blockquote>+</body>+</html>
@@ -0,0 +1,100 @@+\documentclass[]{article}+\usepackage{lmodern}+\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}+\else % if luatex or xelatex+ \ifxetex+ \usepackage{mathspec}+ \usepackage{xltxtra,xunicode}+ \else+ \usepackage{fontspec}+ \fi+ \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}+ \newcommand{\euro}{€}+\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+}{}+\usepackage{color}+\usepackage{fancyvrb}+\newcommand{\VerbBar}{|}+\newcommand{\VERB}{\Verb[commandchars=\\\{\}]}+\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}+% Add ',fontsize=\small' for more characters per line+\newenvironment{Shaded}{}{}+\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}+\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}}+\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}+\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}+\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}+\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}+\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}+\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}}+\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}}+\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}+\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}}+\newcommand{\RegionMarkerTok}[1]{{#1}}+\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}+\newcommand{\NormalTok}[1]{{#1}}+\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={},+ pdftitle={},+ colorlinks=true,+ citecolor=blue,+ urlcolor=blue,+ linkcolor=magenta,+ pdfborder={0 0 0}}+\urlstyle{same} % don't use monospace font for urls+\setlength{\parindent}{0pt}+\setlength{\parskip}{6pt plus 2pt minus 1pt}+\setlength{\emergencystretch}{3em} % prevent overfull lines+\setcounter{secnumdepth}{0}++\date{}++\begin{document}++\section{lhs test}\label{lhs-test}++\texttt{unsplit} is an arrow that takes a pair of values and combines them to+return a single value:++\begin{Shaded}+\begin{Highlighting}[]+\OtherTok{unsplit ::} \NormalTok{(}\DataTypeTok{Arrow} \NormalTok{a) }\OtherTok{=>} \NormalTok{(b }\OtherTok{->} \NormalTok{c }\OtherTok{->} \NormalTok{d) }\OtherTok{->} \NormalTok{a (b, c) d}+\NormalTok{unsplit }\FunctionTok{=} \NormalTok{arr }\FunctionTok{.} \NormalTok{uncurry}+ \CommentTok{-- arr (\textbackslash{}op (x,y) -> x `op` y)}+\end{Highlighting}+\end{Shaded}++\texttt{(***)} combines two arrows into a new arrow by running the two arrows+on a pair of values (one arrow on the first item of the pair and one arrow on+the second item of the pair).++\begin{verbatim}+f *** g = first f >>> second g+\end{verbatim}++Block quote:++\begin{quote}+foo bar+\end{quote}++\end{document}
@@ -0,0 +1,79 @@+\documentclass[]{article}+\usepackage{lmodern}+\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}+\else % if luatex or xelatex+ \ifxetex+ \usepackage{mathspec}+ \usepackage{xltxtra,xunicode}+ \else+ \usepackage{fontspec}+ \fi+ \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}+ \newcommand{\euro}{€}+\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+}{}+\usepackage{listings}+\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}+\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={},+ pdftitle={},+ colorlinks=true,+ citecolor=blue,+ urlcolor=blue,+ linkcolor=magenta,+ pdfborder={0 0 0}}+\urlstyle{same} % don't use monospace font for urls+\setlength{\parindent}{0pt}+\setlength{\parskip}{6pt plus 2pt minus 1pt}+\setlength{\emergencystretch}{3em} % prevent overfull lines+\setcounter{secnumdepth}{0}++\date{}++\begin{document}++\section{lhs test}\label{lhs-test}++\texttt{unsplit} is an arrow that takes a pair of values and combines them to+return a single value:++\begin{code}+unsplit :: (Arrow a) => (b -> c -> d) -> a (b, c) d+unsplit = arr . uncurry+ -- arr (\op (x,y) -> x `op` y)+\end{code}++\texttt{(***)} combines two arrows into a new arrow by running the two arrows+on a pair of values (one arrow on the first item of the pair and one arrow on+the second item of the pair).++\begin{verbatim}+f *** g = first f >>> second g+\end{verbatim}++Block quote:++\begin{quote}+foo bar+\end{quote}++\end{document}
@@ -0,0 +1,21 @@+lhs test+========++`unsplit` is an arrow that takes a pair of values and combines them to return+a single value:++``` {.sourceCode .literate .haskell}+unsplit :: (Arrow a) => (b -> c -> d) -> a (b, c) d+unsplit = arr . uncurry+ -- arr (\op (x,y) -> x `op` y)+```++`(***)` combines two arrows into a new arrow by running the two arrows on a+pair of values (one arrow on the first item of the pair and one arrow on the+second item of the pair).++ f *** g = first f >>> second g++Block quote:++> foo bar
@@ -0,0 +1,19 @@+lhs test+========++`unsplit` is an arrow that takes a pair of values and combines them to return+a single value:++> unsplit :: (Arrow a) => (b -> c -> d) -> a (b, c) d+> unsplit = arr . uncurry+> -- arr (\op (x,y) -> x `op` y)++`(***)` combines two arrows into a new arrow by running the two arrows on a+pair of values (one arrow on the first item of the pair and one arrow on the+second item of the pair).++ f *** g = first f >>> second g++Block quote:++ > foo bar
@@ -0,0 +1,8 @@+[Header 1 ("lhs-test",[],[]) [Str "lhs",Space,Str "test"]+,Para [Code ("",[],[]) "unsplit",Space,Str "is",Space,Str "an",Space,Str "arrow",Space,Str "that",Space,Str "takes",Space,Str "a",Space,Str "pair",Space,Str "of",Space,Str "values",Space,Str "and",Space,Str "combines",Space,Str "them",Space,Str "to",Space,Str "return",Space,Str "a",Space,Str "single",Space,Str "value:"]+,CodeBlock ("",["sourceCode","literate","haskell"],[]) "unsplit :: (Arrow a) => (b -> c -> d) -> a (b, c) d\nunsplit = arr . uncurry\n -- arr (\\op (x,y) -> x `op` y)"+,Para [Code ("",[],[]) "(***)",Space,Str "combines",Space,Str "two",Space,Str "arrows",Space,Str "into",Space,Str "a",Space,Str "new",Space,Str "arrow",Space,Str "by",Space,Str "running",Space,Str "the",Space,Str "two",Space,Str "arrows",Space,Str "on",Space,Str "a",Space,Str "pair",Space,Str "of",Space,Str "values",Space,Str "(one",Space,Str "arrow",Space,Str "on",Space,Str "the",Space,Str "first",Space,Str "item",Space,Str "of",Space,Str "the",Space,Str "pair",Space,Str "and",Space,Str "one",Space,Str "arrow",Space,Str "on",Space,Str "the",Space,Str "second",Space,Str "item",Space,Str "of",Space,Str "the",Space,Str "pair)."]+,CodeBlock ("",[],[]) "f *** g = first f >>> second g"+,Para [Str "Block",Space,Str "quote:"]+,BlockQuote+ [Para [Str "foo",Space,Str "bar"]]]
@@ -0,0 +1,17 @@+[Header 1 ("pandoc-with-citeproc-hs",[],[]) [Str "Pandoc",Space,Str "with",Space,Str "citeproc-hs"]+,BulletList+ [[Para [Cite [Citation {citationId = "nonexistent", citationPrefix = [], citationSuffix = [], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[@nonexistent]"]]]+ ,[Para [Cite [Citation {citationId = "nonexistent", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 0, citationHash = 0}] [Str "@nonexistent"]]]+ ,[Para [Cite [Citation {citationId = "item1", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 0, citationHash = 0}] [Str "@item1"],Space,Str "says",Space,Str "blah."]]+ ,[Para [Cite [Citation {citationId = "item1", citationPrefix = [], citationSuffix = [Str "p.",Space,Str "30"], citationMode = AuthorInText, citationNoteNum = 0, citationHash = 0}] [Str "@item1",Space,Str "[p.",Space,Str "30]"],Space,Str "says",Space,Str "blah."]]+ ,[Para [Cite [Citation {citationId = "item1", citationPrefix = [], citationSuffix = [Str "p.",Space,Str "30,",Space,Str "with",Space,Str "suffix"], citationMode = AuthorInText, citationNoteNum = 0, citationHash = 0}] [Str "@item1",Space,Str "[p.",Space,Str "30,",Space,Str "with",Space,Str "suffix]"],Space,Str "says",Space,Str "blah."]]+ ,[Para [Cite [Citation {citationId = "item1", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 0, citationHash = 0},Citation {citationId = "item2", citationPrefix = [], citationSuffix = [Space,Str "p.",Space,Str "30"], citationMode = SuppressAuthor, citationNoteNum = 0, citationHash = 0},Citation {citationId = "\1087\1091\1085\1082\1090\&3", citationPrefix = [Str "see",Space,Str "also"], citationSuffix = [], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "@item1",Space,Str "[-@item2",Space,Str "p.",Space,Str "30;",Space,Str "see",Space,Str "also",Space,Str "@\1087\1091\1085\1082\1090\&3]"],Space,Str "says",Space,Str "blah."]]+ ,[Para [Str "In",Space,Str "a",Space,Str "note.",Note [Para [Cite [Citation {citationId = "\1087\1091\1085\1082\1090\&3", citationPrefix = [], citationSuffix = [Str "p.",Space,Str "12"], citationMode = AuthorInText, citationNoteNum = 0, citationHash = 0}] [Str "@\1087\1091\1085\1082\1090\&3",Space,Str "[p.",Space,Str "12]"],Space,Str "and",Space,Str "a",Space,Str "citation",Space,Str "without",Space,Str "locators",Space,Cite [Citation {citationId = "\1087\1091\1085\1082\1090\&3", citationPrefix = [], citationSuffix = [], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[@\1087\1091\1085\1082\1090\&3]"],Str "."]]]]+ ,[Para [Str "A",Space,Str "citation",Space,Str "group",Space,Cite [Citation {citationId = "item1", citationPrefix = [Str "see"], citationSuffix = [Space,Str "chap.",Space,Str "3"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0},Citation {citationId = "\1087\1091\1085\1082\1090\&3", citationPrefix = [Str "also"], citationSuffix = [Space,Str "p.",Space,Str "34-35"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[see",Space,Str "@item1",Space,Str "chap.",Space,Str "3;",Space,Str "also",Space,Str "@\1087\1091\1085\1082\1090\&3",Space,Str "p.",Space,Str "34-35]"],Str "."]]+ ,[Para [Str "Another",Space,Str "one",Space,Cite [Citation {citationId = "item1", citationPrefix = [Str "see"], citationSuffix = [Space,Str "p.",Space,Str "34-35"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[see",Space,Str "@item1",Space,Str "p.",Space,Str "34-35]"],Str "."]]+ ,[Para [Str "And",Space,Str "another",Space,Str "one",Space,Str "in",Space,Str "a",Space,Str "note.",Note [Para [Str "Some",Space,Str "citations",Space,Cite [Citation {citationId = "item1", citationPrefix = [Str "see"], citationSuffix = [Space,Str "chap.",Space,Str "3"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0},Citation {citationId = "\1087\1091\1085\1082\1090\&3", citationPrefix = [], citationSuffix = [], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0},Citation {citationId = "item2", citationPrefix = [], citationSuffix = [], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[see",Space,Str "@item1",Space,Str "chap.",Space,Str "3;",Space,Str "@\1087\1091\1085\1082\1090\&3;",Space,Str "@item2]"],Str "."]]]]+ ,[Para [Str "Citation",Space,Str "with",Space,Str "a",Space,Str "suffix",Space,Str "and",Space,Str "locator",Space,Cite [Citation {citationId = "item1", citationPrefix = [], citationSuffix = [Space,Str "pp.",Space,Str "33,",Space,Str "35-37,",Space,Str "and",Space,Str "nowhere",Space,Str "else"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[@item1",Space,Str "pp.",Space,Str "33,",Space,Str "35-37,",Space,Str "and",Space,Str "nowhere",Space,Str "else]"],Str "."]]+ ,[Para [Str "Citation",Space,Str "with",Space,Str "suffix",Space,Str "only",Space,Cite [Citation {citationId = "item1", citationPrefix = [], citationSuffix = [Space,Str "and",Space,Str "nowhere",Space,Str "else"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[@item1",Space,Str "and",Space,Str "nowhere",Space,Str "else]"],Str "."]]+ ,[Para [Str "Now",Space,Str "some",Space,Str "modifiers.",Note [Para [Str "Like",Space,Str "a",Space,Str "citation",Space,Str "without",Space,Str "author:",Space,Cite [Citation {citationId = "item1", citationPrefix = [], citationSuffix = [], citationMode = SuppressAuthor, citationNoteNum = 0, citationHash = 0}] [Str "[-@item1]"],Str ",",Space,Str "and",Space,Str "now",Space,Str "Doe",Space,Str "with",Space,Str "a",Space,Str "locator",Space,Cite [Citation {citationId = "item2", citationPrefix = [], citationSuffix = [Space,Str "p.",Space,Str "44"], citationMode = SuppressAuthor, citationNoteNum = 0, citationHash = 0}] [Str "[-@item2",Space,Str "p.",Space,Str "44]"],Str "."]]]]+ ,[Para [Str "With",Space,Str "some",Space,Str "markup",Space,Cite [Citation {citationId = "item1", citationPrefix = [Emph [Str "see"]], citationSuffix = [Space,Str "p.",Space,Strong [Str "32"]], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[*see*",Space,Str "@item1",Space,Str "p.",Space,Str "**32**]"],Str "."]]]+,Header 1 ("references",[],[]) [Str "References"]]
@@ -0,0 +1,39 @@+Pandoc with citeproc-hs+=======================++- [@nonexistent]++- @nonexistent++- @item1 says blah.++- @item1 [p. 30] says blah.++- @item1 [p. 30, with suffix] says blah.++- @item1 [-@item2 p. 30; see also @пункт3] says blah.++- In a note.[^1]++- A citation group [see @item1 chap. 3; also @пункт3 p. 34-35].++- Another one [see @item1 p. 34-35].++- And another one in a note.[^2]++- Citation with a suffix and locator [@item1 pp. 33, 35-37, and nowhere else].++- Citation with suffix only [@item1 and nowhere else].++- Now some modifiers.[^3]++- With some markup [*see* @item1 p. **32**].++References+==========++[^1]: @пункт3 [p. 12] and a citation without locators [@пункт3].++[^2]: Some citations [see @item1 chap. 3; @пункт3; @item2].++[^3]: Like a citation without author: [-@item1], and now Doe with a locator [-@item2 p. 44].
@@ -0,0 +1,154 @@+[Header 1 ("additional-markdown-reader-tests",[],[]) [Str "Additional",Space,Str "markdown",Space,Str "reader",Space,Str "tests"]+,Header 2 ("blank-line-before-url-in-link-reference",[],[]) [Str "Blank",Space,Str "line",Space,Str "before",Space,Str "URL",Space,Str "in",Space,Str "link",Space,Str "reference"]+,Para [Link [Str "foo"] ("/url",""),Space,Str "and",Space,Link [Str "bar"] ("/url","title")]+,Header 2 ("raw-context-environments",[],[]) [Str "Raw",Space,Str "ConTeXt",Space,Str "environments"]+,Plain [RawInline (Format "tex") "\\placeformula "]+,RawBlock (Format "context") "\\startformula\n L_{1} = L_{2}\n \\stopformula"+,RawBlock (Format "context") "\\start[a2]\n\\start[a2]\n\\stop[a2]\n\\stop[a2]"+,Header 2 ("urls-with-spaces-and-punctuation",[],[]) [Str "URLs",Space,Str "with",Space,Str "spaces",Space,Str "and",Space,Str "punctuation"]+,Para [Link [Str "foo"] ("/bar%20and%20baz",""),Space,Link [Str "foo"] ("/bar%20and%20baz",""),Space,Link [Str "foo"] ("/bar%20and%20baz",""),Space,Link [Str "foo"] ("bar%20baz","title")]+,Para [Link [Str "baz"] ("/foo%20foo",""),Space,Link [Str "bam"] ("/foo%20fee",""),Space,Link [Str "bork"] ("/foo/zee%20zob","title")]+,Para [Link [Str "Ward\8217s",Space,Str "method."] ("http://en.wikipedia.org/wiki/Ward's_method","")]+,Header 2 ("horizontal-rules-with-spaces-at-end",[],[]) [Str "Horizontal",Space,Str "rules",Space,Str "with",Space,Str "spaces",Space,Str "at",Space,Str "end"]+,HorizontalRule+,HorizontalRule+,Header 2 ("raw-html-before-header",[],[]) [Str "Raw",Space,Str "HTML",Space,Str "before",Space,Str "header"]+,Para [RawInline (Format "html") "<a>",RawInline (Format "html") "</a>"]+,Header 3 ("my-header",[],[]) [Str "my",Space,Str "header"]+,Header 2 ("in-math",[],[]) [Str "$",Space,Str "in",Space,Str "math"]+,Para [Math InlineMath "\\$2 + \\$3"]+,Para [Str "This",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "math:"]+,Para [Str "$PATH",Space,Str "90",Space,Str "$PATH"]+,Header 2 ("commented-out-list-item",[],[]) [Str "Commented-out",Space,Str "list",Space,Str "item"]+,BulletList+ [[Plain [Str "one",Space,RawInline (Format "html") "<!--\n- two\n-->"]]+ ,[Plain [Str "three"]]]+,Header 2 ("indented-code-at-beginning-of-list",[],[]) [Str "Indented",Space,Str "code",Space,Str "at",Space,Str "beginning",Space,Str "of",Space,Str "list"]+,BulletList+ [[CodeBlock ("",[],[]) "code\ncode"]]+,OrderedList (1,Decimal,Period)+ [[CodeBlock ("",[],[]) "code\ncode"]+ ,[CodeBlock ("",[],[]) "code\ncode"]]+,BulletList+ [[CodeBlock ("",[],[]) "code\ncode"]+ ,[Plain [Str "no",Space,Str "code"]]]+,Header 2 ("backslash-newline",[],[]) [Str "Backslash",Space,Str "newline"]+,Para [Str "hi",LineBreak,Str "there"]+,Header 2 ("code-spans",[],[]) [Str "Code",Space,Str "spans"]+,Para [Code ("",[],[]) "hi\\"]+,Para [Code ("",[],[]) "hi there"]+,Para [Code ("",[],[]) "hi````there"]+,Para [Str "`hi"]+,Para [Str "there`"]+,Header 2 ("multilingual-urls",[],[]) [Str "Multilingual",Space,Str "URLs"]+,Para [Link [Str "http://\27979.com?\27979=\27979"] ("http://\27979.com?\27979=\27979","")]+,Para [Link [Str "foo"] ("/bar/\27979?x=\27979","title")]+,Para [Link [Str "\27979@foo.\27979.baz"] ("mailto:\27979@foo.\27979.baz","")]+,Header 2 ("numbered-examples",[],[]) [Str "Numbered",Space,Str "examples"]+,OrderedList (1,Example,TwoParens)+ [[Plain [Str "First",Space,Str "example."]]+ ,[Plain [Str "Second",Space,Str "example."]]]+,Para [Str "Explanation",Space,Str "of",Space,Str "examples",Space,Str "(2)",Space,Str "and",Space,Str "(3)."]+,OrderedList (3,Example,TwoParens)+ [[Plain [Str "Third",Space,Str "example."]]]+,Header 2 ("macros",[],[]) [Str "Macros"]+,Para [Math InlineMath "{\\langle x,y \\rangle}"]+,Header 2 ("case-insensitive-references",[],[]) [Str "Case-insensitive",Space,Str "references"]+,Para [Link [Str "Fum"] ("/fum","")]+,Para [Link [Str "FUM"] ("/fum","")]+,Para [Link [Str "bat"] ("/bat","")]+,Header 2 ("curly-smart-quotes",[],[]) [Str "Curly",Space,Str "smart",Space,Str "quotes"]+,Para [Quoted DoubleQuote [Str "Hi"]]+,Para [Quoted SingleQuote [Str "Hi"]]+,Header 2 ("consecutive-lists",[],[]) [Str "Consecutive",Space,Str "lists"]+,BulletList+ [[Plain [Str "one"]]+ ,[Plain [Str "two"]]]+,OrderedList (1,Decimal,Period)+ [[Plain [Str "one"]]+ ,[Plain [Str "two"]]]+,OrderedList (1,LowerAlpha,Period)+ [[Plain [Str "one"]]+ ,[Plain [Str "two"]]]+,Header 2 ("implicit-header-references",[],[]) [Str "Implicit",Space,Str "header",Space,Str "references"]+,Header 3 ("my-header-1",[],[]) [Str "My",Space,Str "header"]+,Header 3 ("my-other-header",[],[]) [Str "My",Space,Str "other",Space,Str "header"]+,Para [Str "A",Space,Str "link",Space,Str "to",Space,Link [Str "My",Space,Str "header"] ("#my-header-1",""),Str "."]+,Para [Str "Another",Space,Str "link",Space,Str "to",Space,Link [Str "it"] ("#my-header-1",""),Str "."]+,Para [Str "Link",Space,Str "to",Space,Link [Str "Explicit",Space,Str "header",Space,Str "attributes"] ("#foobar",""),Str "."]+,Para [Str "But",Space,Str "this",Space,Str "is",Space,Str "not",Space,Str "a",Space,Str "link",Space,Str "to",Space,Link [Str "My",Space,Str "other",Space,Str "header"] ("/foo",""),Str ",",Space,Str "since",Space,Str "the",Space,Str "reference",Space,Str "is",Space,Str "defined."]+,Header 2 ("foobar",["baz"],[("key","val")]) [Str "Explicit",Space,Str "header",Space,Str "attributes"]+,Header 2 ("line-blocks",[],[]) [Str "Line",Space,Str "blocks"]+,Para [Str "But",Space,Str "can",Space,Str "a",Space,Str "bee",Space,Str "be",Space,Str "said",Space,Str "to",Space,Str "be",LineBreak,Str "\160\160\160\160or",Space,Str "not",Space,Str "to",Space,Str "be",Space,Str "an",Space,Str "entire",Space,Str "bee,",LineBreak,Str "\160\160\160\160\160\160\160\160when",Space,Str "half",Space,Str "the",Space,Str "bee",Space,Str "is",Space,Str "not",Space,Str "a",Space,Str "bee,",LineBreak,Str "\160\160\160\160\160\160\160\160\160\160\160\160due",Space,Str "to",Space,Str "some",Space,Str "ancient",Space,Str "injury?"]+,Para [Str "Continuation",Space,Str "line",LineBreak,Str "\160\160and",Space,Str "another"]+,Header 2 ("grid-tables",[],[]) [Str "Grid",Space,Str "Tables"]+,Table [] [AlignDefault,AlignDefault,AlignDefault] [0.2638888888888889,0.16666666666666666,0.18055555555555555]+ [[Plain [Str "col",Space,Str "1"]]+ ,[Plain [Str "col",Space,Str "2"]]+ ,[Plain [Str "col",Space,Str "3"]]]+ [[[Para [Str "r1",Space,Str "a",Space,Str "r1",Space,Str "bis"]]+ ,[Para [Str "b",Space,Str "b",Space,Str "2"]]+ ,[Para [Str "c",Space,Str "c",Space,Str "2"]]]+ ,[[Para [Str "r2",Space,Str "d"]]+ ,[Para [Str "e"]]+ ,[Para [Str "f"]]]]+,Para [Str "Headless"]+,Table [] [AlignDefault,AlignDefault,AlignDefault] [0.2638888888888889,0.16666666666666666,0.18055555555555555]+ [[]+ ,[]+ ,[]]+ [[[Para [Str "r1",Space,Str "a",Space,Str "r1",Space,Str "bis"]]+ ,[Para [Str "b",Space,Str "b",Space,Str "2"]]+ ,[Para [Str "c",Space,Str "c",Space,Str "2"]]]+ ,[[Para [Str "r2",Space,Str "d"]]+ ,[Para [Str "e"]]+ ,[Para [Str "f"]]]]+,Para [Str "Spaces",Space,Str "at",Space,Str "ends",Space,Str "of",Space,Str "lines"]+,Table [] [AlignDefault,AlignDefault,AlignDefault] [0.2638888888888889,0.16666666666666666,0.18055555555555555]+ [[]+ ,[]+ ,[]]+ [[[Para [Str "r1",Space,Str "a",Space,Str "r1",Space,Str "bis"]]+ ,[Para [Str "b",Space,Str "b",Space,Str "2"]]+ ,[Para [Str "c",Space,Str "c",Space,Str "2"]]]+ ,[[Para [Str "r2",Space,Str "d"]]+ ,[Para [Str "e"]]+ ,[Para [Str "f"]]]]+,Para [Str "Multiple",Space,Str "blocks",Space,Str "in",Space,Str "a",Space,Str "cell"]+,Table [] [AlignDefault,AlignDefault,AlignDefault] [0.2638888888888889,0.16666666666666666,0.18055555555555555]+ [[]+ ,[]+ ,[]]+ [[[Header 1 ("col-1",[],[]) [Str "col",Space,Str "1"]+ ,Para [Str "col",Space,Str "1"]]+ ,[Header 1 ("col-2",[],[]) [Str "col",Space,Str "2"]+ ,Para [Str "col",Space,Str "2"]]+ ,[Header 1 ("col-3",[],[]) [Str "col",Space,Str "3"]+ ,Para [Str "col",Space,Str "3"]]]+ ,[[Para [Str "r1",Space,Str "a"]+ ,Para [Str "r1",Space,Str "bis"]]+ ,[BulletList+ [[Plain [Str "b"]]+ ,[Plain [Str "b",Space,Str "2"]]+ ,[Plain [Str "b",Space,Str "2"]]]]+ ,[Para [Str "c",Space,Str "c",Space,Str "2",Space,Str "c",Space,Str "2"]]]]+,Para [Str "Empty",Space,Str "cells"]+,Table [] [AlignDefault,AlignDefault] [5.555555555555555e-2,5.555555555555555e-2]+ [[]+ ,[]]+ [[[]+ ,[]]]+,Header 2 ("entities-in-links-and-titles",[],[]) [Str "Entities",Space,Str "in",Space,Str "links",Space,Str "and",Space,Str "titles"]+,Para [Link [Str "link"] ("/\252rl","\246\246!")]+,Para [Link [Str "http://g\246\246gle.com"] ("http://g\246\246gle.com","")]+,Para [Link [Str "me@ex\228mple.com"] ("mailto:me@ex\228mple.com","")]+,Para [Link [Str "foobar"] ("/\252rl","\246\246!")]+,Header 2 ("parentheses-in-urls",[],[]) [Str "Parentheses",Space,Str "in",Space,Str "URLs"]+,Para [Link [Str "link"] ("/hi(there)","")]+,Para [Link [Str "link"] ("/hithere)","")]+,Para [Link [Str "linky"] ("hi_(there_(nested))","")]+,Header 2 ("reference-link-fallbacks",[],[]) [Str "Reference",Space,Str "link",Space,Str "fallbacks"]+,Para [Str "[",Emph [Str "not",Space,Str "a",Space,Str "link"],Str "]",Space,Str "[",Emph [Str "nope"],Str "]\8230"]+,Header 2 ("empty-reference-links",[],[]) [Str "Empty",Space,Str "reference",Space,Str "links"]+,Para [Str "bar"]+,Para [Link [Str "foo2"] ("","")]]
@@ -0,0 +1,267 @@+% Title+ spanning multiple lines+% Author One+ Author Two; Author Three;+ Author Four+ +# Additional markdown reader tests++## Blank line before URL in link reference++[foo] and [bar]++[foo]: + /url++[bar]:+/url+"title"++## Raw ConTeXt environments++\placeformula \startformula+ L_{1} = L_{2}+ \stopformula++\start[a2]+\start[a2]+\stop[a2]+\stop[a2]++## URLs with spaces and punctuation++[foo](/bar and baz)+[foo](/bar+ and baz )+[foo]( /bar and baz )+[foo](bar baz "title" )++[baz][] [bam][] [bork][]++[baz]: /foo foo+[bam]: /foo fee +[bork]: /foo/zee zob (title)++[Ward's method.](http://en.wikipedia.org/wiki/Ward's_method)++## Horizontal rules with spaces at end++* * * * * ++-- - -- -- - ++## Raw HTML before header++<a></a>++### my header++## $ in math++$\$2 + \$3$++This should not be math:++$PATH 90 $PATH++## Commented-out list item++- one+<!--+- two+-->+- three++## Indented code at beginning of list++- code+ code++ 1. code+ code++ 12345678. code+ code++ - code+ code++ - no code++## Backslash newline++hi\+there++## Code spans++`hi\`++`hi+there`++`` hi````there ``++`hi++there`++## Multilingual URLs++<http://测.com?测=测>++[foo](/bar/测?x=测 "title")++<测@foo.测.baz>++## Numbered examples++(@) First example.+(@foo) Second example.++Explanation of examples (@foo) and (@bar).++(@bar) Third example.++## Macros++\newcommand{\tuple}[1]{\langle #1 \rangle}++$\tuple{x,y}$++## Case-insensitive references++[Fum]++[FUM]++[bat]++[fum]: /fum+[BAT]: /bat++## Curly smart quotes++“Hi”++‘Hi’++## Consecutive lists++- one+- two+1. one+2. two++ a. one+ b. two++## Implicit header references++### My header++### My other header++A link to [My header].++Another link to [it][My header].++Link to [Explicit header attributes].++[my other header]: /foo++But this is not a link to [My other header], since the reference is defined.++## Explicit header attributes {#foobar .baz key="val"}++## Line blocks++| But can a bee be said to be+| or not to be an entire bee,+| when half the bee is not a bee,+| due to some ancient injury?+|+| Continuation+ line+| and+ another++## Grid Tables+++------------------+-----------+------------++| col 1 | col 2 | col 3 |++==================+===========+============++| r1 a | b | c |+| r1 bis | b 2 | c 2 |++------------------+-----------+------------++| r2 d | e | f |++------------------+-----------+------------+++Headless+++------------------+-----------+------------++| r1 a | b | c |+| r1 bis | b 2 | c 2 |++------------------+-----------+------------++| r2 d | e | f |++------------------+-----------+------------+++Spaces at ends of lines+++------------------+-----------+------------+ +| r1 a | b | c |+| r1 bis | b 2 | c 2 | ++------------------+-----------+------------++| r2 d | e | f |++------------------+-----------+------------+++Multiple blocks in a cell+++------------------+-----------+------------++| # col 1 | # col 2 | # col 3 |+| col 1 | col 2 | col 3 |++------------------+-----------+------------++| r1 a | - b | c |+| | - b 2 | c 2 |+| r1 bis | - b 2 | c 2 |++------------------+-----------+------------+++Empty cells+++---+---++| | |++---+---+++## Entities in links and titles++[link](/ürl "öö!")++<http://göögle.com>++<me@exämple.com>++[foobar]++[foobar]: /ürl "öö!"++## Parentheses in URLs++[link](/hi(there))++[link](/hithere\))++[linky]++[linky]: hi_(there_(nested))++## Reference link fallbacks++[*not a link*] [*nope*]...++## Empty reference links++[foo2]:++bar++[foo2]
binary file changed (absent → 1046 bytes)
@@ -0,0 +1,78 @@+[Para [Str "Simplest",Space,Str "table",Space,Str "without",Space,Str "caption:"]+,Table [] [AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0]+ [[Plain [Str "Default1"]]+ ,[Plain [Str "Default2"]]+ ,[Plain [Str "Default3"]]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Simple",Space,Str "table",Space,Str "with",Space,Str "caption:"]+,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignRight,AlignLeft,AlignDefault,AlignCenter] [0.0,0.0,0.0,0.0]+ [[Plain [Str "Right"]]+ ,[Plain [Str "Left"]]+ ,[Plain [Str "Default"]]+ ,[Plain [Str "Center"]]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Simple",Space,Str "table",Space,Str "without",Space,Str "caption:"]+,Table [] [AlignRight,AlignLeft,AlignCenter] [0.0,0.0,0.0]+ [[Plain [Str "Right"]]+ ,[Plain [Str "Left"]]+ ,[Plain [Str "Center"]]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Headerless",Space,Str "table",Space,Str "without",Space,Str "caption:"]+,Table [] [AlignRight,AlignLeft,AlignCenter] [0.0,0.0,0.0]+ [[]+ ,[]+ ,[]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Table",Space,Str "without",Space,Str "sides:"]+,Table [] [AlignDefault,AlignRight] [0.0,0.0]+ [[Plain [Str "Fruit"]]+ ,[Plain [Str "Quantity"]]]+ [[[Plain [Str "apple"]]+ ,[Plain [Str "5"]]]+ ,[[Plain [Str "orange"]]+ ,[Plain [Str "17"]]]+ ,[[Plain [Str "pear"]]+ ,[Plain [Str "302"]]]]+,Para [Str "One-column:"]+,Table [] [AlignDefault] [0.0]+ [[Plain [Str "hi"]]]+ [[[Plain [Str "lo"]]]]+,Para [Str "Header-less",Space,Str "one-column:"]+,Table [] [AlignCenter] [0.0]+ [[]]+ [[[Plain [Str "hi"]]]]]
@@ -0,0 +1,52 @@+Simplest table without caption:++| Default1 | Default2 | Default3 | +|----------|----------|----------|+|12|12|12|+|123|123|123|+|1|1|1|++Simple table with caption:++| Right | Left | Default | Center |+| ----: | :--- | ------- | :----: |+| 12 | 12 | 12 | 12 |+| 123 | 123 | 123 | 123 |+| 1 | 1 | 1 | 1 |++ : Demonstration of simple table syntax.++Simple table without caption:++| Right | Left | Center | +|------:|:-----|:------:|+|12|12|12|+|123|123|123|+|1|1|1|+++Headerless table without caption:++|------:|:-----|:------:|+|12|12|12|+|123|123|123|+|1|1|1|++Table without sides:++Fruit |Quantity+------|-------:+apple | 5+orange| 17+pear | 302++One-column:++|hi|+|--|+|lo|++Header-less one-column:++|:-:|+|hi|
@@ -0,0 +1,54 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html xmlns="http://www.w3.org/1999/xhtml">+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+ <meta name="author" content="Sam Smith" />+ <meta name="author" content="Jen Jones" />+ <meta name="date" content="2006-07-15" />+ <title>My S5 Document</title>+ <style type="text/css">code{white-space: pre;}</style>+ <!-- configuration parameters -->+ <meta name="defaultView" content="slideshow" />+ <meta name="controlVis" content="hidden" />+ <!-- style sheet links -->+ <link rel="stylesheet" href="s5/default/slides.css" type="text/css" media="projection" id="slideProj" />+ <link rel="stylesheet" href="s5/default/outline.css" type="text/css" media="screen" id="outlineStyle" />+ <link rel="stylesheet" href="s5/default/print.css" type="text/css" media="print" id="slidePrint" />+ <link rel="stylesheet" href="s5/default/opera.css" type="text/css" media="projection" id="operaFix" />+ <!-- S5 JS -->+ <script src="s5/default/slides.js" type="text/javascript"></script>+</head>+<body>+<div class="layout">+<div id="controls"></div>+<div id="currentSlide"></div>+<div id="header"></div>+<div id="footer">+ <h1>July 15, 2006</h1>+ <h2>My S5 Document</h2>+</div>+</div>+<div class="presentation">+<div class="titleslide slide">+ <h1>My S5 Document</h1>+ <h2>Sam Smith<br/>Jen Jones</h2>+ <h3>July 15, 2006</h3>+</div>+<div id="first-slide" class="slide section level1">+<h1>First slide</h1>+<ul>+<li>first bullet</li>+<li>second bullet</li>+</ul>+</div>+<div id="math" class="slide section level1">+<h1>Math</h1>+<ul>+<li><span class="math">$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</span></li>+</ul>+</div>+</div>+</body>+</html>
@@ -0,0 +1,255 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html xmlns="http://www.w3.org/1999/xhtml">+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+ <meta name="author" content="Sam Smith" />+ <meta name="author" content="Jen Jones" />+ <meta name="date" content="2006-07-15" />+ <title>My S5 Document</title>+ <style type="text/css">code{white-space: pre;}</style>+ <!-- configuration parameters -->+ <meta name="defaultView" content="slideshow" />+ <meta name="controlVis" content="hidden" />+ <!-- style sheet links -->+ <link rel="stylesheet" href="s5/default/slides.css" type="text/css" media="projection" id="slideProj" />+ <link rel="stylesheet" href="s5/default/outline.css" type="text/css" media="screen" id="outlineStyle" />+ <link rel="stylesheet" href="s5/default/print.css" type="text/css" media="print" id="slidePrint" />+ <link rel="stylesheet" href="s5/default/opera.css" type="text/css" media="projection" id="operaFix" />+ <!-- S5 JS -->+ <script src="s5/default/slides.js" type="text/javascript"></script>+ <script type="text/javascript">/*<![CDATA[*/+ /*+ LaTeXMathML.js from http://math.etsu.edu/LaTeXMathML/+ Adapted by Jeff Knisely and Douglas Woodall from ASCIIMathML.js v. 1.4.7,+ (c) 2005 Peter Jipsen http://www.chapman.edu/~jipsen.+ Released under the GNU General Public License version 2 or later.+ See the GNU General Public License (at http://www.gnu.org/copyleft/gpl.html)+ for more details.+ */+ var checkForMathML=true;var notifyIfNoMathML=true;var alertIfNoMathML=false;var mathcolor="";var mathfontfamily="";var showasciiformulaonhover=true;var isIE=document.createElementNS==null;if(document.getElementById==null)+ alert("This webpage requires a recent browser such as \nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer")+ function AMcreateElementXHTML(t){if(isIE)return document.createElement(t);else return document.createElementNS("http://www.w3.org/1999/xhtml",t);}+ function AMnoMathMLNote(){var nd=AMcreateElementXHTML("h3");nd.setAttribute("align","center")+ nd.appendChild(AMcreateElementXHTML("p"));nd.appendChild(document.createTextNode("To view the "));var an=AMcreateElementXHTML("a");an.appendChild(document.createTextNode("LaTeXMathML"));an.setAttribute("href","http://www.maths.nott.ac.uk/personal/drw/lm.html");nd.appendChild(an);nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+"));an=AMcreateElementXHTML("a");an.appendChild(document.createTextNode("MathPlayer"));an.setAttribute("href","http://www.dessci.com/en/products/mathplayer/download.htm");nd.appendChild(an);nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox"));nd.appendChild(AMcreateElementXHTML("p"));return nd;}+ function AMisMathMLavailable(){if(navigator.appName.slice(0,8)=="Netscape")+ if(navigator.appVersion.slice(0,1)>="5")return null;else return AMnoMathMLNote();else if(navigator.appName.slice(0,9)=="Microsoft")+ try{var ActiveX=new ActiveXObject("MathPlayer.Factory.1");return null;}catch(e){return AMnoMathMLNote();}+ else return AMnoMathMLNote();}+ var AMcal=[0xEF35,0x212C,0xEF36,0xEF37,0x2130,0x2131,0xEF38,0x210B,0x2110,0xEF39,0xEF3A,0x2112,0x2133,0xEF3B,0xEF3C,0xEF3D,0xEF3E,0x211B,0xEF3F,0xEF40,0xEF41,0xEF42,0xEF43,0xEF44,0xEF45,0xEF46];var AMfrk=[0xEF5D,0xEF5E,0x212D,0xEF5F,0xEF60,0xEF61,0xEF62,0x210C,0x2111,0xEF63,0xEF64,0xEF65,0xEF66,0xEF67,0xEF68,0xEF69,0xEF6A,0x211C,0xEF6B,0xEF6C,0xEF6D,0xEF6E,0xEF6F,0xEF70,0xEF71,0x2128];var AMbbb=[0xEF8C,0xEF8D,0x2102,0xEF8E,0xEF8F,0xEF90,0xEF91,0x210D,0xEF92,0xEF93,0xEF94,0xEF95,0xEF96,0x2115,0xEF97,0x2119,0x211A,0x211D,0xEF98,0xEF99,0xEF9A,0xEF9B,0xEF9C,0xEF9D,0xEF9E,0x2124];var CONST=0,UNARY=1,BINARY=2,INFIX=3,LEFTBRACKET=4,RIGHTBRACKET=5,SPACE=6,UNDEROVER=7,DEFINITION=8,TEXT=9,BIG=10,LONG=11,STRETCHY=12,MATRIX=13;var AMsqrt={input:"\\sqrt",tag:"msqrt",output:"sqrt",ttype:UNARY},AMroot={input:"\\root",tag:"mroot",output:"root",ttype:BINARY},AMfrac={input:"\\frac",tag:"mfrac",output:"/",ttype:BINARY},AMover={input:"\\stackrel",tag:"mover",output:"stackrel",ttype:BINARY},AMatop={input:"\\atop",tag:"mfrac",output:"",ttype:INFIX},AMchoose={input:"\\choose",tag:"mfrac",output:"",ttype:INFIX},AMsub={input:"_",tag:"msub",output:"_",ttype:INFIX},AMsup={input:"^",tag:"msup",output:"^",ttype:INFIX},AMtext={input:"\\mathrm",tag:"mtext",output:"text",ttype:TEXT},AMmbox={input:"\\mbox",tag:"mtext",output:"mbox",ttype:TEXT};var AMsymbols=[{input:"\\alpha",tag:"mi",output:"\u03B1",ttype:CONST},{input:"\\beta",tag:"mi",output:"\u03B2",ttype:CONST},{input:"\\gamma",tag:"mi",output:"\u03B3",ttype:CONST},{input:"\\delta",tag:"mi",output:"\u03B4",ttype:CONST},{input:"\\epsilon",tag:"mi",output:"\u03B5",ttype:CONST},{input:"\\varepsilon",tag:"mi",output:"\u025B",ttype:CONST},{input:"\\zeta",tag:"mi",output:"\u03B6",ttype:CONST},{input:"\\eta",tag:"mi",output:"\u03B7",ttype:CONST},{input:"\\theta",tag:"mi",output:"\u03B8",ttype:CONST},{input:"\\vartheta",tag:"mi",output:"\u03D1",ttype:CONST},{input:"\\iota",tag:"mi",output:"\u03B9",ttype:CONST},{input:"\\kappa",tag:"mi",output:"\u03BA",ttype:CONST},{input:"\\lambda",tag:"mi",output:"\u03BB",ttype:CONST},{input:"\\mu",tag:"mi",output:"\u03BC",ttype:CONST},{input:"\\nu",tag:"mi",output:"\u03BD",ttype:CONST},{input:"\\xi",tag:"mi",output:"\u03BE",ttype:CONST},{input:"\\pi",tag:"mi",output:"\u03C0",ttype:CONST},{input:"\\varpi",tag:"mi",output:"\u03D6",ttype:CONST},{input:"\\rho",tag:"mi",output:"\u03C1",ttype:CONST},{input:"\\varrho",tag:"mi",output:"\u03F1",ttype:CONST},{input:"\\varsigma",tag:"mi",output:"\u03C2",ttype:CONST},{input:"\\sigma",tag:"mi",output:"\u03C3",ttype:CONST},{input:"\\tau",tag:"mi",output:"\u03C4",ttype:CONST},{input:"\\upsilon",tag:"mi",output:"\u03C5",ttype:CONST},{input:"\\phi",tag:"mi",output:"\u03C6",ttype:CONST},{input:"\\varphi",tag:"mi",output:"\u03D5",ttype:CONST},{input:"\\chi",tag:"mi",output:"\u03C7",ttype:CONST},{input:"\\psi",tag:"mi",output:"\u03C8",ttype:CONST},{input:"\\omega",tag:"mi",output:"\u03C9",ttype:CONST},{input:"\\Gamma",tag:"mo",output:"\u0393",ttype:CONST},{input:"\\Delta",tag:"mo",output:"\u0394",ttype:CONST},{input:"\\Theta",tag:"mo",output:"\u0398",ttype:CONST},{input:"\\Lambda",tag:"mo",output:"\u039B",ttype:CONST},{input:"\\Xi",tag:"mo",output:"\u039E",ttype:CONST},{input:"\\Pi",tag:"mo",output:"\u03A0",ttype:CONST},{input:"\\Sigma",tag:"mo",output:"\u03A3",ttype:CONST},{input:"\\Upsilon",tag:"mo",output:"\u03A5",ttype:CONST},{input:"\\Phi",tag:"mo",output:"\u03A6",ttype:CONST},{input:"\\Psi",tag:"mo",output:"\u03A8",ttype:CONST},{input:"\\Omega",tag:"mo",output:"\u03A9",ttype:CONST},{input:"\\frac12",tag:"mo",output:"\u00BD",ttype:CONST},{input:"\\frac14",tag:"mo",output:"\u00BC",ttype:CONST},{input:"\\frac34",tag:"mo",output:"\u00BE",ttype:CONST},{input:"\\frac13",tag:"mo",output:"\u2153",ttype:CONST},{input:"\\frac23",tag:"mo",output:"\u2154",ttype:CONST},{input:"\\frac15",tag:"mo",output:"\u2155",ttype:CONST},{input:"\\frac25",tag:"mo",output:"\u2156",ttype:CONST},{input:"\\frac35",tag:"mo",output:"\u2157",ttype:CONST},{input:"\\frac45",tag:"mo",output:"\u2158",ttype:CONST},{input:"\\frac16",tag:"mo",output:"\u2159",ttype:CONST},{input:"\\frac56",tag:"mo",output:"\u215A",ttype:CONST},{input:"\\frac18",tag:"mo",output:"\u215B",ttype:CONST},{input:"\\frac38",tag:"mo",output:"\u215C",ttype:CONST},{input:"\\frac58",tag:"mo",output:"\u215D",ttype:CONST},{input:"\\frac78",tag:"mo",output:"\u215E",ttype:CONST},{input:"\\pm",tag:"mo",output:"\u00B1",ttype:CONST},{input:"\\mp",tag:"mo",output:"\u2213",ttype:CONST},{input:"\\triangleleft",tag:"mo",output:"\u22B2",ttype:CONST},{input:"\\triangleright",tag:"mo",output:"\u22B3",ttype:CONST},{input:"\\cdot",tag:"mo",output:"\u22C5",ttype:CONST},{input:"\\star",tag:"mo",output:"\u22C6",ttype:CONST},{input:"\\ast",tag:"mo",output:"\u002A",ttype:CONST},{input:"\\times",tag:"mo",output:"\u00D7",ttype:CONST},{input:"\\div",tag:"mo",output:"\u00F7",ttype:CONST},{input:"\\circ",tag:"mo",output:"\u2218",ttype:CONST},{input:"\\bullet",tag:"mo",output:"\u2022",ttype:CONST},{input:"\\oplus",tag:"mo",output:"\u2295",ttype:CONST},{input:"\\ominus",tag:"mo",output:"\u2296",ttype:CONST},{input:"\\otimes",tag:"mo",output:"\u2297",ttype:CONST},{input:"\\bigcirc",tag:"mo",output:"\u25CB",ttype:CONST},{input:"\\oslash",tag:"mo",output:"\u2298",ttype:CONST},{input:"\\odot",tag:"mo",output:"\u2299",ttype:CONST},{input:"\\land",tag:"mo",output:"\u2227",ttype:CONST},{input:"\\wedge",tag:"mo",output:"\u2227",ttype:CONST},{input:"\\lor",tag:"mo",output:"\u2228",ttype:CONST},{input:"\\vee",tag:"mo",output:"\u2228",ttype:CONST},{input:"\\cap",tag:"mo",output:"\u2229",ttype:CONST},{input:"\\cup",tag:"mo",output:"\u222A",ttype:CONST},{input:"\\sqcap",tag:"mo",output:"\u2293",ttype:CONST},{input:"\\sqcup",tag:"mo",output:"\u2294",ttype:CONST},{input:"\\uplus",tag:"mo",output:"\u228E",ttype:CONST},{input:"\\amalg",tag:"mo",output:"\u2210",ttype:CONST},{input:"\\bigtriangleup",tag:"mo",output:"\u25B3",ttype:CONST},{input:"\\bigtriangledown",tag:"mo",output:"\u25BD",ttype:CONST},{input:"\\dag",tag:"mo",output:"\u2020",ttype:CONST},{input:"\\dagger",tag:"mo",output:"\u2020",ttype:CONST},{input:"\\ddag",tag:"mo",output:"\u2021",ttype:CONST},{input:"\\ddagger",tag:"mo",output:"\u2021",ttype:CONST},{input:"\\lhd",tag:"mo",output:"\u22B2",ttype:CONST},{input:"\\rhd",tag:"mo",output:"\u22B3",ttype:CONST},{input:"\\unlhd",tag:"mo",output:"\u22B4",ttype:CONST},{input:"\\unrhd",tag:"mo",output:"\u22B5",ttype:CONST},{input:"\\sum",tag:"mo",output:"\u2211",ttype:UNDEROVER},{input:"\\prod",tag:"mo",output:"\u220F",ttype:UNDEROVER},{input:"\\bigcap",tag:"mo",output:"\u22C2",ttype:UNDEROVER},{input:"\\bigcup",tag:"mo",output:"\u22C3",ttype:UNDEROVER},{input:"\\bigwedge",tag:"mo",output:"\u22C0",ttype:UNDEROVER},{input:"\\bigvee",tag:"mo",output:"\u22C1",ttype:UNDEROVER},{input:"\\bigsqcap",tag:"mo",output:"\u2A05",ttype:UNDEROVER},{input:"\\bigsqcup",tag:"mo",output:"\u2A06",ttype:UNDEROVER},{input:"\\coprod",tag:"mo",output:"\u2210",ttype:UNDEROVER},{input:"\\bigoplus",tag:"mo",output:"\u2A01",ttype:UNDEROVER},{input:"\\bigotimes",tag:"mo",output:"\u2A02",ttype:UNDEROVER},{input:"\\bigodot",tag:"mo",output:"\u2A00",ttype:UNDEROVER},{input:"\\biguplus",tag:"mo",output:"\u2A04",ttype:UNDEROVER},{input:"\\int",tag:"mo",output:"\u222B",ttype:CONST},{input:"\\oint",tag:"mo",output:"\u222E",ttype:CONST},{input:":=",tag:"mo",output:":=",ttype:CONST},{input:"\\lt",tag:"mo",output:"<",ttype:CONST},{input:"\\gt",tag:"mo",output:">",ttype:CONST},{input:"\\ne",tag:"mo",output:"\u2260",ttype:CONST},{input:"\\neq",tag:"mo",output:"\u2260",ttype:CONST},{input:"\\le",tag:"mo",output:"\u2264",ttype:CONST},{input:"\\leq",tag:"mo",output:"\u2264",ttype:CONST},{input:"\\leqslant",tag:"mo",output:"\u2264",ttype:CONST},{input:"\\ge",tag:"mo",output:"\u2265",ttype:CONST},{input:"\\geq",tag:"mo",output:"\u2265",ttype:CONST},{input:"\\geqslant",tag:"mo",output:"\u2265",ttype:CONST},{input:"\\equiv",tag:"mo",output:"\u2261",ttype:CONST},{input:"\\ll",tag:"mo",output:"\u226A",ttype:CONST},{input:"\\gg",tag:"mo",output:"\u226B",ttype:CONST},{input:"\\doteq",tag:"mo",output:"\u2250",ttype:CONST},{input:"\\prec",tag:"mo",output:"\u227A",ttype:CONST},{input:"\\succ",tag:"mo",output:"\u227B",ttype:CONST},{input:"\\preceq",tag:"mo",output:"\u227C",ttype:CONST},{input:"\\succeq",tag:"mo",output:"\u227D",ttype:CONST},{input:"\\subset",tag:"mo",output:"\u2282",ttype:CONST},{input:"\\supset",tag:"mo",output:"\u2283",ttype:CONST},{input:"\\subseteq",tag:"mo",output:"\u2286",ttype:CONST},{input:"\\supseteq",tag:"mo",output:"\u2287",ttype:CONST},{input:"\\sqsubset",tag:"mo",output:"\u228F",ttype:CONST},{input:"\\sqsupset",tag:"mo",output:"\u2290",ttype:CONST},{input:"\\sqsubseteq",tag:"mo",output:"\u2291",ttype:CONST},{input:"\\sqsupseteq",tag:"mo",output:"\u2292",ttype:CONST},{input:"\\sim",tag:"mo",output:"\u223C",ttype:CONST},{input:"\\simeq",tag:"mo",output:"\u2243",ttype:CONST},{input:"\\approx",tag:"mo",output:"\u2248",ttype:CONST},{input:"\\cong",tag:"mo",output:"\u2245",ttype:CONST},{input:"\\Join",tag:"mo",output:"\u22C8",ttype:CONST},{input:"\\bowtie",tag:"mo",output:"\u22C8",ttype:CONST},{input:"\\in",tag:"mo",output:"\u2208",ttype:CONST},{input:"\\ni",tag:"mo",output:"\u220B",ttype:CONST},{input:"\\owns",tag:"mo",output:"\u220B",ttype:CONST},{input:"\\propto",tag:"mo",output:"\u221D",ttype:CONST},{input:"\\vdash",tag:"mo",output:"\u22A2",ttype:CONST},{input:"\\dashv",tag:"mo",output:"\u22A3",ttype:CONST},{input:"\\models",tag:"mo",output:"\u22A8",ttype:CONST},{input:"\\perp",tag:"mo",output:"\u22A5",ttype:CONST},{input:"\\smile",tag:"mo",output:"\u2323",ttype:CONST},{input:"\\frown",tag:"mo",output:"\u2322",ttype:CONST},{input:"\\asymp",tag:"mo",output:"\u224D",ttype:CONST},{input:"\\notin",tag:"mo",output:"\u2209",ttype:CONST},{input:"\\begin{eqnarray}",output:"X",ttype:MATRIX,invisible:true},{input:"\\begin{array}",output:"X",ttype:MATRIX,invisible:true},{input:"\\\\",output:"}&{",ttype:DEFINITION},{input:"\\end{eqnarray}",output:"}}",ttype:DEFINITION},{input:"\\end{array}",output:"}}",ttype:DEFINITION},{input:"\\big",tag:"mo",output:"X",atval:"1.2",ieval:"2.2",ttype:BIG},{input:"\\Big",tag:"mo",output:"X",atval:"1.6",ieval:"2.6",ttype:BIG},{input:"\\bigg",tag:"mo",output:"X",atval:"2.2",ieval:"3.2",ttype:BIG},{input:"\\Bigg",tag:"mo",output:"X",atval:"2.9",ieval:"3.9",ttype:BIG},{input:"\\left",tag:"mo",output:"X",ttype:LEFTBRACKET},{input:"\\right",tag:"mo",output:"X",ttype:RIGHTBRACKET},{input:"{",output:"{",ttype:LEFTBRACKET,invisible:true},{input:"}",output:"}",ttype:RIGHTBRACKET,invisible:true},{input:"(",tag:"mo",output:"(",atval:"1",ttype:STRETCHY},{input:"[",tag:"mo",output:"[",atval:"1",ttype:STRETCHY},{input:"\\lbrack",tag:"mo",output:"[",atval:"1",ttype:STRETCHY},{input:"\\{",tag:"mo",output:"{",atval:"1",ttype:STRETCHY},{input:"\\lbrace",tag:"mo",output:"{",atval:"1",ttype:STRETCHY},{input:"\\langle",tag:"mo",output:"\u2329",atval:"1",ttype:STRETCHY},{input:"\\lfloor",tag:"mo",output:"\u230A",atval:"1",ttype:STRETCHY},{input:"\\lceil",tag:"mo",output:"\u2308",atval:"1",ttype:STRETCHY},{input:")",tag:"mo",output:")",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"]",tag:"mo",output:"]",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\rbrack",tag:"mo",output:"]",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\}",tag:"mo",output:"}",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\rbrace",tag:"mo",output:"}",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\rangle",tag:"mo",output:"\u232A",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\rfloor",tag:"mo",output:"\u230B",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"\\rceil",tag:"mo",output:"\u2309",rtag:"mi",atval:"1",ttype:STRETCHY},{input:"|",tag:"mo",output:"\u2223",atval:"1",ttype:STRETCHY},{input:"\\|",tag:"mo",output:"\u2225",atval:"1",ttype:STRETCHY},{input:"\\vert",tag:"mo",output:"\u2223",atval:"1",ttype:STRETCHY},{input:"\\Vert",tag:"mo",output:"\u2225",atval:"1",ttype:STRETCHY},{input:"\\mid",tag:"mo",output:"\u2223",atval:"1",ttype:STRETCHY},{input:"\\parallel",tag:"mo",output:"\u2225",atval:"1",ttype:STRETCHY},{input:"/",tag:"mo",output:"/",atval:"1.01",ttype:STRETCHY},{input:"\\backslash",tag:"mo",output:"\u2216",atval:"1",ttype:STRETCHY},{input:"\\setminus",tag:"mo",output:"\\",ttype:CONST},{input:"\\!",tag:"mspace",atname:"width",atval:"-0.167em",ttype:SPACE},{input:"\\,",tag:"mspace",atname:"width",atval:"0.167em",ttype:SPACE},{input:"\\>",tag:"mspace",atname:"width",atval:"0.222em",ttype:SPACE},{input:"\\:",tag:"mspace",atname:"width",atval:"0.222em",ttype:SPACE},{input:"\\;",tag:"mspace",atname:"width",atval:"0.278em",ttype:SPACE},{input:"~",tag:"mspace",atname:"width",atval:"0.333em",ttype:SPACE},{input:"\\quad",tag:"mspace",atname:"width",atval:"1em",ttype:SPACE},{input:"\\qquad",tag:"mspace",atname:"width",atval:"2em",ttype:SPACE},{input:"\\prime",tag:"mo",output:"\u2032",ttype:CONST},{input:"'",tag:"mo",output:"\u02B9",ttype:CONST},{input:"''",tag:"mo",output:"\u02BA",ttype:CONST},{input:"'''",tag:"mo",output:"\u2034",ttype:CONST},{input:"''''",tag:"mo",output:"\u2057",ttype:CONST},{input:"\\ldots",tag:"mo",output:"\u2026",ttype:CONST},{input:"\\cdots",tag:"mo",output:"\u22EF",ttype:CONST},{input:"\\vdots",tag:"mo",output:"\u22EE",ttype:CONST},{input:"\\ddots",tag:"mo",output:"\u22F1",ttype:CONST},{input:"\\forall",tag:"mo",output:"\u2200",ttype:CONST},{input:"\\exists",tag:"mo",output:"\u2203",ttype:CONST},{input:"\\Re",tag:"mo",output:"\u211C",ttype:CONST},{input:"\\Im",tag:"mo",output:"\u2111",ttype:CONST},{input:"\\aleph",tag:"mo",output:"\u2135",ttype:CONST},{input:"\\hbar",tag:"mo",output:"\u210F",ttype:CONST},{input:"\\ell",tag:"mo",output:"\u2113",ttype:CONST},{input:"\\wp",tag:"mo",output:"\u2118",ttype:CONST},{input:"\\emptyset",tag:"mo",output:"\u2205",ttype:CONST},{input:"\\infty",tag:"mo",output:"\u221E",ttype:CONST},{input:"\\surd",tag:"mo",output:"\\sqrt{}",ttype:DEFINITION},{input:"\\partial",tag:"mo",output:"\u2202",ttype:CONST},{input:"\\nabla",tag:"mo",output:"\u2207",ttype:CONST},{input:"\\triangle",tag:"mo",output:"\u25B3",ttype:CONST},{input:"\\therefore",tag:"mo",output:"\u2234",ttype:CONST},{input:"\\angle",tag:"mo",output:"\u2220",ttype:CONST},{input:"\\diamond",tag:"mo",output:"\u22C4",ttype:CONST},{input:"\\Diamond",tag:"mo",output:"\u25C7",ttype:CONST},{input:"\\neg",tag:"mo",output:"\u00AC",ttype:CONST},{input:"\\lnot",tag:"mo",output:"\u00AC",ttype:CONST},{input:"\\bot",tag:"mo",output:"\u22A5",ttype:CONST},{input:"\\top",tag:"mo",output:"\u22A4",ttype:CONST},{input:"\\square",tag:"mo",output:"\u25AB",ttype:CONST},{input:"\\Box",tag:"mo",output:"\u25A1",ttype:CONST},{input:"\\wr",tag:"mo",output:"\u2240",ttype:CONST},{input:"\\arccos",tag:"mi",output:"arccos",ttype:UNARY,func:true},{input:"\\arcsin",tag:"mi",output:"arcsin",ttype:UNARY,func:true},{input:"\\arctan",tag:"mi",output:"arctan",ttype:UNARY,func:true},{input:"\\arg",tag:"mi",output:"arg",ttype:UNARY,func:true},{input:"\\cos",tag:"mi",output:"cos",ttype:UNARY,func:true},{input:"\\cosh",tag:"mi",output:"cosh",ttype:UNARY,func:true},{input:"\\cot",tag:"mi",output:"cot",ttype:UNARY,func:true},{input:"\\coth",tag:"mi",output:"coth",ttype:UNARY,func:true},{input:"\\csc",tag:"mi",output:"csc",ttype:UNARY,func:true},{input:"\\deg",tag:"mi",output:"deg",ttype:UNARY,func:true},{input:"\\det",tag:"mi",output:"det",ttype:UNARY,func:true},{input:"\\dim",tag:"mi",output:"dim",ttype:UNARY,func:true},{input:"\\exp",tag:"mi",output:"exp",ttype:UNARY,func:true},{input:"\\gcd",tag:"mi",output:"gcd",ttype:UNARY,func:true},{input:"\\hom",tag:"mi",output:"hom",ttype:UNARY,func:true},{input:"\\inf",tag:"mo",output:"inf",ttype:UNDEROVER},{input:"\\ker",tag:"mi",output:"ker",ttype:UNARY,func:true},{input:"\\lg",tag:"mi",output:"lg",ttype:UNARY,func:true},{input:"\\lim",tag:"mo",output:"lim",ttype:UNDEROVER},{input:"\\liminf",tag:"mo",output:"liminf",ttype:UNDEROVER},{input:"\\limsup",tag:"mo",output:"limsup",ttype:UNDEROVER},{input:"\\ln",tag:"mi",output:"ln",ttype:UNARY,func:true},{input:"\\log",tag:"mi",output:"log",ttype:UNARY,func:true},{input:"\\max",tag:"mo",output:"max",ttype:UNDEROVER},{input:"\\min",tag:"mo",output:"min",ttype:UNDEROVER},{input:"\\Pr",tag:"mi",output:"Pr",ttype:UNARY,func:true},{input:"\\sec",tag:"mi",output:"sec",ttype:UNARY,func:true},{input:"\\sin",tag:"mi",output:"sin",ttype:UNARY,func:true},{input:"\\sinh",tag:"mi",output:"sinh",ttype:UNARY,func:true},{input:"\\sup",tag:"mo",output:"sup",ttype:UNDEROVER},{input:"\\tan",tag:"mi",output:"tan",ttype:UNARY,func:true},{input:"\\tanh",tag:"mi",output:"tanh",ttype:UNARY,func:true},{input:"\\gets",tag:"mo",output:"\u2190",ttype:CONST},{input:"\\leftarrow",tag:"mo",output:"\u2190",ttype:CONST},{input:"\\to",tag:"mo",output:"\u2192",ttype:CONST},{input:"\\rightarrow",tag:"mo",output:"\u2192",ttype:CONST},{input:"\\leftrightarrow",tag:"mo",output:"\u2194",ttype:CONST},{input:"\\uparrow",tag:"mo",output:"\u2191",ttype:CONST},{input:"\\downarrow",tag:"mo",output:"\u2193",ttype:CONST},{input:"\\updownarrow",tag:"mo",output:"\u2195",ttype:CONST},{input:"\\Leftarrow",tag:"mo",output:"\u21D0",ttype:CONST},{input:"\\Rightarrow",tag:"mo",output:"\u21D2",ttype:CONST},{input:"\\Leftrightarrow",tag:"mo",output:"\u21D4",ttype:CONST},{input:"\\iff",tag:"mo",output:"~\\Longleftrightarrow~",ttype:DEFINITION},{input:"\\Uparrow",tag:"mo",output:"\u21D1",ttype:CONST},{input:"\\Downarrow",tag:"mo",output:"\u21D3",ttype:CONST},{input:"\\Updownarrow",tag:"mo",output:"\u21D5",ttype:CONST},{input:"\\mapsto",tag:"mo",output:"\u21A6",ttype:CONST},{input:"\\longleftarrow",tag:"mo",output:"\u2190",ttype:LONG},{input:"\\longrightarrow",tag:"mo",output:"\u2192",ttype:LONG},{input:"\\longleftrightarrow",tag:"mo",output:"\u2194",ttype:LONG},{input:"\\Longleftarrow",tag:"mo",output:"\u21D0",ttype:LONG},{input:"\\Longrightarrow",tag:"mo",output:"\u21D2",ttype:LONG},{input:"\\Longleftrightarrow",tag:"mo",output:"\u21D4",ttype:LONG},{input:"\\longmapsto",tag:"mo",output:"\u21A6",ttype:CONST},AMsqrt,AMroot,AMfrac,AMover,AMsub,AMsup,AMtext,AMmbox,AMatop,AMchoose,{input:"\\acute",tag:"mover",output:"\u00B4",ttype:UNARY,acc:true},{input:"\\grave",tag:"mover",output:"\u0060",ttype:UNARY,acc:true},{input:"\\breve",tag:"mover",output:"\u02D8",ttype:UNARY,acc:true},{input:"\\check",tag:"mover",output:"\u02C7",ttype:UNARY,acc:true},{input:"\\dot",tag:"mover",output:".",ttype:UNARY,acc:true},{input:"\\ddot",tag:"mover",output:"..",ttype:UNARY,acc:true},{input:"\\mathring",tag:"mover",output:"\u00B0",ttype:UNARY,acc:true},{input:"\\vec",tag:"mover",output:"\u20D7",ttype:UNARY,acc:true},{input:"\\overrightarrow",tag:"mover",output:"\u20D7",ttype:UNARY,acc:true},{input:"\\overleftarrow",tag:"mover",output:"\u20D6",ttype:UNARY,acc:true},{input:"\\hat",tag:"mover",output:"\u005E",ttype:UNARY,acc:true},{input:"\\widehat",tag:"mover",output:"\u0302",ttype:UNARY,acc:true},{input:"\\tilde",tag:"mover",output:"~",ttype:UNARY,acc:true},{input:"\\widetilde",tag:"mover",output:"\u02DC",ttype:UNARY,acc:true},{input:"\\bar",tag:"mover",output:"\u203E",ttype:UNARY,acc:true},{input:"\\overbrace",tag:"mover",output:"\uFE37",ttype:UNARY,acc:true},{input:"\\overbracket",tag:"mover",output:"\u23B4",ttype:UNARY,acc:true},{input:"\\overline",tag:"mover",output:"\u00AF",ttype:UNARY,acc:true},{input:"\\underbrace",tag:"munder",output:"\uFE38",ttype:UNARY,acc:true},{input:"\\underbracket",tag:"munder",output:"\u23B5",ttype:UNARY,acc:true},{input:"\\underline",tag:"munder",output:"\u00AF",ttype:UNARY,acc:true},{input:"\\displaystyle",tag:"mstyle",atname:"displaystyle",atval:"true",ttype:UNARY},{input:"\\textstyle",tag:"mstyle",atname:"displaystyle",atval:"false",ttype:UNARY},{input:"\\scriptstyle",tag:"mstyle",atname:"scriptlevel",atval:"1",ttype:UNARY},{input:"\\scriptscriptstyle",tag:"mstyle",atname:"scriptlevel",atval:"2",ttype:UNARY},{input:"\\textrm",tag:"mstyle",output:"\\mathrm",ttype:DEFINITION},{input:"\\mathbf",tag:"mstyle",atname:"mathvariant",atval:"bold",ttype:UNARY},{input:"\\textbf",tag:"mstyle",atname:"mathvariant",atval:"bold",ttype:UNARY},{input:"\\mathit",tag:"mstyle",atname:"mathvariant",atval:"italic",ttype:UNARY},{input:"\\textit",tag:"mstyle",atname:"mathvariant",atval:"italic",ttype:UNARY},{input:"\\mathtt",tag:"mstyle",atname:"mathvariant",atval:"monospace",ttype:UNARY},{input:"\\texttt",tag:"mstyle",atname:"mathvariant",atval:"monospace",ttype:UNARY},{input:"\\mathsf",tag:"mstyle",atname:"mathvariant",atval:"sans-serif",ttype:UNARY},{input:"\\mathbb",tag:"mstyle",atname:"mathvariant",atval:"double-struck",ttype:UNARY,codes:AMbbb},{input:"\\mathcal",tag:"mstyle",atname:"mathvariant",atval:"script",ttype:UNARY,codes:AMcal},{input:"\\mathfrak",tag:"mstyle",atname:"mathvariant",atval:"fraktur",ttype:UNARY,codes:AMfrk},{input:"\\textcolor",tag:"mstyle",atname:"mathvariant",atval:"mathcolor",ttype:BINARY},{input:"\\colorbox",tag:"mstyle",atname:"mathvariant",atval:"background",ttype:BINARY}];function compareNames(s1,s2){if(s1.input>s2.input)return 1+ else return-1;}+ var AMnames=[];function AMinitSymbols(){AMsymbols.sort(compareNames);for(i=0;i<AMsymbols.length;i++)AMnames[i]=AMsymbols[i].input;}+ var AMmathml="http://www.w3.org/1998/Math/MathML";function AMcreateElementMathML(t){if(isIE)return document.createElement("m:"+t);else return document.createElementNS(AMmathml,t);}+ function AMcreateMmlNode(t,frag){if(isIE)var node=document.createElement("m:"+t);else var node=document.createElementNS(AMmathml,t);node.appendChild(frag);return node;}+ function newcommand(oldstr,newstr){AMsymbols=AMsymbols.concat([{input:oldstr,tag:"mo",output:newstr,ttype:DEFINITION}]);}+ function AMremoveCharsAndBlanks(str,n){var st;st=str.slice(n);for(var i=0;i<st.length&&st.charCodeAt(i)<=32;i=i+1);return st.slice(i);}+ function AMposition(arr,str,n){if(n==0){var h,m;n=-1;h=arr.length;while(n+1<h){m=(n+h)>>1;if(arr[m]<str)n=m;else h=m;}+ return h;}else+ for(var i=n;i<arr.length&&arr[i]<str;i++);return i;}+ function AMgetSymbol(str){var k=0;var j=0;var mk;var st;var tagst;var match="";var more=true;for(var i=1;i<=str.length&&more;i++){st=str.slice(0,i);j=k;k=AMposition(AMnames,st,j);if(k<AMnames.length&&str.slice(0,AMnames[k].length)==AMnames[k]){match=AMnames[k];mk=k;i=match.length;}+ more=k<AMnames.length&&str.slice(0,AMnames[k].length)>=AMnames[k];}+ AMpreviousSymbol=AMcurrentSymbol;if(match!=""){AMcurrentSymbol=AMsymbols[mk].ttype;return AMsymbols[mk];}+ AMcurrentSymbol=CONST;k=1;st=str.slice(0,1);if("0"<=st&&st<="9")tagst="mn";else tagst=(("A">st||st>"Z")&&("a">st||st>"z")?"mo":"mi");return{input:st,tag:tagst,output:st,ttype:CONST};}+ var AMpreviousSymbol,AMcurrentSymbol;function AMparseSexpr(str){var symbol,node,result,result2,i,st,newFrag=document.createDocumentFragment();str=AMremoveCharsAndBlanks(str,0);symbol=AMgetSymbol(str);if(symbol==null||symbol.ttype==RIGHTBRACKET)+ return[null,str,null];if(symbol.ttype==DEFINITION){str=symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length);symbol=AMgetSymbol(str);if(symbol==null||symbol.ttype==RIGHTBRACKET)+ return[null,str,null];}+ str=AMremoveCharsAndBlanks(str,symbol.input.length);switch(symbol.ttype){case SPACE:node=AMcreateElementMathML(symbol.tag);node.setAttribute(symbol.atname,symbol.atval);return[node,str,symbol.tag];case UNDEROVER:if(isIE){if(symbol.input.substr(0,4)=="\\big"){str="\\"+symbol.input.substr(4)+str;symbol=AMgetSymbol(str);symbol.ttype=UNDEROVER;str=AMremoveCharsAndBlanks(str,symbol.input.length);}}+ return[AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str,symbol.tag];case CONST:var output=symbol.output;if(isIE){if(symbol.input=="'")+ output="\u2032";else if(symbol.input=="''")+ output="\u2033";else if(symbol.input=="'''")+ output="\u2033\u2032";else if(symbol.input=="''''")+ output="\u2033\u2033";else if(symbol.input=="\\square")+ output="\u25A1";else if(symbol.input.substr(0,5)=="\\frac"){var denom=symbol.input.substr(6,1);if(denom=="5"||denom=="6"){str=symbol.input.replace(/\\frac/,"\\frac ")+str;return[node,str,symbol.tag];}}}+ node=AMcreateMmlNode(symbol.tag,document.createTextNode(output));return[node,str,symbol.tag];case LONG:node=AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output));node.setAttribute("minsize","1.5");node.setAttribute("maxsize","1.5");node=AMcreateMmlNode("mover",node);node.appendChild(AMcreateElementMathML("mspace"));return[node,str,symbol.tag];case STRETCHY:if(isIE&&symbol.input=="\\backslash")+ symbol.output="\\";node=AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output));if(symbol.input=="|"||symbol.input=="\\vert"||symbol.input=="\\|"||symbol.input=="\\Vert"){node.setAttribute("lspace","0em");node.setAttribute("rspace","0em");}+ node.setAttribute("maxsize",symbol.atval);if(symbol.rtag!=null)+ return[node,str,symbol.rtag];else+ return[node,str,symbol.tag];case BIG:var atval=symbol.atval;if(isIE)+ atval=symbol.ieval;symbol=AMgetSymbol(str);if(symbol==null)+ return[null,str,null];str=AMremoveCharsAndBlanks(str,symbol.input.length);node=AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output));if(isIE){var space=AMcreateElementMathML("mspace");space.setAttribute("height",atval+"ex");node=AMcreateMmlNode("mrow",node);node.appendChild(space);}else{node.setAttribute("minsize",atval);node.setAttribute("maxsize",atval);}+ return[node,str,symbol.tag];case LEFTBRACKET:if(symbol.input=="\\left"){symbol=AMgetSymbol(str);if(symbol!=null){if(symbol.input==".")+ symbol.invisible=true;str=AMremoveCharsAndBlanks(str,symbol.input.length);}}+ result=AMparseExpr(str,true,false);if(symbol==null||(typeof symbol.invisible=="boolean"&&symbol.invisible))+ node=AMcreateMmlNode("mrow",result[0]);else{node=AMcreateMmlNode("mo",document.createTextNode(symbol.output));node=AMcreateMmlNode("mrow",node);node.appendChild(result[0]);}+ return[node,result[1],result[2]];case MATRIX:if(symbol.input=="\\begin{array}"){var mask="";symbol=AMgetSymbol(str);str=AMremoveCharsAndBlanks(str,0);if(symbol==null)+ mask="l";else{str=AMremoveCharsAndBlanks(str,symbol.input.length);if(symbol.input!="{")+ mask="l";else do{symbol=AMgetSymbol(str);if(symbol!=null){str=AMremoveCharsAndBlanks(str,symbol.input.length);if(symbol.input!="}")+ mask=mask+symbol.input;}}while(symbol!=null&&symbol.input!=""&&symbol.input!="}");}+ result=AMparseExpr("{"+str,true,true);node=AMcreateMmlNode("mtable",result[0]);mask=mask.replace(/l/g,"left ");mask=mask.replace(/r/g,"right ");mask=mask.replace(/c/g,"center ");node.setAttribute("columnalign",mask);node.setAttribute("displaystyle","false");if(isIE)+ return[node,result[1],null];var lspace=AMcreateElementMathML("mspace");lspace.setAttribute("width","0.167em");var rspace=AMcreateElementMathML("mspace");rspace.setAttribute("width","0.167em");var node1=AMcreateMmlNode("mrow",lspace);node1.appendChild(node);node1.appendChild(rspace);return[node1,result[1],null];}else{result=AMparseExpr("{"+str,true,true);node=AMcreateMmlNode("mtable",result[0]);if(isIE)+ node.setAttribute("columnspacing","0.25em");else+ node.setAttribute("columnspacing","0.167em");node.setAttribute("columnalign","right center left");node.setAttribute("displaystyle","true");node=AMcreateMmlNode("mrow",node);return[node,result[1],null];}+ case TEXT:if(str.charAt(0)=="{")i=str.indexOf("}");else i=0;if(i==-1)+ i=str.length;st=str.slice(1,i);if(st.charAt(0)==" "){node=AMcreateElementMathML("mspace");node.setAttribute("width","0.33em");newFrag.appendChild(node);}+ newFrag.appendChild(AMcreateMmlNode(symbol.tag,document.createTextNode(st)));if(st.charAt(st.length-1)==" "){node=AMcreateElementMathML("mspace");node.setAttribute("width","0.33em");newFrag.appendChild(node);}+ str=AMremoveCharsAndBlanks(str,i+1);return[AMcreateMmlNode("mrow",newFrag),str,null];case UNARY:result=AMparseSexpr(str);if(result[0]==null)return[AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str];if(typeof symbol.func=="boolean"&&symbol.func){st=str.charAt(0);if(st=="^"||st=="_"||st==","){return[AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str,symbol.tag];}else{node=AMcreateMmlNode("mrow",AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));if(isIE){var space=AMcreateElementMathML("mspace");space.setAttribute("width","0.167em");node.appendChild(space);}+ node.appendChild(result[0]);return[node,result[1],symbol.tag];}}+ if(symbol.input=="\\sqrt"){if(isIE){var space=AMcreateElementMathML("mspace");space.setAttribute("height","1.2ex");space.setAttribute("width","0em");node=AMcreateMmlNode(symbol.tag,result[0])+ node.appendChild(space);return[node,result[1],symbol.tag];}else+ return[AMcreateMmlNode(symbol.tag,result[0]),result[1],symbol.tag];}else if(typeof symbol.acc=="boolean"&&symbol.acc){node=AMcreateMmlNode(symbol.tag,result[0]);var output=symbol.output;if(isIE){if(symbol.input=="\\hat")+ output="\u0302";else if(symbol.input=="\\widehat")+ output="\u005E";else if(symbol.input=="\\bar")+ output="\u00AF";else if(symbol.input=="\\grave")+ output="\u0300";else if(symbol.input=="\\tilde")+ output="\u0303";}+ var node1=AMcreateMmlNode("mo",document.createTextNode(output));if(symbol.input=="\\vec"||symbol.input=="\\check")+ node1.setAttribute("maxsize","1.2");if(isIE&&symbol.input=="\\bar")+ node1.setAttribute("maxsize","0.5");if(symbol.input=="\\underbrace"||symbol.input=="\\underline")+ node1.setAttribute("accentunder","true");else+ node1.setAttribute("accent","true");node.appendChild(node1);if(symbol.input=="\\overbrace"||symbol.input=="\\underbrace")+ node.ttype=UNDEROVER;return[node,result[1],symbol.tag];}else{if(!isIE&&typeof symbol.codes!="undefined"){for(i=0;i<result[0].childNodes.length;i++)+ if(result[0].childNodes[i].nodeName=="mi"||result[0].nodeName=="mi"){st=(result[0].nodeName=="mi"?result[0].firstChild.nodeValue:result[0].childNodes[i].firstChild.nodeValue);var newst=[];for(var j=0;j<st.length;j++)+ if(st.charCodeAt(j)>64&&st.charCodeAt(j)<91)newst=newst++ String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]);else newst=newst+st.charAt(j);if(result[0].nodeName=="mi")+ result[0]=AMcreateElementMathML("mo").appendChild(document.createTextNode(newst));else result[0].replaceChild(AMcreateElementMathML("mo").appendChild(document.createTextNode(newst)),result[0].childNodes[i]);}}+ node=AMcreateMmlNode(symbol.tag,result[0]);node.setAttribute(symbol.atname,symbol.atval);if(symbol.input=="\\scriptstyle"||symbol.input=="\\scriptscriptstyle")+ node.setAttribute("displaystyle","false");return[node,result[1],symbol.tag];}+ case BINARY:result=AMparseSexpr(str);if(result[0]==null)return[AMcreateMmlNode("mo",document.createTextNode(symbol.input)),str,null];result2=AMparseSexpr(result[1]);if(result2[0]==null)return[AMcreateMmlNode("mo",document.createTextNode(symbol.input)),str,null];if(symbol.input=="\\textcolor"||symbol.input=="\\colorbox"){var tclr=str.match(/\{\s*([#\w]+)\s*\}/);str=str.replace(/\{\s*[#\w]+\s*\}/,"");if(tclr!=null){if(IsColorName.test(tclr[1].toLowerCase())){tclr=LaTeXColor[tclr[1].toLowerCase()];}else{tclr=tclr[1];}+ node=AMcreateElementMathML("mstyle");node.setAttribute(symbol.atval,tclr);node.appendChild(result2[0]);return[node,result2[1],symbol.tag];}}+ if(symbol.input=="\\root"||symbol.input=="\\stackrel")newFrag.appendChild(result2[0]);newFrag.appendChild(result[0]);if(symbol.input=="\\frac")newFrag.appendChild(result2[0]);return[AMcreateMmlNode(symbol.tag,newFrag),result2[1],symbol.tag];case INFIX:str=AMremoveCharsAndBlanks(str,symbol.input.length);return[AMcreateMmlNode("mo",document.createTextNode(symbol.output)),str,symbol.tag];default:return[AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str,symbol.tag];}}+ function AMparseIexpr(str){var symbol,sym1,sym2,node,result,tag,underover;str=AMremoveCharsAndBlanks(str,0);sym1=AMgetSymbol(str);result=AMparseSexpr(str);node=result[0];str=result[1];tag=result[2];symbol=AMgetSymbol(str);if(symbol.ttype==INFIX){str=AMremoveCharsAndBlanks(str,symbol.input.length);result=AMparseSexpr(str);if(result[0]==null)+ result[0]=AMcreateMmlNode("mo",document.createTextNode("\u25A1"));str=result[1];tag=result[2];if(symbol.input=="_"||symbol.input=="^"){sym2=AMgetSymbol(str);tag=null;underover=((sym1.ttype==UNDEROVER)||(node.ttype==UNDEROVER));if(symbol.input=="_"&&sym2.input=="^"){str=AMremoveCharsAndBlanks(str,sym2.input.length);var res2=AMparseSexpr(str);str=res2[1];tag=res2[2];node=AMcreateMmlNode((underover?"munderover":"msubsup"),node);node.appendChild(result[0]);node.appendChild(res2[0]);}else if(symbol.input=="_"){node=AMcreateMmlNode((underover?"munder":"msub"),node);node.appendChild(result[0]);}else{node=AMcreateMmlNode((underover?"mover":"msup"),node);node.appendChild(result[0]);}+ node=AMcreateMmlNode("mrow",node);}else{node=AMcreateMmlNode(symbol.tag,node);if(symbol.input=="\\atop"||symbol.input=="\\choose")+ node.setAttribute("linethickness","0ex");node.appendChild(result[0]);if(symbol.input=="\\choose")+ node=AMcreateMmlNode("mfenced",node);}}+ return[node,str,tag];}+ function AMparseExpr(str,rightbracket,matrix){var symbol,node,result,i,tag,newFrag=document.createDocumentFragment();do{str=AMremoveCharsAndBlanks(str,0);result=AMparseIexpr(str);node=result[0];str=result[1];tag=result[2];symbol=AMgetSymbol(str);if(node!=undefined){if((tag=="mn"||tag=="mi")&&symbol!=null&&typeof symbol.func=="boolean"&&symbol.func){var space=AMcreateElementMathML("mspace");space.setAttribute("width","0.167em");node=AMcreateMmlNode("mrow",node);node.appendChild(space);}+ newFrag.appendChild(node);}}while((symbol.ttype!=RIGHTBRACKET)&&symbol!=null&&symbol.output!="");tag=null;if(symbol.ttype==RIGHTBRACKET){if(symbol.input=="\\right"){str=AMremoveCharsAndBlanks(str,symbol.input.length);symbol=AMgetSymbol(str);if(symbol!=null&&symbol.input==".")+ symbol.invisible=true;if(symbol!=null)+ tag=symbol.rtag;}+ if(symbol!=null)+ str=AMremoveCharsAndBlanks(str,symbol.input.length);var len=newFrag.childNodes.length;if(matrix&&len>0&&newFrag.childNodes[len-1].nodeName=="mrow"&&len>1&&newFrag.childNodes[len-2].nodeName=="mo"&&newFrag.childNodes[len-2].firstChild.nodeValue=="&"){var pos=[];var m=newFrag.childNodes.length;for(i=0;matrix&&i<m;i=i+2){pos[i]=[];node=newFrag.childNodes[i];for(var j=0;j<node.childNodes.length;j++)+ if(node.childNodes[j].firstChild.nodeValue=="&")+ pos[i][pos[i].length]=j;}+ var row,frag,n,k,table=document.createDocumentFragment();for(i=0;i<m;i=i+2){row=document.createDocumentFragment();frag=document.createDocumentFragment();node=newFrag.firstChild;n=node.childNodes.length;k=0;for(j=0;j<n;j++){if(typeof pos[i][k]!="undefined"&&j==pos[i][k]){node.removeChild(node.firstChild);row.appendChild(AMcreateMmlNode("mtd",frag));k++;}else frag.appendChild(node.firstChild);}+ row.appendChild(AMcreateMmlNode("mtd",frag));if(newFrag.childNodes.length>2){newFrag.removeChild(newFrag.firstChild);newFrag.removeChild(newFrag.firstChild);}+ table.appendChild(AMcreateMmlNode("mtr",row));}+ return[table,str];}+ if(typeof symbol.invisible!="boolean"||!symbol.invisible){node=AMcreateMmlNode("mo",document.createTextNode(symbol.output));newFrag.appendChild(node);}}+ return[newFrag,str,tag];}+ function AMparseMath(str){var result,node=AMcreateElementMathML("mstyle");var cclr=str.match(/\\color\s*\{\s*([#\w]+)\s*\}/);str=str.replace(/\\color\s*\{\s*[#\w]+\s*\}/g,"");if(cclr!=null){if(IsColorName.test(cclr[1].toLowerCase())){cclr=LaTeXColor[cclr[1].toLowerCase()];}else{cclr=cclr[1];}+ node.setAttribute("mathcolor",cclr);}else{if(mathcolor!="")node.setAttribute("mathcolor",mathcolor);};if(mathfontfamily!="")node.setAttribute("fontfamily",mathfontfamily);node.appendChild(AMparseExpr(str.replace(/^\s+/g,""),false,false)[0]);node=AMcreateMmlNode("math",node);if(showasciiformulaonhover)+ node.setAttribute("title",str.replace(/\s+/g," "));if(false){var fnode=AMcreateElementXHTML("font");fnode.setAttribute("face",mathfontfamily);fnode.appendChild(node);return fnode;}+ return node;}+ function AMstrarr2docFrag(arr,linebreaks){var newFrag=document.createDocumentFragment();var expr=false;for(var i=0;i<arr.length;i++){if(expr)newFrag.appendChild(AMparseMath(arr[i]));else{var arri=(linebreaks?arr[i].split("\n\n"):[arr[i]]);newFrag.appendChild(AMcreateElementXHTML("span").appendChild(document.createTextNode(arri[0])));for(var j=1;j<arri.length;j++){newFrag.appendChild(AMcreateElementXHTML("p"));newFrag.appendChild(AMcreateElementXHTML("span").appendChild(document.createTextNode(arri[j])));}}+ expr=!expr;}+ return newFrag;}+ function AMprocessNodeR(n,linebreaks){var mtch,str,arr,frg,i;if(n.childNodes.length==0){if((n.nodeType!=8||linebreaks)&&n.parentNode.nodeName!="form"&&n.parentNode.nodeName!="FORM"&&n.parentNode.nodeName!="textarea"&&n.parentNode.nodeName!="TEXTAREA"&&n.parentNode.nodeName!="pre"&&n.parentNode.nodeName!="PRE"){str=n.nodeValue;if(!(str==null)){str=str.replace(/\r\n\r\n/g,"\n\n");str=str.replace(/\x20+/g," ");str=str.replace(/\s*\r\n/g," ");mtch=(str.indexOf("\$")==-1?false:true);str=str.replace(/([^\\])\$/g,"$1 \$");str=str.replace(/^\$/," \$");arr=str.split(" \$");for(i=0;i<arr.length;i++)+ arr[i]=arr[i].replace(/\\\$/g,"\$");if(arr.length>1||mtch){if(checkForMathML){checkForMathML=false;var nd=AMisMathMLavailable();AMnoMathML=nd!=null;if(AMnoMathML&¬ifyIfNoMathML)+ if(alertIfNoMathML)+ alert("To view the ASCIIMathML notation use Internet Explorer 6 +\nMathPlayer (free from www.dessci.com)\nor Firefox/Mozilla/Netscape");else AMbody.insertBefore(nd,AMbody.childNodes[0]);}+ if(!AMnoMathML){frg=AMstrarr2docFrag(arr,n.nodeType==8);var len=frg.childNodes.length;n.parentNode.replaceChild(frg,n);return len-1;}else return 0;}}}else return 0;}else if(n.nodeName!="math"){for(i=0;i<n.childNodes.length;i++)+ i+=AMprocessNodeR(n.childNodes[i],linebreaks);}+ return 0;}+ function AMprocessNode(n,linebreaks,spanclassAM){var frag,st;if(spanclassAM!=null){frag=document.getElementsByTagName("span")+ for(var i=0;i<frag.length;i++)+ if(frag[i].className=="AM")+ AMprocessNodeR(frag[i],linebreaks);}else{try{st=n.innerHTML;}catch(err){}+ if(st==null||st.indexOf("\$")!=-1)+ AMprocessNodeR(n,linebreaks);}+ if(isIE){frag=document.getElementsByTagName('math');for(var i=0;i<frag.length;i++)frag[i].update()}}+ var inAppendix=false;var sectionCntr=0;var IEcommentWarning=true;var biblist=[];var bibcntr=0;var LaTeXCounter=[];LaTeXCounter["definition"]=0;LaTeXCounter["proposition"]=0;LaTeXCounter["lemma"]=0;LaTeXCounter["theorem"]=0;LaTeXCounter["corollary"]=0;LaTeXCounter["example"]=0;LaTeXCounter["exercise"]=0;LaTeXCounter["subsection"]=0;LaTeXCounter["subsubsection"]=0;LaTeXCounter["figure"]=0;LaTeXCounter["equation"]=0;LaTeXCounter["table"]=0;var LaTeXColor=[];LaTeXColor["greenyellow"]="#D9FF4F";LaTeXColor["yellow"]="#FFFF00";LaTeXColor["goldenrod"]="#FFE529";LaTeXColor["dandelion"]="#FFB529";LaTeXColor["apricot"]="#FFAD7A";LaTeXColor["peach"]="#FF804D";LaTeXColor["melon"]="#FF8A80";LaTeXColor["yelloworange"]="#FF9400";LaTeXColor["orange"]="#FF6321";LaTeXColor["burntorange"]="#FF7D00";LaTeXColor["bittersweet"]="#C20300";LaTeXColor["redorange"]="#FF3B21";LaTeXColor["mahogany"]="#A60000";LaTeXColor["maroon"]="#AD0000";LaTeXColor["brickred"]="#B80000";LaTeXColor["red"]="#FF0000";LaTeXColor["orangered"]="#FF0080";LaTeXColor["rubinered"]="#FF00DE";LaTeXColor["wildstrawberry"]="#FF0A9C";LaTeXColor["salmon"]="#FF789E";LaTeXColor["carnationpink"]="#FF5EFF";LaTeXColor["magenta"]="#FF00FF";LaTeXColor["violetred"]="#FF30FF";LaTeXColor["rhodamine"]="#FF2EFF";LaTeXColor["mulberry"]="#A314FA";LaTeXColor["redviolet"]="#9600A8";LaTeXColor["fuchsia"]="#7303EB";LaTeXColor["lavender"]="#FF85FF";LaTeXColor["thistle"]="#E069FF";LaTeXColor["orchid"]="#AD5CFF";LaTeXColor["darkorchid"]="#9933CC";LaTeXColor["purple"]="#8C24FF";LaTeXColor["plum"]="#8000FF";LaTeXColor["violet"]="#361FFF";LaTeXColor["royalpurple"]="#401AFF";LaTeXColor["blueviolet"]="#1A0DF5";LaTeXColor["periwinkle"]="#6E73FF";LaTeXColor["cadetblue"]="#616EC4";LaTeXColor["cornflowerblue"]="#59DEFF";LaTeXColor["midnightblue"]="#007091";LaTeXColor["navyblue"]="#0F75FF";LaTeXColor["royalblue"]="#0080FF";LaTeXColor["blue"]="#0000FF";LaTeXColor["cerulean"]="#0FE3FF";LaTeXColor["cyan"]="#00FFFF";LaTeXColor["processblue"]="#0AFFFF";LaTeXColor["skyblue"]="#61FFE0";LaTeXColor["turquoise"]="#26FFCC";LaTeXColor["tealblue"]="#1FFAA3";LaTeXColor["aquamarine"]="#2EFFB2";LaTeXColor["bluegreen"]="#26FFAB";LaTeXColor["emerald"]="#00FF80";LaTeXColor["junglegreen"]="#03FF7A";LaTeXColor["seagreen"]="#4FFF80";LaTeXColor["green"]="#00FF00";LaTeXColor["forestgreen"]="#00E000";LaTeXColor["pinegreen"]="#00BF29";LaTeXColor["limegreen"]="#80FF00";LaTeXColor["yellowgreen"]="#8FFF42";LaTeXColor["springgreen"]="#BDFF3D";LaTeXColor["olivegreen"]="#009900";LaTeXColor["rawsienna"]="#8C0000";LaTeXColor["sepia"]="#4D0000";LaTeXColor["brown"]="#660000";LaTeXColor["tan"]="#DB9470";LaTeXColor["gray"]="#808080";LaTeXColor["grey"]="#808080";LaTeXColor["black"]="#000000";LaTeXColor["white"]="#FFFFFF";var IsColorName=/^(?:greenyellow|yellow|goldenrod|dandelion|apricot|peach|melon|yelloworange|orange|burntorange|bittersweet|redorange|mahogany|maroon|brickred|red|orangered|rubinered|wildstrawberry|salmon|carnationpink|magenta|violetred|rhodamine|mulberry|redviolet|fuchsia|lavender|thistle|orchid|darkorchid|purple|plum|violet|royalpurple|blueviolet|periwinkle|cadetblue|cornflowerblue|midnightblue|navyblue|royalblue|blue|cerulean|cyan|processblue|skyblue|turquoise|tealblue|aquamarine|bluegreen|emerald|junglegreen|seagreen|green|forestgreen|pinegreen|limegreen|yellowgreen|springgreen|olivegreen|rawsienna|sepia|brown|tan|gray|grey|black|white)$/;var IsCounter=/^(?:definition|proposition|lemma|theorem|corollary|example|exercise|subsection|subsubsection|figure|equation|table)$/;var IsLaTeXElement=/^(?:displayequation|title|author|address|date|abstract|keyword|section|subsection|subsubsection|ref|cite|thebibliography|definition|proposition|lemma|theorem|corollary|example|exercise|itemize|enumerate|enddefinition|endproposition|endlemma|endtheorem|endcorollary|endexample|endexercise|enditemize|endenumerate|LaTeXMathMLlabel|LaTeXMathML|smallskip|medskip|bigskip|quote|quotation|endquote|endquotation|center|endcenter|description|enddescription|inlinemath)$/;var IsTextOnlyArea=/^(?:form|textarea|pre)$/i;var tableid=0;function makeNumberString(cntr){if(sectionCntr>0){if(inAppendix){return"A"+sectionCntr+"."+cntr;}else{return sectionCntr+"."+cntr;}}else{return""+cntr;}};function LaTeXpreProcess(thebody){var TheBody=thebody;if(TheBody.hasChildNodes()){if(!(IsLaTeXElement.test(TheBody.className)))+ {for(var i=0;i<TheBody.childNodes.length;i++){LaTeXpreProcess(TheBody.childNodes[i])}}}+ else{if(TheBody.nodeType==3&&!(IsTextOnlyArea.test(TheBody.parentNode.nodeName)))+ {var str=TheBody.nodeValue;if(!(str==null)){str=str.replace(/\\%/g,"<per>");str=str.replace(/%[^\n]*(?=\n)/g,"");str=str.replace(/%[^\r]*(?=\r)/g,"");str=str.replace(/%[^\n]*$/,"")+ if(isIE&&str.match(/%/g)!=null&&IEcommentWarning){alert("Comments may not have parsed properly. Try putting in <pre class='LaTeX><div>..</div></pre> structure.");IEcommentWarning=false;}+ str=str.replace(/<per>/g,"%");if(str.match(/XXX[\s\S]*/)!=null){var tmp=str.match(/XXX[\s\S]*/)[0];var tmpstr=tmp.charCodeAt(7)+"::"+tmp.charCodeAt(8)+"::"+tmp.charCodeAt(9)+"::"+tmp.charCodeAt(10)+"::"+tmp.charCodeAt(11)+"::"+tmp.charCodeAt(12)+"::"+tmp.charCodeAt(13);alert(tmpstr);}+ str=str.replace(/([^\\])\\(\s)/g,"$1\u00A0$2");str=str.replace(/\\quad/g,"\u2001");str=str.replace(/\\qquad/g,"\u2001\u2001");str=str.replace(/\\enspace/g,"\u2002");str=str.replace(/\\;/g,"\u2004");str=str.replace(/\\:/g,"\u2005");str=str.replace(/\\,/g,"\u2006");str=str.replace(/\\thinspace/g,"\u200A");str=str.replace(/([^\\])~/g,"$1\u00A0");str=str.replace(/\\~/g,"~");str=str.replace(/\\\[/g," <DEQ> $\\displaystyle{");str=str.replace(/\\\]/g,"}$ <DEQ> ");str=str.replace(/\$\$/g,"${$<DEQ>$}$");str=str.replace(/\\begin\s*\{\s*array\s*\}/g,"\\begin{array}");str=str.replace(/\\end\s*\{\s*array\s*\}/g,"\\end{array}");str=str.replace(/\\begin\s*\{\s*eqnarray\s*\}/g," <DEQ>eqno$\\begin{eqnarray}");str=str.replace(/\\end\s*\{\s*eqnarray\s*\}/g,"\\end{eqnarray}$<DEQ> ");str=str.replace(/\\begin\s*\{\s*eqnarray\*\s*\}/g," <DEQ>$\\begin{eqnarray}");str=str.replace(/\\end\s*\{\s*eqnarray\*\s*\}/g,"\\end{eqnarray}$<DEQ> ");str=str.replace(/\\begin\s*\{\s*displaymath\s*\}/g," <DEQ> $\\displaystyle{");str=str.replace(/\\end\s*\{\s*displaymath\s*\}/g,"}$ <DEQ> ");str=str.replace(/\\begin\s*\{\s*equation\s*\*\s*\}/g," <DEQ> $\\displaystyle{");str=str.replace(/\\end\s*\{\s*equation\s*\*\s*\}/g,"}$ <DEQ> ");str=str.replace(/\\begin\s*\{\s*equation\s*\}/g," <DEQ>eqno$\\displaystyle{");str=str.replace(/\\end\s*\{\s*equation\s*\}/g,"}$ <DEQ> ");str=str.split("<DEQ>");var newFrag=document.createDocumentFragment();for(var i=0;i<str.length;i++){if(i%2){var DEQtable=document.createElement("table");DEQtable.className='displayequation';var DEQtbody=document.createElement("tbody");var DEQtr=document.createElement("tr");var DEQtdeq=document.createElement("td");DEQtdeq.className='eq';str[i]=str[i].replace(/\$\}\$/g,"$\\displaystyle{");str[i]=str[i].replace(/\$\{\$/g,"}");var lbl=str[i].match(/\\label\s*\{\s*(\w+)\s*\}/);var ISeqno=str[i].match(/^eqno/);str[i]=str[i].replace(/^eqno/," ");str[i]=str[i].replace(/\\label\s*\{\s*\w+\s*\}/," ");DEQtdeq.appendChild(document.createTextNode(str[i]));DEQtr.appendChild(DEQtdeq);str[i]=str[i].replace(/\\nonumber/g,"");if(ISeqno!=null||lbl!=null){var DEQtdno=document.createElement("td");DEQtdno.className='eqno';LaTeXCounter["equation"]++;var eqnoString=makeNumberString(LaTeXCounter["equation"]);var DEQanchor=document.createElement("a");if(lbl!=null){DEQanchor.id=lbl[1]};DEQanchor.className="eqno";var anchorSpan=document.createElement("span");anchorSpan.className="eqno";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(eqnoString));DEQanchor.appendChild(anchorSpan);DEQtdno.appendChild(DEQanchor);var DEQspan=document.createElement("span");DEQspan.className="eqno";DEQspan.appendChild(document.createTextNode("("+eqnoString+")"));DEQtdno.appendChild(DEQspan);DEQtr.appendChild(DEQtdno);}+ DEQtbody.appendChild(DEQtr);DEQtable.appendChild(DEQtbody);newFrag.appendChild(DEQtable);}+ else{str[i]=str[i].replace(/\$\}\$/g,"");str[i]=str[i].replace(/\$\{\$/g,"");str[i]=str[i].replace(/\\maketitle/g,"");str[i]=str[i].replace(/\\begin\s*\{\s*document\s*\}/g,"");str[i]=str[i].replace(/\\end\s*\{\s*document\s*\}/g,"");str[i]=str[i].replace(/\\documentclass[^\}]*?\}/g,"");str[i]=str[i].replace(/\\usepackage[^\}]*?\}/g,"");str[i]=str[i].replace(/\\noindent/g,"");str[i]=str[i].replace(/\\notag/g,"");str[i]=str[i].replace(/\\ref\s*\{\s*(\w+)\}/g," \\[ref\\]$1\\[ ");str[i]=str[i].replace(/\\url\s*\{\s*([^\}\n]+)\}/g," \\[url\\]$1\\[ ");str[i]=str[i].replace(/\\href\s*\{\s*([^\}]+)\}\s*\{\s*([^\}]+)\}/g," \\[href\\]$1\\]$2\\[ ");str[i]=str[i].replace(/\\cite\s*\{\s*(\w+)\}/g," \\[cite\\]$1\\[ ");str[i]=str[i].replace(/\\qed/g,"\u220E");str[i]=str[i].replace(/\\endproof/g,"\u220E");str[i]=str[i].replace(/\\proof/g,"\\textbf{Proof: }");str[i]=str[i].replace(/\\n(?=\s)/g," \\[br\\] \\[ ");str[i]=str[i].replace(/\\newline/g," \\[br\\] \\[ ");str[i]=str[i].replace(/\\linebreak/g," \\[br\\] \\[ ");str[i]=str[i].replace(/\\smallskip/g," \\[logicalbreak\\]smallskip\\[ ");str[i]=str[i].replace(/\\medskip/g," \\[logicalbreak\\]medskip\\[ ");str[i]=str[i].replace(/\\bigskip/g," \\[logicalbreak\\]bigskip\\[ ");str[i]=str[i].replace(/[\n\r]+[ \f\n\r\t\v\u2028\u2029]*[\n\r]+/g," \\[logicalbreak\\]LaTeXMathML\\[ ");if(isIE){str[i]=str[i].replace(/\r/g," ");}+ str[i]=str[i].replace(/\\bibitem\s*([^\{]*\{\s*\w*\s*\})/g," \\[bibitem\\]$1\\[ ");str[i]=str[i].replace(/\\bibitem\s*/g," \\[bibitem\\] \\[ ");str[i]=str[i].replace(/\\item\s*\[\s*(\w+)\s*\]/g," \\[alistitem\\]$1\\[ ");str[i]=str[i].replace(/\\item\s*/g," \\[alistitem\\] \\[ ");str[i]=str[i].replace(/\\appendix/g," \\[appendix\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*figure\s*\}([\s\S]+?)\\end\s*\{\s*figure\s*\}/g," \\[figure\\]$1\\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*table\s*\}([\s\S]+?)\\end\s*\{\s*table\s*\}/g," \\[table\\]$1\\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*theorem\s*\}/g," \\[theorem\\]Theorem \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*theorem\s*\}/g," \\[endtheorem\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*definition\s*\}/g," \\[definition\\]Definition \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*definition\s*\}/g," \\[enddefinition\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*lemma\s*\}/g," \\[lemma\\]Lemma \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*lemma\s*\}/g," \\[endlemma\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*corollary\s*\}/g," \\[corollary\\]Corollary \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*corollary\s*\}/g," \\[endcorollary\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*proposition\s*\}/g," \\[proposition\\]Proposition \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*proposition\s*\}/g," \\[endproposition\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*example\s*\}/g," \\[example\\]Example \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*example\s*\}/g," \\[endexample\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*exercise\s*\}/g," \\[exercise\\]Exercise \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*exercise\s*\}/g," \\[endexercise\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*thebibliography\s*\}\s*\{\s*\w+\s*\}/g," \\[thebibliography\\]References \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*thebibliography\s*\}/g," \\[thebibliography\\]References \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*thebibliography\s*\}/g," \\[endthebibliography\\]References \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*proof\s*\}/g," \\[proof\\]Proof: \\[ ");if(isIE){str[i]=str[i].replace(/\\end\s*\{\s*proof\s*\}/g,"\u220E \\[endproof\\] \\[ ");}else{str[i]=str[i].replace(/\\end\s*\{\s*proof\s*\}/g," \\[endproof\\] \\[ ");}+ str[i]=str[i].replace(/\\title\s*\{\s*([^\}]+)\}/g," \\[title\\] \\[$1 \\[endtitle\\] \\[ ");str[i]=str[i].replace(/\\author\s*\{\s*([^\}]+)\}/g," \\[author\\] \\[$1 \\[endauthor\\] \\[ ");str[i]=str[i].replace(/\\address\s*\{\s*([^\}]+)\}/g," \\[address\\] \\[$1 \\[endaddress\\] \\[ ");str[i]=str[i].replace(/\\date\s*\{\s*([^\}]+)\}/g," \\[date\\] \\[$1 \\[enddate\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*keyword\s*\}/g," \\[keyword\\] \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*keyword\s*\}/g," \\[endkeyword\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*abstract\s*\}/g," \\[abstract\\] \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*abstract\s*\}/g," \\[endabstract\\] \\[ ");str[i]=str[i].replace(/\\begin\s*\{\s*(?!array|tabular)(\w+)\s*\}/g," \\[$1\\] \\[ ");str[i]=str[i].replace(/\\end\s*\{\s*(?!array|tabular)(\w+)\s*\}/g," \\[end$1\\] \\[ ");var sectionIndex=str[i].search(/\\section\s*\{\s*[\s\S]+\}/);while(sectionIndex>=0){str[i]=str[i].replace(/\\section\s*\{/," \\[section\\]");var delimcnt=1;for(var ii=sectionIndex;ii<str[i].length;ii++){if(str[i].charAt(ii)=="{"){delimcnt++};if(str[i].charAt(ii)=="}"){delimcnt--};if(delimcnt==0){str[i]=str[i].substring(0,ii)+"\\[ "+str[i].substring(ii+1,str[i].length);break;}};sectionIndex=str[i].search(/\\section\s*\{\s*[\s\S]+\}/);}+ sectionIndex=str[i].search(/\\subsection\s*\{\s*[\s\S]+\}/);while(sectionIndex>=0){str[i]=str[i].replace(/\\subsection\s*\{/," \\[subsection\\]");var delimcnt=1;for(var ii=sectionIndex;ii<str[i].length;ii++){if(str[i].charAt(ii)=="{"){delimcnt++};if(str[i].charAt(ii)=="}"){delimcnt--};if(delimcnt==0){str[i]=str[i].substring(0,ii)+"\\[ "+str[i].substring(ii+1,str[i].length);break;}};sectionIndex=str[i].search(/\\subsection\s*\{\s*[\s\S]+\}/);}+ sectionIndex=str[i].search(/\\subsubsection\s*\{\s*[\s\S]+\}/);while(sectionIndex>=0){str[i]=str[i].replace(/\\subsubsection\s*\{/," \\[subsubsection\\]");var delimcnt=1;for(var ii=sectionIndex;ii<str[i].length;ii++){if(str[i].charAt(ii)=="{"){delimcnt++};if(str[i].charAt(ii)=="}"){delimcnt--};if(delimcnt==0){str[i]=str[i].substring(0,ii)+"\\[ "+str[i].substring(ii+1,str[i].length);break;}};sectionIndex=str[i].search(/\\subsubsection\s*\{\s*[\s\S]+\}/);}+ var CatToNextEven="";var strtmp=str[i].split("\\[");for(var j=0;j<strtmp.length;j++){if(j%2){var strtmparray=strtmp[j].split("\\]");switch(strtmparray[0]){case"section":var nodeTmp=document.createElement("H2");nodeTmp.className='section';sectionCntr++;for(var div in LaTeXCounter){LaTeXCounter[div]=0};var nodeAnchor=document.createElement("a");if(inAppendix){nodeAnchor.className='appendixsection';}else{nodeAnchor.className='section';}+ var nodeNumString=makeNumberString("");var anchorSpan=document.createElement("span");anchorSpan.className="section";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(nodeNumString));nodeAnchor.appendChild(anchorSpan);nodeTmp.appendChild(nodeAnchor);var nodeSpan=document.createElement("span");nodeSpan.className='section';nodeSpan.appendChild(document.createTextNode(nodeNumString+" "));nodeTmp.appendChild(nodeSpan);nodeTmp.appendChild(document.createTextNode(strtmparray[1]));newFrag.appendChild(nodeTmp);break;case"subsection":var nodeTmp=document.createElement("H3");nodeTmp.className='subsection';LaTeXCounter["subsection"]++;LaTeXCounter["subsubsection"]=0;var nodeAnchor=document.createElement("a");nodeAnchor.className='subsection';var nodeNumString=makeNumberString(LaTeXCounter["subsection"]);var anchorSpan=document.createElement("span");anchorSpan.className="subsection";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(nodeNumString));nodeAnchor.appendChild(anchorSpan);nodeTmp.appendChild(nodeAnchor);var nodeSpan=document.createElement("span");nodeSpan.className='subsection';nodeSpan.appendChild(document.createTextNode(nodeNumString+". "));nodeTmp.appendChild(nodeSpan);nodeTmp.appendChild(document.createTextNode(strtmparray[1]));newFrag.appendChild(nodeTmp);break;case"subsubsection":var nodeTmp=document.createElement("H4");nodeTmp.className='subsubsection';LaTeXCounter["subsubsection"]++;var nodeAnchor=document.createElement("a");nodeAnchor.className='subsubsection';var nodeNumString=makeNumberString(LaTeXCounter["subsection"]+"."+LaTeXCounter["subsubsection"]);var anchorSpan=document.createElement("span");anchorSpan.className="subsubsection";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(nodeNumString));nodeAnchor.appendChild(anchorSpan);nodeTmp.appendChild(nodeAnchor);var nodeSpan=document.createElement("span");nodeSpan.className='subsubsection';nodeSpan.appendChild(document.createTextNode(nodeNumString+". "));nodeTmp.appendChild(nodeSpan);nodeTmp.appendChild(document.createTextNode(strtmparray[1]));newFrag.appendChild(nodeTmp);break;case"href":var nodeTmp=document.createElement("a");nodeTmp.className='LaTeXMathML';nodeTmp.href=strtmparray[1];nodeTmp.appendChild(document.createTextNode(strtmparray[2]));newFrag.appendChild(nodeTmp);break;case"url":var nodeTmp=document.createElement("a");nodeTmp.className='LaTeXMathML';nodeTmp.href=strtmparray[1];nodeTmp.appendChild(document.createTextNode(strtmparray[1]));newFrag.appendChild(nodeTmp);break;case"figure":var nodeTmp=document.createElement("table");nodeTmp.className='figure';var FIGtbody=document.createElement("tbody");var FIGlbl=strtmparray[1].match(/\\label\s*\{\s*(\w+)\s*\}/);strtmparray[1]=strtmparray[1].replace(/\\label\s*\{\w+\}/g,"");var capIndex=strtmparray[1].search(/\\caption\s*\{[\s\S]+\}/);var FIGcap="";if(capIndex>=0){var tmp=strtmparray[1];var delimcnt=0;var capstart=-1;for(var pos=capIndex;pos<tmp.length;pos++){if(tmp.charAt(pos)=="{"){delimcnt++};if(tmp.charAt(pos)=="}"){delimcnt--};if(delimcnt==1&&capstart<0){capstart=pos+1};if(delimcnt==0&&capstart>0){capend=pos-1;FIGcap=tmp.substring(capstart,pos);break}}}+ var FIGtr2=document.createElement("tr");var FIGtd2=document.createElement("td");FIGtd2.className="caption";var FIGanchor=document.createElement("a");FIGanchor.className="figure";if(FIGlbl!=null){FIGanchor.id=FIGlbl[1];}+ LaTeXCounter["figure"]++;var fignmbr=makeNumberString(LaTeXCounter["figure"]);var anchorSpan=document.createElement("span");anchorSpan.className="figure";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(fignmbr));FIGanchor.appendChild(anchorSpan);FIGtd2.appendChild(FIGanchor);var FIGspan=document.createElement("span");FIGspan.className="figure";FIGspan.appendChild(document.createTextNode("Figure "+fignmbr+". "));FIGtd2.appendChild(FIGspan);FIGtd2.appendChild(document.createTextNode(""+FIGcap));FIGtr2.appendChild(FIGtd2);FIGtbody.appendChild(FIGtr2);var IsSpecial=false;var FIGinfo=strtmparray[1].match(/\\includegraphics\s*\{([^\}]+)\}/);if(FIGinfo==null){FIGinfo=strtmparray[1].match(/\\includegraphics\s*\[[^\]]*\]\s*\{\s*([^\}]+)\s*\}/);}+ if(FIGinfo==null){FIGinfo=strtmparray[1].match(/\\special\s*\{\s*([^\}]+)\}/);IsSpecial=true};if(FIGinfo!=null){var FIGtr1=document.createElement("tr");var FIGtd1=document.createElement("td");FIGtd1.className="image";var FIGimg=document.createElement("img");var FIGsrc=FIGinfo[1];FIGimg.src=FIGsrc;FIGimg.alt="Figure "+FIGsrc+" did not load";FIGimg.title="Figure "+fignmbr+". "+FIGcap;FIGimg.id="figure"+fignmbr;FIGtd1.appendChild(FIGimg);FIGtr1.appendChild(FIGtd1);FIGtbody.appendChild(FIGtr1);}+ nodeTmp.appendChild(FIGtbody);newFrag.appendChild(nodeTmp);break;case"table":var nodeTmp=document.createElement("table");if(strtmparray[1].search(/\\centering/)>=0){nodeTmp.className='LaTeXtable centered';nodeTmp.align="center";}else{nodeTmp.className='LaTeXtable';};tableid++;nodeTmp.id="LaTeXtable"+tableid;var TABlbl=strtmparray[1].match(/\\label\s*\{\s*(\w+)\s*\}/);strtmparray[1]=strtmparray[1].replace(/\\label\s*\{\w+\}/g,"");var capIndex=strtmparray[1].search(/\\caption\s*\{[\s\S]+\}/);var TABcap="";if(capIndex>=0){var tmp=strtmparray[1];var delimcnt=0;var capstart=-1;for(var pos=capIndex;pos<tmp.length;pos++){if(tmp.charAt(pos)=="{"){delimcnt++};if(tmp.charAt(pos)=="}"){delimcnt--};if(delimcnt==1&&capstart<0){capstart=pos+1};if(delimcnt==0&&capstart>0){capend=pos-1;TABcap=tmp.substring(capstart,pos);break}}}+ if(TABcap!=""){var TABtbody=document.createElement("tbody");var TABcaption=document.createElement("caption");TABcaption.className="LaTeXtable centered";var TABanchor=document.createElement("a");TABanchor.className="LaTeXtable";if(TABlbl!=null){TABanchor.id=TABlbl[1];}+ LaTeXCounter["table"]++;var tabnmbr=makeNumberString(LaTeXCounter["table"]);var anchorSpan=document.createElement("span");anchorSpan.className="LaTeXtable";anchorSpan.style.display="none";anchorSpan.appendChild(document.createTextNode(tabnmbr));TABanchor.appendChild(anchorSpan);TABcaption.appendChild(TABanchor);var TABspan=document.createElement("span");TABspan.className="LaTeXtable";TABspan.appendChild(document.createTextNode("Table "+tabnmbr+". "));TABcaption.appendChild(TABspan);TABcaption.appendChild(document.createTextNode(""+TABcap));nodeTmp.appendChild(TABcaption);}+ var TABinfo=strtmparray[1].match(/\\begin\s*\{\s*tabular\s*\}([\s\S]+)\\end\s*\{\s*tabular\s*\}/);if(TABinfo!=null){var TABtbody=document.createElement('tbody');var TABrow=null;var TABcell=null;var row=0;var col=0;var TABalign=TABinfo[1].match(/^\s*\{([^\}]+)\}/);TABinfo=TABinfo[1].replace(/^\s*\{[^\}]+\}/,"");TABinfo=TABinfo.replace(/\\hline/g,"");TABalign[1]=TABalign[1].replace(/\|/g,"");TABalign[1]=TABalign[1].replace(/\s/g,"");TABinfo=TABinfo.split("\\\\");for(row=0;row<TABinfo.length;row++){TABrow=document.createElement("tr");TABinfo[row]=TABinfo[row].split("&");for(col=0;col<TABinfo[row].length;col++){TABcell=document.createElement("td");switch(TABalign[1].charAt(col)){case"l":TABcell.align="left";break;case"c":TABcell.align="center";break;case"r":TABcell.align="right";break;default:TABcell.align="left";};TABcell.appendChild(document.createTextNode(TABinfo[row][col]));TABrow.appendChild(TABcell);}+ TABtbody.appendChild(TABrow);}+ nodeTmp.appendChild(TABtbody);}+ newFrag.appendChild(nodeTmp);break;case"logicalbreak":var nodeTmp=document.createElement("p");nodeTmp.className=strtmparray[1];nodeTmp.appendChild(document.createTextNode("\u00A0"));newFrag.appendChild(nodeTmp);break;case"appendix":inAppendix=true;sectionCntr=0;break;case"alistitem":var EndDiv=document.createElement("div");EndDiv.className="endlistitem";newFrag.appendChild(EndDiv);var BegDiv=document.createElement("div");BegDiv.className="listitem";if(strtmparray[1]!=" "){var BegSpan=document.createElement("span");BegSpan.className="listitemmarker";var boldBegSpan=document.createElement("b");boldBegSpan.appendChild(document.createTextNode(strtmparray[1]+" "));BegSpan.appendChild(boldBegSpan);BegDiv.appendChild(BegSpan);}+ newFrag.appendChild(BegDiv);break;case"br":newFrag.appendChild(document.createElement("br"));break;case"bibitem":newFrag.appendChild(document.createElement("br"));var nodeTmp=document.createElement("a");nodeTmp.className='bibitem';var nodeSpan=document.createElement("span");nodeSpan.className='bibitem';bibcntr++;var lbl=strtmparray[1].match(/\{\s*(\w+)\s*\}/);strtmparray[1]=strtmparray[1].replace(/\s*\{\s*\w+\s*\}/g,"");strtmparray[1]=strtmparray[1].replace(/^\s*\[/,"");strtmparray[1]=strtmparray[1].replace(/\s*\]$/,"");strtmparray[1]=strtmparray[1].replace(/^\s+|\s+$/g,"");if(lbl==null){biblist[bibcntr]="bibitem"+bibcntr}else{biblist[bibcntr]=lbl[1];};nodeTmp.name=biblist[bibcntr];nodeTmp.id=biblist[bibcntr];if(strtmparray[1]!=""){nodeSpan.appendChild(document.createTextNode(strtmparray[1]));}else{nodeSpan.appendChild(document.createTextNode("["+bibcntr+"]"));}+ nodeTmp.appendChild(nodeSpan);newFrag.appendChild(nodeTmp);break;case"cite":var nodeTmp=document.createElement("a");nodeTmp.className='cite';nodeTmp.name='cite';nodeTmp.href="#"+strtmparray[1];newFrag.appendChild(nodeTmp);break;case"ref":var nodeTmp=document.createElement("a");nodeTmp.className='ref';nodeTmp.name='ref';nodeTmp.href="#"+strtmparray[1];newFrag.appendChild(nodeTmp);break;default:var nodeTmp=document.createElement("div");nodeTmp.className=strtmparray[0];if(IsCounter.test(strtmparray[0])){LaTeXCounter[strtmparray[0]]++;var nodeAnchor=document.createElement("a");nodeAnchor.className=strtmparray[0];var divnum=makeNumberString(LaTeXCounter[strtmparray[0]]);var anchorSpan=document.createElement("span");anchorSpan.className=strtmparray[0];anchorSpan.appendChild(document.createTextNode(divnum));anchorSpan.style.display="none";nodeAnchor.appendChild(anchorSpan);nodeTmp.appendChild(nodeAnchor);var nodeSpan=document.createElement("span");nodeSpan.className=strtmparray[0];nodeSpan.appendChild(document.createTextNode(strtmparray[1]+" "+divnum+". "));nodeTmp.appendChild(nodeSpan);}+ if(isIE){if(strtmparray[0]==("thebibliography"||"abstract"||"keyword"||"proof")){var nodeSpan=document.createElement("span");nodeSpan.className=strtmparray[0];nodeSpan.appendChild(document.createTextNode(strtmparray[1]));nodeTmp.appendChild(nodeSpan);}}+ if(strtmparray[0]=="endenumerate"||strtmparray[0]=="enditemize"||strtmparray[0]=="enddescription"){var endDiv=document.createElement("div");endDiv.className="endlistitem";newFrag.appendChild(endDiv);}+ newFrag.appendChild(nodeTmp);if(strtmparray[0]=="enumerate"||strtmparray[0]=="itemize"||strtmparray[0]=="description"){var endDiv=document.createElement("div");endDiv.className="listitem";newFrag.appendChild(endDiv);}}}else{strtmp[j]=strtmp[j].replace(/\\\$/g,"<per>");strtmp[j]=strtmp[j].replace(/\$([^\$]+)\$/g," \\[$1\\[ ");strtmp[j]=strtmp[j].replace(/<per>/g,"\\$");strtmp[j]=strtmp[j].replace(/\\begin\s*\{\s*math\s*\}([\s\S]+?)\\end\s*\{\s*math\s*\}/g," \\[$1\\[ ");var strtmptmp=strtmp[j].split("\\[");for(var jjj=0;jjj<strtmptmp.length;jjj++){if(jjj%2){var nodeTmp=document.createElement("span");nodeTmp.className='inlinemath';nodeTmp.appendChild(document.createTextNode("$"+strtmptmp[jjj]+"$"));newFrag.appendChild(nodeTmp);}else{var TagIndex=strtmptmp[jjj].search(/\\\w+/);var tmpIndex=TagIndex;while(tmpIndex>-1){if(/^\\textcolor/.test(strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length))){strtmptmp[jjj]=strtmptmp[jjj].replace(/\\textcolor\s*\{\s*(\w+)\s*\}\s*/," \\[textcolor\\]$1\\]|");}else{if(/^\\colorbox/.test(strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length))){strtmptmp[jjj]=strtmptmp[jjj].replace(/\\colorbox\s*\{\s*(\w+)\s*\}\s*/," \\[colorbox\\]$1\\]|");}else{strtmptmp[jjj]=strtmptmp[jjj].substring(0,TagIndex)+strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).replace(/\\\s*(\w+)\s*/," \\[$1\\]|");}}+ TagIndex+=strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).search(/\|/);TagIndex++;strtmptmp[jjj]=strtmptmp[jjj].replace(/\\\]\|/,"\\] ");if(strtmptmp[jjj].charAt(TagIndex)=="{"){strtmptmp[jjj]=strtmptmp[jjj].substring(0,TagIndex)+strtmptmp[jjj].substring(TagIndex+1,strtmptmp[jjj].length);var delimcnt=1;for(var kk=TagIndex;kk<strtmptmp[jjj].length;kk++){if(strtmptmp[jjj].charAt(kk)=="{"){delimcnt++};if(strtmptmp[jjj].charAt(kk)=="}"){delimcnt--};if(delimcnt==0){break;}}+ strtmptmp[jjj]=strtmptmp[jjj].substring(0,kk)+"\\[ "+strtmptmp[jjj].substring(kk+1,strtmptmp[jjj].length);TagIndex=kk+3;}else{strtmptmp[jjj]=strtmptmp[jjj].substring(0,TagIndex)+"\\[ "+strtmptmp[jjj].substring(TagIndex+1,strtmptmp[jjj].length);TagIndex=TagIndex+3;}+ if(TagIndex<strtmptmp[jjj].length){tmpIndex=strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).search(/\\\w+/);}+ else{tmpIndex=-1};TagIndex+=tmpIndex;}+ strtmptmp[jjj]=strtmptmp[jjj].replace(/\\\\\s*\\\\/g,"\\\\");strtmptmp[jjj]=strtmptmp[jjj].replace(/\\\\/g," \\[br\\] \\[ ");strtmptmp[jjj]=strtmptmp[jjj].replace(/\\label\s*\{\s*(\w+)\s*\}/g," \\[a\\]$1\\[ ");var strlbls=strtmptmp[jjj].split("\\[");for(var jj=0;jj<strlbls.length;jj++){if(jj%2){var strtmparray=strlbls[jj].split("\\]");switch(strtmparray[0]){case"textcolor":var nodeTmp=document.createElement("span");nodeTmp.className='LaTeXColor';if(IsColorName.test(strtmparray[1].toLowerCase())){nodeTmp.style.color=LaTeXColor[strtmparray[1].toLowerCase()];}else{nodeTmp.style.color=strtmparray[1];};nodeTmp.appendChild(document.createTextNode(strtmparray[2]));newFrag.appendChild(nodeTmp);break;case"colorbox":var nodeTmp=document.createElement("span");nodeTmp.className='LaTeXColor';if(IsColorName.test(strtmparray[1].toLowerCase())){nodeTmp.style.background=LaTeXColor[strtmparray[1].toLowerCase()];}else{nodeTmp.style.background=strtmparray[1];};nodeTmp.appendChild(document.createTextNode(strtmparray[2]));newFrag.appendChild(nodeTmp);break;case"br":newFrag.appendChild(document.createElement("br"));break;case"a":var nodeTmp=document.createElement("a");nodeTmp.className='LaTeXMathMLlabel';nodeTmp.id=strtmparray[1];nodeTmp.style.display="none";newFrag.appendChild(nodeTmp);break;default:var nodeTmp=document.createElement("span");nodeTmp.className=strtmparray[0];nodeTmp.appendChild(document.createTextNode(strtmparray[1]))+ newFrag.appendChild(nodeTmp);}}else{newFrag.appendChild(document.createTextNode(strlbls[jj]));}}}}}}}};TheBody.parentNode.replaceChild(newFrag,TheBody);}}}+ return TheBody;}+ function LaTeXDivsAndRefs(thebody){var TheBody=thebody;var EndDivClass=null;var AllDivs=TheBody.getElementsByTagName("div");var lbl2id="";var lblnode=null;for(var i=AllDivs.length-1;i>=0;i--){EndDivClass=AllDivs[i].className.match(/end\w+/);if(EndDivClass!=null){EndDivClass=EndDivClass[0];var DivClass=EndDivClass.substring(3,EndDivClass.length);var EndDivNode=AllDivs[i];break;}}+ while(EndDivClass!=null){var newFrag=document.createDocumentFragment();var RootNode=EndDivNode.parentNode;var ClassCount=1;while(EndDivNode.previousSibling!=null&&ClassCount>0){switch(EndDivNode.previousSibling.className){case EndDivClass:ClassCount++;newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);break;case DivClass:if(EndDivNode.previousSibling.nodeName=="DIV"){ClassCount--;if(lbl2id!=""){EndDivNode.previousSibling.id=lbl2id;lbl2id=""}+ if(ClassCount==0){RootNode=EndDivNode.previousSibling;}else{newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);}};break;case'LaTeXMathMLlabel':lbl2id=EndDivNode.previousSibling.id;EndDivNode.parentNode.removeChild(EndDivNode.previousSibling);break;default:newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);}}+ RootNode.appendChild(newFrag);EndDivNode.parentNode.removeChild(EndDivNode);AllDivs=TheBody.getElementsByTagName("DIV");for(i=AllDivs.length-1;i>=0;i--){EndDivClass=AllDivs[i].className.match(/end\w+/);if(EndDivClass!=null){ClassCount=0;EndDivClass=EndDivClass[0];DivClass=EndDivClass.substring(3,EndDivClass.length);EndDivNode=AllDivs[i];RootNode=EndDivNode.parentNode;break;}}}+ var AllDivs=TheBody.getElementsByTagName("div");var DIV2LI=null;for(var i=0;i<AllDivs.length;i++){if(AllDivs[i].className=="itemize"||AllDivs[i].className=="enumerate"||AllDivs[i].className=="description"){if(AllDivs[i].className=="itemize"){RootNode=document.createElement("UL");}else{RootNode=document.createElement("OL");}+ RootNode.className='LaTeXMathML';if(AllDivs[i].hasChildNodes()){AllDivs[i].removeChild(AllDivs[i].firstChild)};while(AllDivs[i].hasChildNodes()){if(AllDivs[i].firstChild.hasChildNodes()){DIV2LI=document.createElement("LI");while(AllDivs[i].firstChild.hasChildNodes()){DIV2LI.appendChild(AllDivs[i].firstChild.firstChild);}+ if(DIV2LI.firstChild.className=="listitemmarker"){DIV2LI.style.listStyleType="none";}+ RootNode.appendChild(DIV2LI)}+ AllDivs[i].removeChild(AllDivs[i].firstChild);}+ AllDivs[i].appendChild(RootNode);}}+ var AllAnchors=TheBody.getElementsByTagName("a");for(var i=0;i<AllAnchors.length;i++){if(AllAnchors[i].className=="ref"||AllAnchors[i].className=="cite"){var label=AllAnchors[i].href.match(/\#(\w+)/);if(label!=null){var labelNode=document.getElementById(label[1]);if(labelNode!=null){var TheSpans=labelNode.getElementsByTagName("SPAN");if(TheSpans!=null){var refNode=TheSpans[0].cloneNode(true);refNode.style.display="inline"+ refNode.className=AllAnchors[i].className;AllAnchors[i].appendChild(refNode);}}}}}+ return TheBody;}+ var AMbody;var AMnoMathML=false,AMtranslated=false;function translate(spanclassAM){if(!AMtranslated){AMtranslated=true;AMinitSymbols();var LaTeXContainers=[];var AllContainers=document.getElementsByTagName('*');var ExtendName="";for(var k=0,l=0;k<AllContainers.length;k++){ExtendName=" "+AllContainers[k].className+" ";if(ExtendName.match(/\sLaTeX\s/)!=null){LaTeXContainers[l]=AllContainers[k];l++;}};if(LaTeXContainers.length>0){for(var m=0;m<LaTeXContainers.length;m++){AMbody=LaTeXContainers[m];try{AMbody=LaTeXDivsAndRefs(LaTeXpreProcess(AMbody));}catch(err){alert("Unknown Error: Defaulting to Original LaTeXMathML");}+ if(AMbody.tagName=="PRE"){var PreChilds=document.createDocumentFragment();var DivChilds=document.createElement("DIV");while(AMbody.hasChildNodes()){DivChilds.appendChild(AMbody.firstChild);}+ PreChilds.appendChild(DivChilds);AMbody.parentNode.replaceChild(PreChilds,AMbody);AMbody=DivChilds;}+ AMprocessNode(AMbody,false,spanclassAM);}}else{AMbody=document.getElementsByTagName("body")[0];try{AMbody=LaTeXDivsAndRefs(LaTeXpreProcess(AMbody));}catch(err){alert("Unknown Error: Defaulting to Original LaTeXMathML");}+ AMprocessNode(AMbody,false,spanclassAM);}}}+ if(isIE){document.write("<object id=\"mathplayer\" classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>");document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>");}+ function generic()+ {translate();};if(typeof window.addEventListener!='undefined')+ {window.addEventListener('load',generic,false);}+ else if(typeof document.addEventListener!='undefined')+ {document.addEventListener('load',generic,false);}+ else if(typeof window.attachEvent!='undefined')+ {window.attachEvent('onload',generic);}+ else+ {if(typeof window.onload=='function')+ {var existing=onload;window.onload=function()+ {existing();generic();};}+ else+ {window.onload=generic;}}+ /*]]>*/+ </script>+</head>+<body>+<div class="layout">+<div id="controls"></div>+<div id="currentSlide"></div>+<div id="header"></div>+<div id="footer">+ <h1>July 15, 2006</h1>+ <h2>My S5 Document</h2>+</div>+</div>+<div class="presentation">+<div class="titleslide slide">+ <h1>My S5 Document</h1>+ <h2>Sam Smith<br/>Jen Jones</h2>+ <h3>July 15, 2006</h3>+</div>+<div id="first-slide" class="slide section level1">+<h1>First slide</h1>+<ul class="incremental">+<li>first bullet</li>+<li>second bullet</li>+</ul>+</div>+<div id="math" class="slide section level1">+<h1>Math</h1>+<ul class="incremental">+<li><span class="LaTeX">$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</span></li>+</ul>+</div>+</div>+</body>+</html>
@@ -0,0 +1,9 @@+<h1 id="first-slide">First slide</h1>+<ul>+<li>first bullet</li>+<li>second bullet</li>+</ul>+<h1 id="math">Math</h1>+<ul>+<li><span class="math">$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</span></li>+</ul>
@@ -0,0 +1,34 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html xmlns="http://www.w3.org/1999/xhtml">+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+ <meta name="author" content="Sam Smith" />+ <meta name="author" content="Jen Jones" />+ <meta name="date" content="2006-07-15" />+ <title>My S5 Document</title>+ <style type="text/css">code{white-space: pre;}</style>+ <link rel="stylesheet" href="main.css" type="text/css" />+ STUFF INSERTED+</head>+<body>+STUFF INSERTED+<div id="header">+<h1 class="title">My S5 Document</h1>+<h2 class="author">Sam Smith</h2>+<h2 class="author">Jen Jones</h2>+<h3 class="date">July 15, 2006</h3>+</div>+<h1 id="first-slide">First slide</h1>+<ul>+<li>first bullet</li>+<li>second bullet</li>+</ul>+<h1 id="math">Math</h1>+<ul>+<li><span class="math">$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</span></li>+</ul>+STUFF INSERTED+</body>+</html>
@@ -0,0 +1,8 @@+Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "Sam",Space,Str "Smith"],MetaInlines [Str "Jen",Space,Str "Jones"]]),("date",MetaInlines [Str "July",Space,Str "15,",Space,Str "2006"]),("title",MetaInlines [Str "My",Space,Str "S5",Space,Str "Document"])]})+[Header 1 ("first-slide",[],[]) [Str "First",Space,Str "slide"]+,BulletList+ [[Plain [Str "first",Space,Str "bullet"]]+ ,[Plain [Str "second",Space,Str "bullet"]]]+,Header 1 ("math",[],[]) [Str "Math"]+,BulletList+ [[Plain [Math InlineMath "\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"]]]]
@@ -0,0 +1,334 @@+<div class="math scholmd-math-definitions" style="visibility: hidden; height: 0px; width 0px;">\[+\renewcommand{\fx}{f(x)}+\]</div>+<header>+<h1 class="scholmd-title">ScholarlyMarkdown: a Markdown-compatible plaintext format for academic communication</h1>+<div class="scholmd-author">+Tim T.Y. Lin+</div>+<div class="scholmd-date">January 1, 2000</div>+</header>+<div class="scholmd-abstract">+<h2 class="scholmd-abstract-title">Abstract</h2>+<p>This is the abstract! It should show up at the beginning of the page.</p>+</div>+<h2 id="scholarlymarkdown-math-support">ScholarlyMarkdown math support</h2>+<h3 id="math-as-fenced-code-blocks">Math as (fenced) code blocks</h3>+<p>This is a line of text with a <code>simple code block</code> in it.</p>+<p><code>`this should be just a `normal` inline code block surrounded by literal backticks`</code></p>+<p>This is another line of text. Here should be some math: <span class="math scholmd-math-inline">\(\mathbf{F = ma}<2\mathbf{ma}\)</span>. There should be some displaymath environment on the following line +<span class="math scholmd-math-display" style="display: block;">\[+\begin{equation*}+ \mathbf{F = ma} < 2\mathbf{ma}+\end{equation*}+\]</span>+ and there should be no line breaks between the displaymath block and here. <strong>This should be bold</strong>. <em>This should be italic.</em></p>+<p>The following is a displaymath with an aligned environment in a separate paragraph (preceded with, and followed by, two blank lines), with identifier <code>matheqn1</code>. It should automatically be wrapped with the <code>aligned</code> environment.</p>+<p>+<span class="math scholmd-math-display" style="display: block;">\[+\begin{equation}+\label{matheqn1}+\begin{aligned}+\tag{BIGLABEL}+ \mbox{minimize}\quad & \fx = \max_{i=1,\ldots,m} (a_i^T x + b_i) \\+ & \|x\|_2 \le \sigma.+\end{aligned}+\end{equation}+\]</span>+</p>+<p></p>+<p>Here is an implicit align math environment consisting of multiple lines of equations with no newline in between, with at least one <code>&</code> symbol in the whole expression. It should be in the same paragraph as this one. +<span class="math scholmd-math-display" style="display: block;">\[+\begin{align}+\nonumber \sum_{j_1, j_2, \ldots j_m} \sum_{k_1, k_2, \ldots, k_m} & \widetilde{A}_{j_1,k_1}^{\ast} \widetilde{A}_{j_1,k_2} \tilde{A}_{j_2,k_2}^{\ast} \widetilde{A}_{j_2,k_3} \ldots \widetilde{A}_{j_m,k_m}^{\ast} \widetilde{A}_{j_m,k_1}\\+\label{middleAlignMathNumber} = \sum_{j_1, j_2, \ldots j_m} \sum_{k_1, k_2, \ldots, k_m} & \left( R_{\Lambda} T_{k_1}^{\ast} P_{\Omega} T_{j_1} R_{\Lambda}^{\ast} \right) \left( R_{\Lambda} T_{j_1}^{\ast} P_{\Omega} T_{k_2} R_{\Lambda}^{\ast} \right) \left( R_{\Lambda} T_{k_2}^{\ast} P_{\Omega} T_{j_2} R_{\Lambda}^{\ast} \right)\\+\nonumber & \left( R_{\Lambda} T_{j_2}^{\ast} P_{\Omega} T_{k_3} R_{\Lambda}^{\ast} \right) \ldots \left( R_{\Lambda} T_{k_m}^{\ast} P_{\Omega} T_{j_m} R_{\Lambda}^{\ast} \right) \left( R_{\Lambda} T_{j_m}^{\ast} P_{\Omega} T_{k_1} R_{\Lambda}^{\ast} \right).+\end{align}+\]</span>+ And here is an implicit gather math environment consisting of multiple lines of equations with no newline in between, with <code>&</code> symbol not appearing in every statement: +<span class="math scholmd-math-display" style="display: block;">\[+\begin{gather}+\label{firstGatherMathNumber} \left.\begin{aligned}+ B'&=-\partial\times E\\+ E'&=\partial\times B - 4\pi j+ \end{aligned}+ \right\} \quad \textsf{Maxwell's equations}\\+\label{secondGatherMathNumber} A = B\\+\label{thirdgathernumber} AAAAAAA = BBBBBB+\end{gather}+\]</span>+</p>+<p>Single math equations that have line-breaks (the <code>\\</code> command) are automatically wrapped in a <code>split</code> environment. If alignment commands (symbol <code>&</code>) also exist, they get wrapped in an <code>aligned</code> environment instead. This behaviour can be disabled using the <code>math_plain</code> environment: +<span class="math scholmd-math-display" style="display: block;">\[+\begin{equation*}+\begin{split}+y = ax \\+f = kg^{-1}+\end{split}+\end{equation*}+\]</span>+ +<span class="math scholmd-math-display" style="display: block;">\[+\begin{equation*}+\begin{aligned}+y &= ax \\+f &= kg^{-1}+\end{aligned}+\end{equation*}+\]</span>+ The following has an ampersand and line breaks in comma, but is actually a single-line equation that should be untouched: +<span class="math scholmd-math-display" style="display: block;">\[+\begin{equation*}+|y|\ \&\ |x| % an & and \\ that should be ignored+= 99\% z % an & and \\ that should be ignored+\end{equation*}+\]</span>+ Below is more internal vertical alignment tests. The first is one that uses <code>cases</code> internally: +<span class="math scholmd-math-display" style="display: block;">\[+\begin{equation}+\label{matheqn2}+ P_{r-j}=\begin{cases}+ 0& \ensuremath\text{if $r-j$ is odd},\\+ r!\,(-1)^{(r-j)/2}& \text{if $r-j$ is even},+ \end{cases}+\end{equation}+\]</span>+ and another one that uses <code>aligned</code> internally. +<span class="math scholmd-math-display" style="display: block;">\[+\begin{equation}+\label{matheqn3}+ \left.\begin{aligned}+ B'&=-\partial\times E\\+ E'&=\partial\times B - 4\pi j+ \end{aligned}+ \right\}+ \qquad \text{Maxwell's equations}+\end{equation}+\]</span>+</p>+<h3 id="math-and-lists">Math and lists</h3>+<p>Here’s a list with both inline and display math environments:</p>+<ul>+<li>Item 1 is a famous item</li>+<li>Item 2 with a <code>code block</code> and <span class="math scholmd-math-inline">\(\mathsf{\text{inline math}}\)</span> with equation <span class="math scholmd-math-inline">\(\mathbf{y=Ax}\)</span></li>+<li>Item 3+<ul>+<li>Indented item 4</li>+<li>Indented item 5, followed by display math, which cannot be indented: +<span class="math scholmd-math-display" style="display: block;">\[+\begin{equation*}+\mathbf{F_1 = m_1a}+\end{equation*}+\]</span>+ with some text below</li>+<li>Indented item 6, which does not recognize list-item display math surrounded by one additional blank line:</li>+</ul></li>+</ul>+<p>+<span class="math scholmd-math-display" style="display: block;">\[+\begin{equation*}+\mathbf{F_2 = m_2a}+\end{equation*}+\]</span>+</p>+<pre><code> without breaking this text out of the list and into a pre block</code></pre>+<ul>+<li>Item 4+<ol type="1">+<li>Numerical Item 1</li>+<li>Numerical item 2</li>+</ol></li>+</ul>+<h2 id="scholarly-x-refs">Scholarly X-refs</h2>+<h3 id="references-to-figures">References to figures</h3>+<p>This line refers to Figure <span class="scholmd-crossref"><a href="#figure2">3</a></span>.</p>+<p>This line refers to Figure 2.</p>+<p>This line refers to subfigure <span class="scholmd-crossref"><a href="#reginfig3">(2c)</a></span>.</p>+<h3 id="references-to-equations">References to equations</h3>+<p>This line refers to Equation <span class="scholmd-crossref"><span class="math scholmd-math-inline">\(\eqref{matheqn3}\)</span></span>.</p>+<p>Referencing using the <code>\ref</code> tag: Equation <span class="scholmd-crossref"><span class="math scholmd-math-inline">\(\ref{matheqn1}\)</span></span>.</p>+<p>Referencing using the <code>\eqref</code> tag: Equation <span class="scholmd-crossref"><span class="math scholmd-math-inline">\(\eqref{middleAlignMathNumber}\)</span></span>.</p>+<h3 id="automatic-non-breaking-spaces">Automatic non-breaking spaces</h3>+<p>Any cross-references (such as Equation <span class="scholmd-crossref"><span class="math scholmd-math-inline">\(\ref{middleAlignMathNumber}\)</span></span>) will automatically be prepended with non-breaking spaces.</p>+<p>Unless, they appear in a list like equations <span class="scholmd-crossref"><span class="math scholmd-math-inline">\(\ref{matheqn1}\)</span></span>, <span class="scholmd-crossref"><span class="math scholmd-math-inline">\(\ref{matheqn2}\)</span></span>, <span class="scholmd-crossref"><span class="math scholmd-math-inline">\(\ref{matheqn3}\)</span></span>, and <span class="scholmd-crossref"><span class="math scholmd-math-inline">\(\ref{middleAlignMathNumber}\)</span></span>.</p>+<h2 id="scholarlymarkdown-figures">ScholarlyMarkdown Figures</h2>+<h3 id="images-with-attributes">Images with attributes</h3>+<p>The following will be a bunch of figures with attributes: <img src="lunar_orbit.jpg" alt="Regular link with attributes" id="reglink" width="20%" /> <img src="lunar_orbit.jpg" alt="Reference link with attributes" id="reflink" width="20%" /> Which should all show fine and display a picture with a baby seal.</p>+<p>Below is more text so that the css doesn’t end abruptly! Now we’ll have an explicit Scholarly Figure environment!</p>+<h3 id="scholarlymarkdown-figuremultifigures">ScholarlyMarkdown figure/multifigures</h3>+<figure class="scholmd-float scholmd-figure" id="figure0">+<div class="scholmd-float-content"><figure class="scholmd-subfig" style="display: inline-block; width: 50%">+<img src="lunar_orbit.jpg" />+</figure></div>+<div class="scholmd-float-caption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix">Figure</span><span class="scholmd-caption-head-label">1</span></span><span class="scholmd-caption-text">Single-image figure. You can also have citations inside captions <span class="scholmd-citation" data-cites="Gill">[@Gill]</span>.</span></figcaption></div>+</figure>+<figure class="scholmd-float scholmd-figure" id="figure1">+<div class="scholmd-float-content"><figure class="scholmd-subfig" id="reginfig1" style="display: inline-block; width: 20%">+<img src="lunar_orbit.jpg" />+<div class="scholmd-float-subcaption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix"></span><span class="scholmd-caption-head-label">(a)</span></span><span class="scholmd-caption-text">sub</span></figcaption></div>+</figure><figure class="scholmd-subfig" style="display: inline-block; width: 20%">+<img src="lunar_orbit.jpg" />+<div class="scholmd-float-subcaption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix"></span><span class="scholmd-caption-head-label">(b)</span></span><span class="scholmd-caption-text">subfig</span></figcaption></div>+</figure><figure class="scholmd-subfig" id="reginfig3" style="display: inline-block; width: 20%">+<img src="lunar_orbit.jpg" />+<div class="scholmd-float-subcaption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix"></span><span class="scholmd-caption-head-label">(c)</span></span><span class="scholmd-caption-text">longer subcaption that flows</span></figcaption></div>+</figure></div>+<div class="scholmd-float-caption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix">Figure</span><span class="scholmd-caption-head-label">2</span></span><span class="scholmd-caption-text">Reference link in its own paragraph and long caption Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</span></figcaption></div>+</figure>+<figure class="scholmd-float scholmd-figure scholmd-widefloat" id="figure2">+<div class="scholmd-float-content"><figure class="scholmd-subfig" id="reginfig4" style="display: inline-block; width: 40%">+<img src="lunar_orbit.jpg" />+<div class="scholmd-float-subcaption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix"></span><span class="scholmd-caption-head-label">(a)</span></span><span class="scholmd-caption-text">fdsaf</span></figcaption></div>+</figure><figure class="scholmd-subfig" id="reginfig5" style="display: inline-block; width: 30%">+<img src="lunar_orbit.jpg" />+<div class="scholmd-float-subcaption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix"></span><span class="scholmd-caption-head-label">(b)</span></span><span class="scholmd-caption-text">woogawooga</span></figcaption></div>+</figure></div>+<div class="scholmd-float-caption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix">Figure</span><span class="scholmd-caption-head-label">3</span></span><span class="scholmd-caption-text">Reference link in its own paragraph and long caption Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</span></figcaption></div>+</figure>+<h2 id="scholarlymarkdown-algorithms">ScholarlyMarkdown Algorithms</h2>+<p>Here are some algorithms using various methods. The “most canonical one” is currently just using a line-block:</p>+<figure class="scholmd-float scholmd-algorithm" id="alg:gs">+<div class="scholmd-float-content"><p><code> 1.</code> <strong>Inputs</strong>: variables <span class="math scholmd-math-inline">\(A, b\)</span><br /><code> 2.</code> <strong>Output</strong>: <span class="math scholmd-math-inline">\(\phi\)</span> <code>//this is a comment</code></p>+<p><code> 3.</code> Choose an initial guess <span class="math scholmd-math-inline">\(\phi\)</span> to the solution<br /><code> 4.</code> <strong>repeat</strong> until convergence<br /><code> 5.</code> <strong>for</strong> <span class="math scholmd-math-inline">\(i\)</span> <strong>from</strong> 1 <strong>until</strong> <span class="math scholmd-math-inline">\(n\)</span> <strong>do</strong><br /><code> 6.</code> <span class="math scholmd-math-inline">\(\sigma \leftarrow 0\)</span><br /><code> 7.</code> <strong>for</strong> <span class="math scholmd-math-inline">\(j\)</span> <strong>from</strong> 1 <strong>until</strong> <span class="math scholmd-math-inline">\(n\)</span> <strong>do</strong><br /><code> 8.</code> <strong>if</strong> <span class="math scholmd-math-inline">\(j \ne i\)</span> <strong>then</strong><br /><code> 9.</code> <span class="math scholmd-math-inline">\(\sigma \leftarrow \sigma + a_{ij} \phi_j\)</span><br /><code>10.</code> <strong>end if</strong><br /><code>11.</code> <strong>end</strong> (<span class="math scholmd-math-inline">\(j\)</span>-loop)<br /><code>12.</code> <span class="math scholmd-math-inline">\(\phi_i \leftarrow \frac 1 {a_{ii}} (b_i - \sigma)\)</span><br /><code>13.</code> <strong>end</strong> (<span class="math scholmd-math-inline">\(i\)</span>-loop)<br /><code>14.</code> check if convergence is reached<br /><code>15.</code> <strong>end</strong> (repeat)</p></div>+<div class="scholmd-float-caption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix">Algorithm</span><span class="scholmd-caption-head-label">1</span></span><span class="scholmd-caption-text">caption for this algorithm</span></figcaption></div>+</figure>+<figure class="scholmd-float scholmd-algorithm" id="alg:gs2">+<div class="scholmd-float-content"><p> <strong>Inputs</strong>: variables <span class="math scholmd-math-inline">\(A, b\)</span><br /> <strong>Output</strong>: <span class="math scholmd-math-inline">\(\phi\)</span></p>+<p> Choose an initial guess <span class="math scholmd-math-inline">\(\phi\)</span> to the solution<br /> <strong>repeat</strong> until convergence<br /> <strong>for</strong> <span class="math scholmd-math-inline">\(i\)</span> from 1 to <span class="math scholmd-math-inline">\(n\)</span> <strong>do</strong><br /> <span class="math scholmd-math-inline">\(\sigma \leftarrow 0\)</span><br /> <strong>for</strong> <span class="math scholmd-math-inline">\(j\)</span> from 1 to <span class="math scholmd-math-inline">\(n\)</span> <strong>do</strong><br /> <strong>if</strong> <span class="math scholmd-math-inline">\(j \ne i\)</span> <strong>then</strong><br /> <span class="math scholmd-math-inline">\(\sigma \leftarrow \sigma + a_{ij} \phi_j\)</span><br /> <strong>end if</strong><br /> <strong>end</strong> (<span class="math scholmd-math-inline">\(j\)</span>-loop)<br /> <span class="math scholmd-math-inline">\(\phi_i \leftarrow \frac 1 {a_{ii}} (b_i - \sigma)\)</span><br /> <strong>end</strong> (<span class="math scholmd-math-inline">\(i\)</span>-loop)<br /> check if convergence is reached<br /> <strong>end</strong> (repeat)</p></div>+<div class="scholmd-float-caption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix">Algorithm</span><span class="scholmd-caption-head-label">2</span></span></figcaption></div>+</figure>+<p>The should not be a caption</p>+<figure class="scholmd-float scholmd-algorithm" id="alg:gs3">+<div class="scholmd-float-content"><p> <strong>Inputs</strong>: variables <span class="math scholmd-math-inline">\(A, b\)</span><br /> <strong>Output</strong>: <span class="math scholmd-math-inline">\(\phi\)</span></p>+<p> Choose an initial guess <span class="math scholmd-math-inline">\(\phi\)</span> to the solution<br /> <strong>repeat</strong> until convergence<br /> <strong>for</strong> <span class="math scholmd-math-inline">\(i\)</span> from 1 to <span class="math scholmd-math-inline">\(n\)</span> <strong>do</strong><br /> <span class="math scholmd-math-inline">\(\sigma \leftarrow 0\)</span><br /> <strong>for</strong> <span class="math scholmd-math-inline">\(j\)</span> from 1 to <span class="math scholmd-math-inline">\(n\)</span> <strong>do</strong><br /> <strong>if</strong> <span class="math scholmd-math-inline">\(j \ne i\)</span> <strong>then</strong><br /> <span class="math scholmd-math-inline">\(\sigma \leftarrow \sigma + a_{ij} \phi_j\)</span><br /> <strong>end if</strong><br /> <strong>end</strong> (<span class="math scholmd-math-inline">\(j\)</span>-loop)<br /> <span class="math scholmd-math-inline">\(\phi_i \leftarrow \frac 1 {a_{ii}} (b_i - \sigma)\)</span><br /> <strong>end</strong> (<span class="math scholmd-math-inline">\(i\)</span>-loop)<br /> check if convergence is reached<br /> <strong>end</strong> (repeat)</p></div>+<div class="scholmd-float-caption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix">Algorithm</span><span class="scholmd-caption-head-label">3</span></span><span class="scholmd-caption-text">This should should be a caption</span></figcaption></div>+</figure>+<h2 id="scholarlymarkdown-tables">ScholarlyMarkdown Tables</h2>+<h3 id="standard-pandoc-tables">Standard Pandoc tables</h3>+<p>The following is a normal Pandoc table</p>+<table>+<caption>Thisis a caption</caption>+<thead>+<tr class="header">+<th style="text-align: right;">Right</th>+<th style="text-align: left;">Left</th>+<th style="text-align: left;">Default</th>+<th style="text-align: center;">Center</th>+</tr>+</thead>+<tbody>+<tr class="odd">+<td style="text-align: right;">12</td>+<td style="text-align: left;">12</td>+<td style="text-align: left;">12</td>+<td style="text-align: center;">12</td>+</tr>+<tr class="even">+<td style="text-align: right;">123</td>+<td style="text-align: left;">123</td>+<td style="text-align: left;">123</td>+<td style="text-align: center;">123</td>+</tr>+<tr class="odd">+<td style="text-align: right;">1</td>+<td style="text-align: left;">1</td>+<td style="text-align: left;">1</td>+<td style="text-align: center;">1</td>+</tr>+</tbody>+</table>+<p>This should not be a caption</p>+<h3 id="scholarly-tables">Scholarly tables</h3>+<p>The following is a floated ScholMD table</p>+<figure class="scholmd-float scholmd-table-float" id="tab:exscholmd">+<div class="scholmd-float-content"><table>+<thead>+<tr class="header">+<th style="text-align: right;">Right</th>+<th style="text-align: left;">Left</th>+<th style="text-align: left;">Default</th>+<th style="text-align: center;">Center</th>+</tr>+</thead>+<tbody>+<tr class="odd">+<td style="text-align: right;">12</td>+<td style="text-align: left;">12</td>+<td style="text-align: left;">12</td>+<td style="text-align: center;">12</td>+</tr>+<tr class="even">+<td style="text-align: right;">123</td>+<td style="text-align: left;">123</td>+<td style="text-align: left;">123</td>+<td style="text-align: center;">123</td>+</tr>+<tr class="odd">+<td style="text-align: right;">1</td>+<td style="text-align: left;">1</td>+<td style="text-align: left;">1</td>+<td style="text-align: center;">1</td>+</tr>+</tbody>+</table></div>+<div class="scholmd-float-caption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix">Table</span><span class="scholmd-caption-head-label">1</span></span><span class="scholmd-caption-text">This is a really really really really really really really really really really really really really really really really really really really really really really really really really really really long caption</span></figcaption></div>+</figure>+<h2 id="scholarlymarkdown-code-blocks">ScholarlyMarkdown Code blocks</h2>+<h3 id="standard-pandoc-code-blocks">Standard Pandoc code blocks</h3>+<h4 id="fenced-blocks">fenced blocks</h4>+<pre><code>Value <- [0-9.]+ / '(' Expr ')'+Product <- Expr (('*' / '/') Expr)*+Sum <- Expr (('+' / '-') Expr)*+Expr <- Product / Sum / Value</code></pre>+<h4 id="indented-blocks">indented blocks</h4>+<pre><code>Value <- [0-9.]+ / '(' Expr ')'+Product <- Expr (('*' / '/') Expr)*+Sum <- Expr (('+' / '-') Expr)*+Expr <- Product / Sum / Value</code></pre>+<h3 id="scholarly-code-block-floats">Scholarly code block floats</h3>+<figure class="scholmd-float scholmd-listing-float" id="lst:pegcalc">+<div class="scholmd-float-content"><table class="sourceCode c numberLines" startFrom="100"><tr class="sourceCode"><td class="lineNumbers"><pre>100+101+102+103+</pre></td><td class="sourceCode"><pre><code class="sourceCode c">Value <- [<span class="dv">0-9</span>.]+ / '(' Expr ')'+Product <- Expr (('*' / '/') Expr)*+Sum <- Expr (('+' / '-') Expr)*+Expr <- Product / Sum / Value</code></pre></td></tr></table></div>+<div class="scholmd-float-caption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix">Listing</span><span class="scholmd-caption-head-label">1</span></span><span class="scholmd-caption-text"><a href="http://en.wikipedia.org/wiki/Parsing_expression_grammar">Parsing Expression Grammar</a> rules for a simple calculator using PEG.</span></figcaption></div>+</figure>+<figure class="scholmd-float scholmd-listing-float" id="lst:pegcalc">+<div class="scholmd-float-content"><pre><code>Value <- [0-9.]+ / '(' Expr ')'+Product <- Expr (('*' / '/') Expr)*+Sum <- Expr (('+' / '-') Expr)*+Expr <- Product / Sum / Value</code></pre></div>+<div class="scholmd-float-caption"><figcaption><span class="scholmd-caption-head"><span class="scholmd-caption-head-prefix">Listing</span><span class="scholmd-caption-head-label">2</span></span><span class="scholmd-caption-text"><a href="http://en.wikipedia.org/wiki/Parsing_expression_grammar">Parsing Expression Grammar</a> rules for a simple calculator.</span></figcaption></div>+</figure>++<script type="text/x-mathjax-config">+MathJax.Hub.Config({+ tex2jax: {+ processClass: "math"+ },+ TeX: {+ TagSide: "left",+ TagIndent: "1.2em",+ equationNumbers: {+ autoNumber: "AMS"+ },+ Macros: {+ ensuremath: ["#1",1],+ textsf: ["\\mathsf{\\text{#1}}",1],+ texttt: ["\\mathtt{\\text{#1}}",1]+ }+ },+ "HTML-CSS": { + scale: 100,+ availableFonts: ["TeX"], + preferredFont: "TeX",+ webFont: "TeX",+ imageFont: "TeX",+ EqnChunk: 1000+ }+});+</script>
@@ -0,0 +1,366 @@+\section{ScholarlyMarkdown math+support}\label{scholarlymarkdown-math-support}++\subsection{Math as (fenced) code+blocks}\label{math-as-fenced-code-blocks}++This is a line of text with a \texttt{simple code block} in it.++\texttt{`this should be just a `normal` inline code block surrounded by literal backticks`}++This is another line of text. Here should be some math:+$\mathbf{F = ma}<2\mathbf{ma}$. There should be some displaymath+environment on the following line+%+\begin{equation*}+ \mathbf{F = ma} < 2\mathbf{ma}+\end{equation*}+%+ and there should be no line breaks between the displaymath block and+here. \textbf{This should be bold}. \emph{This should be italic.}++The following is a displaymath with an aligned environment in a separate+paragraph (preceded with, and followed by, two blank lines), with+identifier \texttt{matheqn1}. It should automatically be wrapped with+the \texttt{aligned} environment.++%+\begin{equation}+\label{matheqn1}+\begin{aligned}+\tag{BIGLABEL}+ \mbox{minimize}\quad & \fx = \max_{i=1,\ldots,m} (a_i^T x + b_i) \\+ & \|x\|_2 \le \sigma.+\end{aligned}+\end{equation}+%++Here is an implicit align math environment consisting of multiple lines+of equations with no newline in between, with at least one \texttt{\&}+symbol in the whole expression. It should be in the same paragraph as+this one.+%+\begin{align}+\nonumber \sum_{j_1, j_2, \ldots j_m} \sum_{k_1, k_2, \ldots, k_m} & \widetilde{A}_{j_1,k_1}^{\ast} \widetilde{A}_{j_1,k_2} \tilde{A}_{j_2,k_2}^{\ast} \widetilde{A}_{j_2,k_3} \ldots \widetilde{A}_{j_m,k_m}^{\ast} \widetilde{A}_{j_m,k_1}\\+\label{middleAlignMathNumber} = \sum_{j_1, j_2, \ldots j_m} \sum_{k_1, k_2, \ldots, k_m} & \left( R_{\Lambda} T_{k_1}^{\ast} P_{\Omega} T_{j_1} R_{\Lambda}^{\ast} \right) \left( R_{\Lambda} T_{j_1}^{\ast} P_{\Omega} T_{k_2} R_{\Lambda}^{\ast} \right) \left( R_{\Lambda} T_{k_2}^{\ast} P_{\Omega} T_{j_2} R_{\Lambda}^{\ast} \right)\\+\nonumber & \left( R_{\Lambda} T_{j_2}^{\ast} P_{\Omega} T_{k_3} R_{\Lambda}^{\ast} \right) \ldots \left( R_{\Lambda} T_{k_m}^{\ast} P_{\Omega} T_{j_m} R_{\Lambda}^{\ast} \right) \left( R_{\Lambda} T_{j_m}^{\ast} P_{\Omega} T_{k_1} R_{\Lambda}^{\ast} \right).+\end{align}+%+ And here is an implicit gather math environment consisting of multiple+lines of equations with no newline in between, with \texttt{\&} symbol+not appearing in every statement:+%+\begin{gather}+\label{firstGatherMathNumber} \left.\begin{aligned}+ B'&=-\partial\times E\\+ E'&=\partial\times B - 4\pi j+ \end{aligned}+ \right\} \quad \textsf{Maxwell's equations}\\+\label{secondGatherMathNumber} A = B\\+\label{thirdgathernumber} AAAAAAA = BBBBBB+\end{gather}+%++Single math equations that have line-breaks (the+\texttt{\textbackslash{}\textbackslash{}} command) are automatically+wrapped in a \texttt{split} environment. If alignment commands (symbol+\texttt{\&}) also exist, they get wrapped in an \texttt{aligned}+environment instead. This behaviour can be disabled using the+\texttt{math\_plain} environment:+%+\begin{equation*}+\begin{split}+y = ax \\+f = kg^{-1}+\end{split}+\end{equation*}+%+%+\begin{equation*}+\begin{aligned}+y &= ax \\+f &= kg^{-1}+\end{aligned}+\end{equation*}+%+ The following has an ampersand and line breaks in comma, but is+actually a single-line equation that should be untouched:+%+\begin{equation*}+|y|\ \&\ |x| % an & and \\ that should be ignored+= 99\% z % an & and \\ that should be ignored+\end{equation*}+%+ Below is more internal vertical alignment tests. The first is one that+uses \texttt{cases} internally:+%+\begin{equation}+\label{matheqn2}+ P_{r-j}=\begin{cases}+ 0& \ensuremath\text{if $r-j$ is odd},\\+ r!\,(-1)^{(r-j)/2}& \text{if $r-j$ is even},+ \end{cases}+\end{equation}+%+ and another one that uses \texttt{aligned} internally.+%+\begin{equation}+\label{matheqn3}+ \left.\begin{aligned}+ B'&=-\partial\times E\\+ E'&=\partial\times B - 4\pi j+ \end{aligned}+ \right\}+ \qquad \text{Maxwell's equations}+\end{equation}+%++\subsection{Math and lists}\label{math-and-lists}++Here's a list with both inline and display math environments:++\begin{itemize}+\itemsep1pt\parskip0pt\parsep0pt+\item+ Item 1 is a famous item+\item+ Item 2 with a \texttt{code block} and $\mathsf{\text{inline math}}$+ with equation $\mathbf{y=Ax}$+\item+ Item 3++ \begin{itemize}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ Indented item 4+ \item+ Indented item 5, followed by display math, which cannot be indented:+ %+ \begin{equation*}+ \mathbf{F_1 = m_1a}+ \end{equation*}+ %+ with some text below+ \item+ Indented item 6, which does not recognize list-item display math+ surrounded by one additional blank line:+ \end{itemize}+\end{itemize}++%+\begin{equation*}+\mathbf{F_2 = m_2a}+\end{equation*}+%++\begin{verbatim}+ without breaking this text out of the list and into a pre block+\end{verbatim}++\begin{itemize}+\itemsep1pt\parskip0pt\parsep0pt+\item+ Item 4++ \begin{enumerate}+ \def\labelenumi{\arabic{enumi}.}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ Numerical Item 1+ \item+ Numerical item 2+ \end{enumerate}+\end{itemize}++\section{Scholarly X-refs}\label{scholarly-x-refs}++\subsection{References to figures}\label{references-to-figures}++This line refers to Figure~\ref{figure2}.++This line refers to Figure 2.++This line refers to subfigure~\eqref{reginfig3}.++\subsection{References to equations}\label{references-to-equations}++This line refers to Equation~\eqref{matheqn3}.++Referencing using the \texttt{\textbackslash{}ref} tag:+Equation~\ref{matheqn1}.++Referencing using the \texttt{\textbackslash{}eqref} tag:+Equation~\eqref{middleAlignMathNumber}.++\subsection{Automatic non-breaking+spaces}\label{automatic-non-breaking-spaces}++Any cross-references (such as Equation~\ref{middleAlignMathNumber}) will+automatically be prepended with non-breaking spaces.++Unless, they appear in a list like equations~\ref{matheqn1},+\ref{matheqn2}, \ref{matheqn3}, and~\ref{middleAlignMathNumber}.++\section{ScholarlyMarkdown Figures}\label{scholarlymarkdown-figures}++\subsection{Images with attributes}\label{images-with-attributes}++The following will be a bunch of figures with attributes:+\includegraphics[width=0.200\textwidth]{lunar_orbit.jpg}+\includegraphics[width=0.200\textwidth]{lunar_orbit.jpg} Which should+all show fine and display a picture with a baby seal.++Below is more text so that the css doesn't end abruptly! Now we'll have+an explicit Scholarly Figure environment!++\subsection{ScholarlyMarkdown+figure/multifigures}\label{scholarlymarkdown-figuremultifigures}++\begin{figure}+\centering+\includegraphics[width=0.500\hsize]{lunar_orbit.jpg}+\caption{Single-image figure. You can also have citations inside+captions {[}@Gill{]}.}\label{figure0}+\end{figure}++\begin{figure}+\centering+\subfloat[sub\label{reginfig1}]{\includegraphics[width=0.200\hsize]{lunar_orbit.jpg}}+\subfloat[subfig]{\includegraphics[width=0.200\hsize]{lunar_orbit.jpg}}+\subfloat[longer subcaption that+flows\label{reginfig3}]{\includegraphics[width=0.200\hsize]{lunar_orbit.jpg}}+\caption{Reference link in its own paragraph and long caption Lorem+ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy+nibh euismod tincidunt ut laoreet dolore magna aliquam erat+volutpat.}\label{figure1}+\end{figure}++\begin{figure*}+\centering+\subfloat[fdsaf\label{reginfig4}]{\includegraphics[width=0.400\hsize]{lunar_orbit.jpg}}+\subfloat[woogawooga\label{reginfig5}]{\includegraphics[width=0.300\hsize]{lunar_orbit.jpg}}+\caption{Reference link in its own paragraph and long caption Lorem+ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy+nibh euismod tincidunt ut laoreet dolore magna aliquam erat+volutpat.}\label{figure2}+\end{figure*}++\section{ScholarlyMarkdown+Algorithms}\label{scholarlymarkdown-algorithms}++Here are some algorithms using various methods. The ``most canonical+one'' is currently just using a line-block:++\begin{scholmdAlgorithm}+\texttt{ 1.}~\textbf{Inputs}:~variables~$A, b$\\\texttt{ 2.}~\textbf{Output}:~$\phi$~~~~~~~~~~~~~~~~\texttt{//this is a comment}++\texttt{ 3.}~Choose~an~initial~guess~$\phi$~to~the~solution\\\texttt{ 4.}~~\textbf{repeat}~until~convergence\\\texttt{ 5.}~~~~\textbf{for}~$i$~\textbf{from}~1~\textbf{until}~$n$~\textbf{do}\\\texttt{ 6.}~~~~~~~~$\sigma \leftarrow 0$\\\texttt{ 7.}~~~~~~~~\textbf{for}~$j$~\textbf{from}~1~\textbf{until}~$n$~\textbf{do}\\\texttt{ 8.}~~~~~~~~~~~~\textbf{if}~$j \ne i$~\textbf{then}\\\texttt{ 9.}~~~~~~~~~~~~~~~$\sigma \leftarrow \sigma + a_{ij} \phi_j$\\\texttt{10.}~~~~~~~~~~~~\textbf{end~if}\\\texttt{11.}~~~~~~~~\textbf{end}~($j$-loop)\\\texttt{12.}~~~~~~~~$\phi_i \leftarrow \frac 1 {a_{ii}} (b_i - \sigma)$\\\texttt{13.}~~~~\textbf{end}~($i$-loop)\\\texttt{14.}~~~~check~if~convergence~is~reached\\\texttt{15.}~\textbf{end}~(repeat)+\caption{caption for this algorithm}\label{alg:gs}+\end{scholmdAlgorithm}++\begin{scholmdAlgorithm}+~\textbf{Inputs}:~variables~$A, b$\\\hspace*{0.333em}\textbf{Output}:~$\phi$++~Choose~an~initial~guess~$\phi$~to~the~solution\\\hspace*{0.333em}\textbf{repeat}~until~convergence\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{for}~$i$~from~1~to~$n$~\textbf{do}\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}$\sigma \leftarrow 0$\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{for}~$j$~from~1~to~$n$~\textbf{do}\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{if}~$j \ne i$~\textbf{then}\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}$\sigma \leftarrow \sigma + a_{ij} \phi_j$\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{end~if}\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{end}~($j$-loop)\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}$\phi_i \leftarrow \frac 1 {a_{ii}} (b_i - \sigma)$\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{end}~($i$-loop)\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}check~if~convergence~is~reached\\\hspace*{0.333em}\textbf{end}~(repeat)+\label{alg:gs2}+\end{scholmdAlgorithm}++The should not be a caption++\begin{scholmdAlgorithm}+~\textbf{Inputs}:~variables~$A, b$\\\hspace*{0.333em}\textbf{Output}:~$\phi$++~Choose~an~initial~guess~$\phi$~to~the~solution\\\hspace*{0.333em}\textbf{repeat}~until~convergence\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{for}~$i$~from~1~to~$n$~\textbf{do}\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}$\sigma \leftarrow 0$\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{for}~$j$~from~1~to~$n$~\textbf{do}\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{if}~$j \ne i$~\textbf{then}\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}$\sigma \leftarrow \sigma + a_{ij} \phi_j$\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{end~if}\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{end}~($j$-loop)\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}$\phi_i \leftarrow \frac 1 {a_{ii}} (b_i - \sigma)$\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\textbf{end}~($i$-loop)\\\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}\hspace*{0.333em}check~if~convergence~is~reached\\\hspace*{0.333em}\textbf{end}~(repeat)+\caption{This should should be a caption}\label{alg:gs3}+\end{scholmdAlgorithm}++\section{ScholarlyMarkdown Tables}\label{scholarlymarkdown-tables}++\subsection{Standard Pandoc tables}\label{standard-pandoc-tables}++The following is a normal Pandoc table++\begin{longtable}[c]{@{}rllc@{}}+\caption{Thisis a caption}\tabularnewline+\toprule+Right & Left & Default & Center\tabularnewline+\midrule+\endfirsthead+\toprule+Right & Left & Default & Center\tabularnewline+\midrule+\endhead+12 & 12 & 12 & 12\tabularnewline+123 & 123 & 123 & 123\tabularnewline+1 & 1 & 1 & 1\tabularnewline+\bottomrule+\end{longtable}++This should not be a caption++\subsection{Scholarly tables}\label{scholarly-tables}++The following is a floated ScholMD table++\begin{table}+\centering+\begin{tabular}{rllc}+\toprule\addlinespace+Right & Left & Default & Center\tabularnewline+\midrule+12 & 12 & 12 & 12\tabularnewline+123 & 123 & 123 & 123\tabularnewline+1 & 1 & 1 & 1\tabularnewline+\bottomrule+\end{tabular}+\caption{This is a really really really really really really really+really really really really really really really really really really+really really really really really really really really really really+long caption}\label{tab:exscholmd}+\end{table}++\section{ScholarlyMarkdown Code+blocks}\label{scholarlymarkdown-code-blocks}++\subsection{Standard Pandoc code+blocks}\label{standard-pandoc-code-blocks}++\subsubsection{fenced blocks}\label{fenced-blocks}++\begin{verbatim}+Value <- [0-9.]+ / '(' Expr ')'+Product <- Expr (('*' / '/') Expr)*+Sum <- Expr (('+' / '-') Expr)*+Expr <- Product / Sum / Value+\end{verbatim}++\subsubsection{indented blocks}\label{indented-blocks}++\begin{verbatim}+Value <- [0-9.]+ / '(' Expr ')'+Product <- Expr (('*' / '/') Expr)*+Sum <- Expr (('+' / '-') Expr)*+Expr <- Product / Sum / Value+\end{verbatim}++\subsection{Scholarly code block+floats}\label{scholarly-code-block-floats}++\begin{lstlisting}[caption={\href{http://en.wikipedia.org/wiki/Parsing_expression_grammar}{Parsing+Expression Grammar} rules for a simple calculator using+PEG.}, language=C, numbers=left, firstnumber=100, label=lst:pegcalc, float=htbp]+Value <- [0-9.]+ / '(' Expr ')'+Product <- Expr (('*' / '/') Expr)*+Sum <- Expr (('+' / '-') Expr)*+Expr <- Product / Sum / Value+\end{lstlisting}++\begin{lstlisting}[caption={\href{http://en.wikipedia.org/wiki/Parsing_expression_grammar}{Parsing+Expression Grammar} rules for a simple+calculator.}, label=lst:pegcalc, float=htbp]+Value <- [0-9.]+ / '(' Expr ')'+Product <- Expr (('*' / '/') Expr)*+Sum <- Expr (('+' / '-') Expr)*+Expr <- Product / Sum / Value+\end{lstlisting}+
@@ -0,0 +1,87 @@+Pandoc (Meta {unMeta = fromList [("abstract",MetaBlocks [Para [Str "This",Space,Str "is",Space,Str "the",Space,Str "abstract!",Space,Str "It",Space,Str "should",Space,Str "show",Space,Str "up",Space,Str "at",Space,Str "the",Space,Str "beginning",Space,Str "of",Space,Str "the",Space,Str "page."]]),("author",MetaInlines [Str "Tim",Space,Str "T.Y.",Space,Str "Lin"]),("bibliography",MetaString "scholdoc_bibtex_file.bib"),("date",MetaInlines [Str "January",Space,Str "1,",Space,Str "2000"]),("identifiersForMath",MetaList [MetaString "",MetaString "matheqn1",MetaString "",MetaString "middleAlignMathNumber",MetaString "",MetaString "firstGatherMathNumber",MetaString "secondGatherMathNumber",MetaString "thirdgathernumber",MetaString "",MetaString "",MetaString "",MetaString "matheqn2",MetaString "matheqn3",MetaString "",MetaString ""]),("latexMacrosForMath",MetaString "\\renewcommand{\\fx}{f(x)}\n"),("tags",MetaList [MetaInlines [Str "test"],MetaInlines [Str "markdown"],MetaInlines [Str "scholarly"]]),("title",MetaInlines [Str "ScholarlyMarkdown:",Space,Str "a",Space,Str "Markdown-compatible",Space,Str "plaintext",Space,Str "format",Space,Str "for",Space,Str "academic",Space,Str "communication"])]})+[Header 2 ("scholarlymarkdown-math-support",[],[]) [Str "ScholarlyMarkdown",Space,Str "math",Space,Str "support"]+,Header 3 ("math-as-fenced-code-blocks",[],[]) [Str "Math",Space,Str "as",Space,Str "(fenced)",Space,Str "code",Space,Str "blocks"]+,Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "line",Space,Str "of",Space,Str "text",Space,Str "with",Space,Str "a",Space,Code ("",[],[]) "simple code block",Space,Str "in",Space,Str "it."]+,Para [Code ("",[],[]) "`this should be just a `normal` inline code block surrounded by literal backticks`"]+,Para [Str "This",Space,Str "is",Space,Str "another",Space,Str "line",Space,Str "of",Space,Str "text.",Space,Str "Here",Space,Str "should",Space,Str "be",Space,Str "some",Space,Str "math:",Space,Math InlineMath "\\mathbf{F = ma}<2\\mathbf{ma}",Str ".",Space,Str "There",Space,Str "should",Space,Str "be",Space,Str "some",Space,Str "displaymath",Space,Str "environment",Space,Str "on",Space,Str "the",Space,Str "following",Space,Str "line",Space,Math (DisplayMath ("",["math"],[])) " \\mathbf{F = ma} < 2\\mathbf{ma}",Space,Str "and",Space,Str "there",Space,Str "should",Space,Str "be",Space,Str "no",Space,Str "line",Space,Str "breaks",Space,Str "between",Space,Str "the",Space,Str "displaymath",Space,Str "block",Space,Str "and",Space,Str "here.",Space,Strong [Str "This",Space,Str "should",Space,Str "be",Space,Str "bold"],Str ".",Space,Emph [Str "This",Space,Str "should",Space,Str "be",Space,Str "italic."]]+,Para [Str "The",Space,Str "following",Space,Str "is",Space,Str "a",Space,Str "displaymath",Space,Str "with",Space,Str "an",Space,Str "aligned",Space,Str "environment",Space,Str "in",Space,Str "a",Space,Str "separate",Space,Str "paragraph",Space,Str "(preceded",Space,Str "with,",Space,Str "and",Space,Str "followed",Space,Str "by,",Space,Str "two",Space,Str "blank",Space,Str "lines),",Space,Str "with",Space,Str "identifier",Space,Code ("",[],[]) "matheqn1",Str ".",Space,Str "It",Space,Str "should",Space,Str "automatically",Space,Str "be",Space,Str "wrapped",Space,Str "with",Space,Str "the",Space,Code ("",[],[]) "aligned",Space,Str "environment."]+,Para [Math (DisplayMath ("matheqn1",["math"],[])) "\\label{matheqn1}\n\\begin{aligned}\n\\tag{BIGLABEL}\n \\mbox{minimize}\\quad & \\fx = \\max_{i=1,\\ldots,m} (a_i^T x + b_i) \\\\\n & \\|x\\|_2 \\le \\sigma.\n\\end{aligned}"]+,Para []+,Para [Str "Here",Space,Str "is",Space,Str "an",Space,Str "implicit",Space,Str "align",Space,Str "math",Space,Str "environment",Space,Str "consisting",Space,Str "of",Space,Str "multiple",Space,Str "lines",Space,Str "of",Space,Str "equations",Space,Str "with",Space,Str "no",Space,Str "newline",Space,Str "in",Space,Str "between,",Space,Str "with",Space,Str "at",Space,Str "least",Space,Str "one",Space,Code ("",[],[]) "&",Space,Str "symbol",Space,Str "in",Space,Str "the",Space,Str "whole",Space,Str "expression.",Space,Str "It",Space,Str "should",Space,Str "be",Space,Str "in",Space,Str "the",Space,Str "same",Space,Str "paragraph",Space,Str "as",Space,Str "this",Space,Str "one.",Space,Math (DisplayMath ("",["math","align"],[("labelList","[\"\",\"middleAlignMathNumber\",\"\"]")])) "\\nonumber \\sum_{j_1, j_2, \\ldots j_m} \\sum_{k_1, k_2, \\ldots, k_m} & \\widetilde{A}_{j_1,k_1}^{\\ast} \\widetilde{A}_{j_1,k_2} \\tilde{A}_{j_2,k_2}^{\\ast} \\widetilde{A}_{j_2,k_3} \\ldots \\widetilde{A}_{j_m,k_m}^{\\ast} \\widetilde{A}_{j_m,k_1}\\\\\n\\label{middleAlignMathNumber} = \\sum_{j_1, j_2, \\ldots j_m} \\sum_{k_1, k_2, \\ldots, k_m} & \\left( R_{\\Lambda} T_{k_1}^{\\ast} P_{\\Omega} T_{j_1} R_{\\Lambda}^{\\ast} \\right) \\left( R_{\\Lambda} T_{j_1}^{\\ast} P_{\\Omega} T_{k_2} R_{\\Lambda}^{\\ast} \\right) \\left( R_{\\Lambda} T_{k_2}^{\\ast} P_{\\Omega} T_{j_2} R_{\\Lambda}^{\\ast} \\right)\\\\\n\\nonumber & \\left( R_{\\Lambda} T_{j_2}^{\\ast} P_{\\Omega} T_{k_3} R_{\\Lambda}^{\\ast} \\right) \\ldots \\left( R_{\\Lambda} T_{k_m}^{\\ast} P_{\\Omega} T_{j_m} R_{\\Lambda}^{\\ast} \\right) \\left( R_{\\Lambda} T_{j_m}^{\\ast} P_{\\Omega} T_{k_1} R_{\\Lambda}^{\\ast} \\right).",Space,Str "And",Space,Str "here",Space,Str "is",Space,Str "an",Space,Str "implicit",Space,Str "gather",Space,Str "math",Space,Str "environment",Space,Str "consisting",Space,Str "of",Space,Str "multiple",Space,Str "lines",Space,Str "of",Space,Str "equations",Space,Str "with",Space,Str "no",Space,Str "newline",Space,Str "in",Space,Str "between,",Space,Str "with",Space,Code ("",[],[]) "&",Space,Str "symbol",Space,Str "not",Space,Str "appearing",Space,Str "in",Space,Str "every",Space,Str "statement:",Space,Math (DisplayMath ("",["math","gather"],[("labelList","[\"firstGatherMathNumber\",\"secondGatherMathNumber\",\"thirdgathernumber\"]")])) "\\label{firstGatherMathNumber} \\left.\\begin{aligned}\n B'&=-\\partial\\times E\\\\\n E'&=\\partial\\times B - 4\\pi j\n \\end{aligned}\n \\right\\} \\quad \\textsf{Maxwell's equations}\\\\\n\\label{secondGatherMathNumber} A = B\\\\\n\\label{thirdgathernumber} AAAAAAA = BBBBBB"]+,Para [Str "Single",Space,Str "math",Space,Str "equations",Space,Str "that",Space,Str "have",Space,Str "line-breaks",Space,Str "(the",Space,Code ("",[],[]) "\\\\",Space,Str "command)",Space,Str "are",Space,Str "automatically",Space,Str "wrapped",Space,Str "in",Space,Str "a",Space,Code ("",[],[]) "split",Space,Str "environment.",Space,Str "If",Space,Str "alignment",Space,Str "commands",Space,Str "(symbol",Space,Code ("",[],[]) "&",Str ")",Space,Str "also",Space,Str "exist,",Space,Str "they",Space,Str "get",Space,Str "wrapped",Space,Str "in",Space,Str "an",Space,Code ("",[],[]) "aligned",Space,Str "environment",Space,Str "instead.",Space,Str "This",Space,Str "behaviour",Space,Str "can",Space,Str "be",Space,Str "disabled",Space,Str "using",Space,Str "the",Space,Code ("",[],[]) "math_plain",Space,Str "environment:",Space,Math (DisplayMath ("",["math"],[])) "\\begin{split}\ny = ax \\\\\nf = kg^{-1}\n\\end{split}",Space,Math (DisplayMath ("",["math"],[])) "\\begin{aligned}\ny &= ax \\\\\nf &= kg^{-1}\n\\end{aligned}",Space,Str "The",Space,Str "following",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "and",Space,Str "line",Space,Str "breaks",Space,Str "in",Space,Str "comma,",Space,Str "but",Space,Str "is",Space,Str "actually",Space,Str "a",Space,Str "single-line",Space,Str "equation",Space,Str "that",Space,Str "should",Space,Str "be",Space,Str "untouched:",Space,Math (DisplayMath ("",["math"],[])) "|y|\\ \\&\\ |x| % an & and \\\\ that should be ignored\n= 99\\% z % an & and \\\\ that should be ignored",Space,Str "Below",Space,Str "is",Space,Str "more",Space,Str "internal",Space,Str "vertical",Space,Str "alignment",Space,Str "tests.",Space,Str "The",Space,Str "first",Space,Str "is",Space,Str "one",Space,Str "that",Space,Str "uses",Space,Code ("",[],[]) "cases",Space,Str "internally:",Space,Math (DisplayMath ("matheqn2",["math"],[])) "\\label{matheqn2}\n P_{r-j}=\\begin{cases}\n 0& \\ensuremath\\text{if $r-j$ is odd},\\\\\n r!\\,(-1)^{(r-j)/2}& \\text{if $r-j$ is even},\n \\end{cases}",Space,Str "and",Space,Str "another",Space,Str "one",Space,Str "that",Space,Str "uses",Space,Code ("",[],[]) "aligned",Space,Str "internally.",Space,Math (DisplayMath ("matheqn3",["math"],[])) "\\label{matheqn3}\n \\left.\\begin{aligned}\n B'&=-\\partial\\times E\\\\\n E'&=\\partial\\times B - 4\\pi j\n \\end{aligned}\n \\right\\}\n \\qquad \\text{Maxwell's equations}"]+,Header 3 ("math-and-lists",[],[]) [Str "Math",Space,Str "and",Space,Str "lists"]+,Para [Str "Here\8217s",Space,Str "a",Space,Str "list",Space,Str "with",Space,Str "both",Space,Str "inline",Space,Str "and",Space,Str "display",Space,Str "math",Space,Str "environments:"]+,BulletList+ [[Plain [Str "Item",Space,Str "1",Space,Str "is",Space,Str "a",Space,Str "famous",Space,Str "item"]]+ ,[Plain [Str "Item",Space,Str "2",Space,Str "with",Space,Str "a",Space,Code ("",[],[]) "code block",Space,Str "and",Space,Math InlineMath "\\mathsf{\\text{inline math}}",Space,Str "with",Space,Str "equation",Space,Math InlineMath "\\mathbf{y=Ax}"]]+ ,[Plain [Str "Item",Space,Str "3"]+ ,BulletList+ [[Plain [Str "Indented",Space,Str "item",Space,Str "4"]]+ ,[Plain [Str "Indented",Space,Str "item",Space,Str "5,",Space,Str "followed",Space,Str "by",Space,Str "display",Space,Str "math,",Space,Str "which",Space,Str "cannot",Space,Str "be",Space,Str "indented:",Space,Math (DisplayMath ("",["math"],[])) "\\mathbf{F_1 = m_1a}",Space,Str "with",Space,Str "some",Space,Str "text",Space,Str "below"]]+ ,[Plain [Str "Indented",Space,Str "item",Space,Str "6,",Space,Str "which",Space,Str "does",Space,Str "not",Space,Str "recognize",Space,Str "list-item",Space,Str "display",Space,Str "math",Space,Str "surrounded",Space,Str "by",Space,Str "one",Space,Str "additional",Space,Str "blank",Space,Str "line:"]]]]]+,Para [Math (DisplayMath ("",["math"],[])) "\\mathbf{F_2 = m_2a}"]+,CodeBlock ("",[],[]) " without breaking this text out of the list and into a pre block"+,BulletList+ [[Plain [Str "Item",Space,Str "4"]+ ,OrderedList (1,Decimal,Period)+ [[Plain [Str "Numerical",Space,Str "Item",Space,Str "1"]]+ ,[Plain [Str "Numerical",Space,Str "item",Space,Str "2"]]]]]+,Header 2 ("scholarly-x-refs",[],[]) [Str "Scholarly",Space,Str "X-refs"]+,Header 3 ("references-to-figures",[],[]) [Str "References",Space,Str "to",Space,Str "figures"]+,Para [Str "This",Space,Str "line",Space,Str "refers",Space,Str "to",Space,Str "Figure",Space,NumRef (NumberedReference {numRefId = "figure2", numRefStyle = PlainNumRef, numRefLabel = [Str "3"]}) "[#figure2]",Str "."]+,Para [Str "This",Space,Str "line",Space,Str "refers",Space,Str "to",Space,Str "Figure",Space,Str "2."]+,Para [Str "This",Space,Str "line",Space,Str "refers",Space,Str "to",Space,Str "subfigure",Space,NumRef (NumberedReference {numRefId = "reginfig3", numRefStyle = ParenthesesNumRef, numRefLabel = [Str "2c"]}) "(#reginfig3)",Str "."]+,Header 3 ("references-to-equations",[],[]) [Str "References",Space,Str "to",Space,Str "equations"]+,Para [Str "This",Space,Str "line",Space,Str "refers",Space,Str "to",Space,Str "Equation",Space,NumRef (NumberedReference {numRefId = "matheqn3", numRefStyle = ParenthesesNumRef, numRefLabel = [Str "7"]}) "(#matheqn3)",Str "."]+,Para [Str "Referencing",Space,Str "using",Space,Str "the",Space,Code ("",[],[]) "\\ref",Space,Str "tag:",Space,Str "Equation",Space,NumRef (NumberedReference {numRefId = "matheqn1", numRefStyle = PlainNumRef, numRefLabel = [Str "1"]}) "[#matheqn1]",Str "."]+,Para [Str "Referencing",Space,Str "using",Space,Str "the",Space,Code ("",[],[]) "\\eqref",Space,Str "tag:",Space,Str "Equation",Space,NumRef (NumberedReference {numRefId = "middleAlignMathNumber", numRefStyle = ParenthesesNumRef, numRefLabel = [Str "2"]}) "(#middleAlignMathNumber)",Str "."]+,Header 3 ("automatic-non-breaking-spaces",[],[]) [Str "Automatic",Space,Str "non-breaking",Space,Str "spaces"]+,Para [Str "Any",Space,Str "cross-references",Space,Str "(such",Space,Str "as",Space,Str "Equation",Space,NumRef (NumberedReference {numRefId = "middleAlignMathNumber", numRefStyle = PlainNumRef, numRefLabel = [Str "2"]}) "[#middleAlignMathNumber]",Str ")",Space,Str "will",Space,Str "automatically",Space,Str "be",Space,Str "prepended",Space,Str "with",Space,Str "non-breaking",Space,Str "spaces."]+,Para [Str "Unless,",Space,Str "they",Space,Str "appear",Space,Str "in",Space,Str "a",Space,Str "list",Space,Str "like",Space,Str "equations",Space,NumRef (NumberedReference {numRefId = "matheqn1", numRefStyle = PlainNumRef, numRefLabel = [Str "1"]}) "[#matheqn1]",Str ",",Space,NumRef (NumberedReference {numRefId = "matheqn2", numRefStyle = PlainNumRef, numRefLabel = [Str "6"]}) "[#matheqn2]",Str ",",Space,NumRef (NumberedReference {numRefId = "matheqn3", numRefStyle = PlainNumRef, numRefLabel = [Str "7"]}) "[#matheqn3]",Str ",",Space,Str "and",Space,NumRef (NumberedReference {numRefId = "middleAlignMathNumber", numRefStyle = PlainNumRef, numRefLabel = [Str "2"]}) "[#middleAlignMathNumber]",Str "."]+,Header 2 ("scholarlymarkdown-figures",[],[]) [Str "ScholarlyMarkdown",Space,Str "Figures"]+,Header 3 ("images-with-attributes",[],[]) [Str "Images",Space,Str "with",Space,Str "attributes"]+,Para [Str "The",Space,Str "following",Space,Str "will",Space,Str "be",Space,Str "a",Space,Str "bunch",Space,Str "of",Space,Str "figures",Space,Str "with",Space,Str "attributes:",Space,Image ("reglink",[],[("width","20%")]) [Str "Regular",Space,Str "link",Space,Str "with",Space,Str "attributes"] ("lunar_orbit.jpg",""),Space,Image ("reflink",[],[("width","20%")]) [Str "Reference",Space,Str "link",Space,Str "with",Space,Str "attributes"] ("lunar_orbit.jpg",""),Space,Str "Which",Space,Str "should",Space,Str "all",Space,Str "show",Space,Str "fine",Space,Str "and",Space,Str "display",Space,Str "a",Space,Str "picture",Space,Str "with",Space,Str "a",Space,Str "baby",Space,Str "seal."]+,Para [Str "Below",Space,Str "is",Space,Str "more",Space,Str "text",Space,Str "so",Space,Str "that",Space,Str "the",Space,Str "css",Space,Str "doesn\8217t",Space,Str "end",Space,Str "abruptly!",Space,Str "Now",Space,Str "we\8217ll",Space,Str "have",Space,Str "an",Space,Str "explicit",Space,Str "Scholarly",Space,Str "Figure",Space,Str "environment!"]+,Header 3 ("scholarlymarkdown-figuremultifigures",[],[]) [Str "ScholarlyMarkdown",Space,Str "figure/multifigures"]+,Figure ImageFigure ("figure0",["singleFigure"],[("numLabel","1"),("subfigIds","[\"\"]")]) [ImageGrid [[Image ("",[],[("width","50%")]) [] ("lunar_orbit.jpg","")]]] (PreparedContent {preparedImageContent = Space, preparedLaTeXContent = ""}) [Str "Single-image",Space,Str "figure.",Space,Str "You",Space,Str "can",Space,Str "also",Space,Str "have",Space,Str "citations",Space,Str "inside",Space,Str "captions",Space,Cite [Citation {citationId = "Gill", citationPrefix = [], citationSuffix = [], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[@Gill]"],Str "."]+,Figure ImageFigure ("figure1",["multiFigure"],[("numLabel","2"),("subfigIds","[\"reginfig1\",\"\",\"reginfig3\"]")]) [ImageGrid [[Image ("reginfig1",[],[("width","20%")]) [Str "sub"] ("lunar_orbit.jpg",""),Image ("",[],[("width","same")]) [Str "subfig"] ("lunar_orbit.jpg",""),Image ("reginfig3",[],[("width","same")]) [Str "longer",Space,Str "subcaption",Space,Str "that",Space,Str "flows"] ("lunar_orbit.jpg","")]]] (PreparedContent {preparedImageContent = Space, preparedLaTeXContent = ""}) [Str "Reference",Space,Str "link",Space,Str "in",Space,Str "its",Space,Str "own",Space,Str "paragraph",Space,Str "and",Space,Str "long",Space,Str "caption",Space,Str "Lorem",Space,Str "ipsum",Space,Str "dolor",Space,Str "sit",Space,Str "amet,",Space,Str "consectetuer",Space,Str "adipiscing",Space,Str "elit,",Space,Str "sed",Space,Str "diam",Space,Str "nonummy",Space,Str "nibh",Space,Str "euismod",Space,Str "tincidunt",Space,Str "ut",Space,Str "laoreet",Space,Str "dolore",Space,Str "magna",Space,Str "aliquam",Space,Str "erat",Space,Str "volutpat."]+,Figure ImageFigure ("figure2",["multiFigure","wide"],[("numLabel","3"),("subfigIds","[\"reginfig4\",\"reginfig5\"]")]) [ImageGrid [[Image ("reginfig4",[],[("width","40%")]) [Str "fdsaf"] ("lunar_orbit.jpg",""),Image ("reginfig5",[],[("width","30%")]) [Str "woogawooga"] ("lunar_orbit.jpg","")]]] (PreparedContent {preparedImageContent = Space, preparedLaTeXContent = ""}) [Str "Reference",Space,Str "link",Space,Str "in",Space,Str "its",Space,Str "own",Space,Str "paragraph",Space,Str "and",Space,Str "long",Space,Str "caption",Space,Str "Lorem",Space,Str "ipsum",Space,Str "dolor",Space,Str "sit",Space,Str "amet,",Space,Str "consectetuer",Space,Str "adipiscing",Space,Str "elit,",Space,Str "sed",Space,Str "diam",Space,Str "nonummy",Space,Str "nibh",Space,Str "euismod",Space,Str "tincidunt",Space,Str "ut",Space,Str "laoreet",Space,Str "dolore",Space,Str "magna",Space,Str "aliquam",Space,Str "erat",Space,Str "volutpat."]+,Header 2 ("scholarlymarkdown-algorithms",[],[]) [Str "ScholarlyMarkdown",Space,Str "Algorithms"]+,Para [Str "Here",Space,Str "are",Space,Str "some",Space,Str "algorithms",Space,Str "using",Space,Str "various",Space,Str "methods.",Space,Str "The",Space,Quoted DoubleQuote [Str "most",Space,Str "canonical",Space,Str "one"],Space,Str "is",Space,Str "currently",Space,Str "just",Space,Str "using",Space,Str "a",Space,Str "line-block:"]+,Figure LineBlockFigure ("alg:gs",[],[("numLabel","1")]) [Para [Code ("",[],[]) " 1.",Str "\160",Strong [Str "Inputs"],Str ":\160variables\160",Math InlineMath "A, b",LineBreak,Code ("",[],[]) " 2.",Str "\160",Strong [Str "Output"],Str ":\160",Math InlineMath "\\phi",Str "\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160",Code ("",[],[]) "//this is a comment"],Para [Code ("",[],[]) " 3.",Str "\160Choose\160an\160initial\160guess\160",Math InlineMath "\\phi",Str "\160to\160the\160solution",LineBreak,Code ("",[],[]) " 4.",Str "\160\160",Strong [Str "repeat"],Str "\160until\160convergence",LineBreak,Code ("",[],[]) " 5.",Str "\160\160\160\160",Strong [Str "for"],Str "\160",Math InlineMath "i",Str "\160",Strong [Str "from"],Str "\160\&1\160",Strong [Str "until"],Str "\160",Math InlineMath "n",Str "\160",Strong [Str "do"],LineBreak,Code ("",[],[]) " 6.",Str "\160\160\160\160\160\160\160\160",Math InlineMath "\\sigma \\leftarrow 0",LineBreak,Code ("",[],[]) " 7.",Str "\160\160\160\160\160\160\160\160",Strong [Str "for"],Str "\160",Math InlineMath "j",Str "\160",Strong [Str "from"],Str "\160\&1\160",Strong [Str "until"],Str "\160",Math InlineMath "n",Str "\160",Strong [Str "do"],LineBreak,Code ("",[],[]) " 8.",Str "\160\160\160\160\160\160\160\160\160\160\160\160",Strong [Str "if"],Str "\160",Math InlineMath "j \\ne i",Str "\160",Strong [Str "then"],LineBreak,Code ("",[],[]) " 9.",Str "\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160",Math InlineMath "\\sigma \\leftarrow \\sigma + a_{ij} \\phi_j",LineBreak,Code ("",[],[]) "10.",Str "\160\160\160\160\160\160\160\160\160\160\160\160",Strong [Str "end\160if"],LineBreak,Code ("",[],[]) "11.",Str "\160\160\160\160\160\160\160\160",Strong [Str "end"],Str "\160(",Math InlineMath "j",Str "-loop)",LineBreak,Code ("",[],[]) "12.",Str "\160\160\160\160\160\160\160\160",Math InlineMath "\\phi_i \\leftarrow \\frac 1 {a_{ii}} (b_i - \\sigma)",LineBreak,Code ("",[],[]) "13.",Str "\160\160\160\160",Strong [Str "end"],Str "\160(",Math InlineMath "i",Str "-loop)",LineBreak,Code ("",[],[]) "14.",Str "\160\160\160\160check\160if\160convergence\160is\160reached",LineBreak,Code ("",[],[]) "15.",Str "\160",Strong [Str "end"],Str "\160(repeat)"]] (PreparedContent {preparedImageContent = Space, preparedLaTeXContent = ""}) [Str "caption",Space,Str "for",Space,Str "this",Space,Str "algorithm"]+,Figure LineBlockFigure ("alg:gs2",[],[("numLabel","2")]) [Para [Str "\160",Strong [Str "Inputs"],Str ":\160variables\160",Math InlineMath "A, b",LineBreak,Str "\160",Strong [Str "Output"],Str ":\160",Math InlineMath "\\phi"],Para [Str "\160Choose\160an\160initial\160guess\160",Math InlineMath "\\phi",Str "\160to\160the\160solution",LineBreak,Str "\160",Strong [Str "repeat"],Str "\160until\160convergence",LineBreak,Str "\160\160\160\160\160\160",Strong [Str "for"],Str "\160",Math InlineMath "i",Str "\160from\160\&1\160to\160",Math InlineMath "n",Str "\160",Strong [Str "do"],LineBreak,Str "\160\160\160\160\160\160\160\160\160\160",Math InlineMath "\\sigma \\leftarrow 0",LineBreak,Str "\160\160\160\160\160\160\160\160\160\160",Strong [Str "for"],Str "\160",Math InlineMath "j",Str "\160from\160\&1\160to\160",Math InlineMath "n",Str "\160",Strong [Str "do"],LineBreak,Str "\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160",Strong [Str "if"],Str "\160",Math InlineMath "j \\ne i",Str "\160",Strong [Str "then"],LineBreak,Str "\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160",Math InlineMath "\\sigma \\leftarrow \\sigma + a_{ij} \\phi_j",LineBreak,Str "\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160",Strong [Str "end\160if"],LineBreak,Str "\160\160\160\160\160\160\160\160\160\160",Strong [Str "end"],Str "\160(",Math InlineMath "j",Str "-loop)",LineBreak,Str "\160\160\160\160\160\160\160\160\160\160",Math InlineMath "\\phi_i \\leftarrow \\frac 1 {a_{ii}} (b_i - \\sigma)",LineBreak,Str "\160\160\160\160\160\160",Strong [Str "end"],Str "\160(",Math InlineMath "i",Str "-loop)",LineBreak,Str "\160\160\160\160\160\160check\160if\160convergence\160is\160reached",LineBreak,Str "\160",Strong [Str "end"],Str "\160(repeat)"]] (PreparedContent {preparedImageContent = Space, preparedLaTeXContent = ""}) []+,Para [Str "The",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "caption"]+,Figure LineBlockFigure ("alg:gs3",[],[("numLabel","3")]) [Para [Str "\160",Strong [Str "Inputs"],Str ":\160variables\160",Math InlineMath "A, b",LineBreak,Str "\160",Strong [Str "Output"],Str ":\160",Math InlineMath "\\phi"],Para [Str "\160Choose\160an\160initial\160guess\160",Math InlineMath "\\phi",Str "\160to\160the\160solution",LineBreak,Str "\160",Strong [Str "repeat"],Str "\160until\160convergence",LineBreak,Str "\160\160\160\160\160\160",Strong [Str "for"],Str "\160",Math InlineMath "i",Str "\160from\160\&1\160to\160",Math InlineMath "n",Str "\160",Strong [Str "do"],LineBreak,Str "\160\160\160\160\160\160\160\160\160\160",Math InlineMath "\\sigma \\leftarrow 0",LineBreak,Str "\160\160\160\160\160\160\160\160\160\160",Strong [Str "for"],Str "\160",Math InlineMath "j",Str "\160from\160\&1\160to\160",Math InlineMath "n",Str "\160",Strong [Str "do"],LineBreak,Str "\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160",Strong [Str "if"],Str "\160",Math InlineMath "j \\ne i",Str "\160",Strong [Str "then"],LineBreak,Str "\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160",Math InlineMath "\\sigma \\leftarrow \\sigma + a_{ij} \\phi_j",LineBreak,Str "\160\160\160\160\160\160\160\160\160\160\160\160\160\160\160",Strong [Str "end\160if"],LineBreak,Str "\160\160\160\160\160\160\160\160\160\160",Strong [Str "end"],Str "\160(",Math InlineMath "j",Str "-loop)",LineBreak,Str "\160\160\160\160\160\160\160\160\160\160",Math InlineMath "\\phi_i \\leftarrow \\frac 1 {a_{ii}} (b_i - \\sigma)",LineBreak,Str "\160\160\160\160\160\160",Strong [Str "end"],Str "\160(",Math InlineMath "i",Str "-loop)",LineBreak,Str "\160\160\160\160\160\160check\160if\160convergence\160is\160reached",LineBreak,Str "\160",Strong [Str "end"],Str "\160(repeat)"]] (PreparedContent {preparedImageContent = Space, preparedLaTeXContent = ""}) [Str "This",Space,Str "should",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "caption"]+,Header 2 ("scholarlymarkdown-tables",[],[]) [Str "ScholarlyMarkdown",Space,Str "Tables"]+,Header 3 ("standard-pandoc-tables",[],[]) [Str "Standard",Space,Str "Pandoc",Space,Str "tables"]+,Para [Str "The",Space,Str "following",Space,Str "is",Space,Str "a",Space,Str "normal",Space,Str "Pandoc",Space,Str "table"]+,Table [Str "Thisis",Space,Str "a",Space,Str "caption"] [AlignRight,AlignLeft,AlignDefault,AlignCenter] [0.0,0.0,0.0,0.0]+ [[Plain [Str "Right"]]+ ,[Plain [Str "Left"]]+ ,[Plain [Str "Default"]]+ ,[Plain [Str "Center"]]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "This",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "caption"]+,Header 3 ("scholarly-tables",[],[]) [Str "Scholarly",Space,Str "tables"]+,Para [Str "The",Space,Str "following",Space,Str "is",Space,Str "a",Space,Str "floated",Space,Str "ScholMD",Space,Str "table"]+,Figure TableFigure ("tab:exscholmd",[],[("numLabel","1")]) [Table [] [AlignRight,AlignLeft,AlignDefault,AlignCenter] [0.0,0.0,0.0,0.0] [[Plain [Str "Right"]],[Plain [Str "Left"]],[Plain [Str "Default"]],[Plain [Str "Center"]]] [[[Plain [Str "12"]],[Plain [Str "12"]],[Plain [Str "12"]],[Plain [Str "12"]]],[[Plain [Str "123"]],[Plain [Str "123"]],[Plain [Str "123"]],[Plain [Str "123"]]],[[Plain [Str "1"]],[Plain [Str "1"]],[Plain [Str "1"]],[Plain [Str "1"]]]]] (PreparedContent {preparedImageContent = Space, preparedLaTeXContent = ""}) [Str "This",Space,Str "is",Space,Str "a",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "really",Space,Str "long",Space,Str "caption"]+,Header 2 ("scholarlymarkdown-code-blocks",[],[]) [Str "ScholarlyMarkdown",Space,Str "Code",Space,Str "blocks"]+,Header 3 ("standard-pandoc-code-blocks",[],[]) [Str "Standard",Space,Str "Pandoc",Space,Str "code",Space,Str "blocks"]+,Header 4 ("fenced-blocks",[],[]) [Str "fenced",Space,Str "blocks"]+,CodeBlock ("",[],[]) "Value <- [0-9.]+ / '(' Expr ')'\nProduct <- Expr (('*' / '/') Expr)*\nSum <- Expr (('+' / '-') Expr)*\nExpr <- Product / Sum / Value"+,Header 4 ("indented-blocks",[],[]) [Str "indented",Space,Str "blocks"]+,CodeBlock ("",[],[]) "Value <- [0-9.]+ / '(' Expr ')'\nProduct <- Expr (('*' / '/') Expr)*\nSum <- Expr (('+' / '-') Expr)*\nExpr <- Product / Sum / Value"+,Header 3 ("scholarly-code-block-floats",[],[]) [Str "Scholarly",Space,Str "code",Space,Str "block",Space,Str "floats"]+,Figure ListingFigure ("lst:pegcalc",[],[("numLabel","1")]) [CodeBlock ("",["c","numberLines"],[("startFrom","100")]) "Value <- [0-9.]+ / '(' Expr ')'\nProduct <- Expr (('*' / '/') Expr)*\nSum <- Expr (('+' / '-') Expr)*\nExpr <- Product / Sum / Value"] (PreparedContent {preparedImageContent = Space, preparedLaTeXContent = ""}) [Link [Str "Parsing",Space,Str "Expression",Space,Str "Grammar"] ("http://en.wikipedia.org/wiki/Parsing_expression_grammar",""),Space,Str "rules",Space,Str "for",Space,Str "a",Space,Str "simple",Space,Str "calculator",Space,Str "using",Space,Str "PEG."]+,Figure ListingFigure ("lst:pegcalc",[],[("numLabel","2")]) [CodeBlock ("",[],[]) "Value <- [0-9.]+ / '(' Expr ')'\nProduct <- Expr (('*' / '/') Expr)*\nSum <- Expr (('+' / '-') Expr)*\nExpr <- Product / Sum / Value"] (PreparedContent {preparedImageContent = Space, preparedLaTeXContent = ""}) [Link [Str "Parsing",Space,Str "Expression",Space,Str "Grammar"] ("http://en.wikipedia.org/wiki/Parsing_expression_grammar",""),Space,Str "rules",Space,Str "for",Space,Str "a",Space,Str "simple",Space,Str "calculator."]]
@@ -0,0 +1,330 @@+---+title: 'ScholarlyMarkdown: a Markdown-compatible plaintext format for academic communication'+author: Tim T.Y. Lin+tags: [test, markdown, scholarly]+date: January 1, 2000+bibliography: scholdoc_bibtex_file.bib+---++## ScholarlyMarkdown math support++### Math as (fenced) code blocks++This is a line of text with a `simple code block` in it.++`` `this should be just a `normal` inline code block+surrounded by literal backticks` ``++This is another line of text. Here should be some math: ``\mathbf{F = ma}<2\mathbf{ma}``. There should be some displaymath environment on the following line++```math+ \mathbf{F = ma} < 2\mathbf{ma}+```++and there should be no line breaks between the displaymath block and here. **This should be bold**. *This should be italic.*++The following is a displaymath with an aligned environment in a separate paragraph (preceded with, and followed by, two blank lines), with identifier `matheqn1`. It should automatically be wrapped with the `aligned` environment.+++```math {#matheqn1}+\tag{BIGLABEL}+ \mbox{minimize}\quad & \fx = \max_{i=1,\ldots,m} (a_i^T x + b_i) \\+ & \|x\|_2 \le \sigma.+```+++```math_def+\renewcommand{\fx}{f(x)}+```++Here is an implicit align math environment consisting of multiple lines of equations with no newline in between, with at least one `&` symbol in the whole expression. It should be in the same paragraph as this one.++```math+ \sum_{j_1, j_2, \ldots j_m} \sum_{k_1, k_2, \ldots, k_m} & \widetilde{A}_{j_1,k_1}^{\ast} \widetilde{A}_{j_1,k_2} \tilde{A}_{j_2,k_2}^{\ast} \widetilde{A}_{j_2,k_3} \ldots \widetilde{A}_{j_m,k_m}^{\ast} \widetilde{A}_{j_m,k_1}+``` +```math #middleAlignMathNumber+ = \sum_{j_1, j_2, \ldots j_m} \sum_{k_1, k_2, \ldots, k_m} & \left( R_{\Lambda} T_{k_1}^{\ast} P_{\Omega} T_{j_1} R_{\Lambda}^{\ast} \right) \left( R_{\Lambda} T_{j_1}^{\ast} P_{\Omega} T_{k_2} R_{\Lambda}^{\ast} \right) \left( R_{\Lambda} T_{k_2}^{\ast} P_{\Omega} T_{j_2} R_{\Lambda}^{\ast} \right)+```+```math+ & \left( R_{\Lambda} T_{j_2}^{\ast} P_{\Omega} T_{k_3} R_{\Lambda}^{\ast} \right) \ldots \left( R_{\Lambda} T_{k_m}^{\ast} P_{\Omega} T_{j_m} R_{\Lambda}^{\ast} \right) \left( R_{\Lambda} T_{j_m}^{\ast} P_{\Omega} T_{k_1} R_{\Lambda}^{\ast} \right).+```++And here is an implicit gather math environment consisting of multiple lines of equations with no newline in between, with `&` symbol not appearing in every statement:++```math {#firstGatherMathNumber}+ \left.\begin{aligned}+ B'&=-\partial\times E\\+ E'&=\partial\times B - 4\pi j+ \end{aligned}+ \right\} \quad \textsf{Maxwell's equations}+```+```math {#secondGatherMathNumber}+A = B+```+```math {#thirdgathernumber}+AAAAAAA = BBBBBB+```+++Single math equations that have line-breaks (the `\\` command) are automatically wrapped in a `split` environment. If alignment commands (symbol `&`) also exist, they get wrapped in an `aligned` environment instead. This behaviour can be disabled using the `math_plain` environment:++```math+y = ax \\+f = kg^{-1}+```++```math+y &= ax \\+f &= kg^{-1}+```++The following has an ampersand and line breaks in comma, but is actually a single-line equation that should be untouched:++```math+|y|\ \&\ |x| % an & and \\ that should be ignored+= 99\% z % an & and \\ that should be ignored+```+Below is more internal vertical alignment tests. The first is one that uses `cases` internally:+```math+ #matheqn2+ P_{r-j}=\begin{cases}+ 0& \ensuremath\text{if $r-j$ is odd},\\+ r!\,(-1)^{(r-j)/2}& \text{if $r-j$ is even},+ \end{cases}+```+and another one that uses `aligned` internally.+```math #matheqn3+ \left.\begin{aligned}+ B'&=-\partial\times E\\+ E'&=\partial\times B - 4\pi j+ \end{aligned}+ \right\}+ \qquad \text{Maxwell's equations}+```+++### Math and lists+++Here's a list with both inline and display math environments:++- Item 1 is a famous item+- Item 2 with a `code block` and ``\mathsf{\text{inline math}}`` with equation ``\mathbf{y=Ax}``+- Item 3+ - Indented item 4+ - Indented item 5, followed by display math, which cannot be indented: +```math+\mathbf{F_1 = m_1a}+```+ with some text below+ - Indented item 6, which does not recognize list-item display math surrounded by one additional blank line:++```math+\mathbf{F_2 = m_2a}+```++ without breaking this text out of the list and into a pre block+- Item 4+ 1. Numerical Item 1+ 2. Numerical item 2+++## Scholarly X-refs++### References to figures++This line refers to Figure [#figure2].++This line refers to Figure 2.++This line refers to subfigure (#reginfig3).++### References to equations++This line refers to Equation (#matheqn3).++Referencing using the `\ref` tag: Equation [#matheqn1].++Referencing using the `\eqref` tag: Equation (#middleAlignMathNumber).++### Automatic non-breaking spaces++Any cross-references (such as Equation [#middleAlignMathNumber]) will+automatically be prepended with non-breaking spaces.++Unless, they appear in a list like equations [#matheqn1], [#matheqn2],+[#matheqn3], and [#middleAlignMathNumber].++## ScholarlyMarkdown Figures+++### Images with attributes++The following will be a bunch of figures with attributes:+{#reglink width=20%}+![Reference link with attributes][lunarorbit]{#reflink width=20%}+Which should all show fine and display a picture with a baby seal.++[lunarorbit]: lunar_orbit.jpg++Below is more text so that the css doesn't end abruptly! Now we'll have an explicit Scholarly Figure environment!++### ScholarlyMarkdown figure/multifigures++#### Figure: this text is completely ignored {#figure0}+{width=50%}+: Single-image figure. You can also have citations inside captions [@Gill].++#### Figure: this text is completely ignored {#figure1}+{#reginfig1 width=20%}+{width=same}+{#reginfig3 width=same}+: Reference link in its own paragraph and long caption Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. ++#### Figure: everything until the attribute block is ignored {#figure2 .wide}+{#reginfig4 width=40%}+{#reginfig5 width=30%}+Reference link in its own paragraph and long caption Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. ++## ScholarlyMarkdown Algorithms++Here are some algorithms using various methods. The "most canonical one" is currently just using a line-block:++#### Algorithm: Gauss-sidel using line blocks {#alg:gs}+| ` 1.` **Inputs**: variables ``A, b``+| ` 2.` **Output**: ``\phi`` `//this is a comment`+| +| ` 3.` Choose an initial guess ``\phi`` to the solution+| ` 4.` **repeat** until convergence+| ` 5.` **for** ``i`` **from** 1 **until** ``n`` **do**+| ` 6.` ``\sigma \leftarrow 0``+| ` 7.` **for** ``j`` **from** 1 **until** ``n`` **do**+| ` 8.` **if** ``j \ne i`` **then**+| ` 9.` ``\sigma \leftarrow \sigma + a_{ij} \phi_j``+| `10.` **end if**+| `11.` **end** (``j``-loop)+| `12.` ``\phi_i \leftarrow \frac 1 {a_{ii}} (b_i - \sigma)``+| `13.` **end** (``i``-loop)+| `14.` check if convergence is reached+| `15.` **end** (repeat)++: caption for this algorithm++#### Algorithm: Gauss-sidel using `line-blocks` {#alg:gs2}++| **Inputs**: variables ``A, b``+| **Output**: ``\phi``+| +| Choose an initial guess ``\phi`` to the solution+| **repeat** until convergence+| **for** ``i`` from 1 to ``n`` **do**+| ``\sigma \leftarrow 0``+| **for** ``j`` from 1 to ``n`` **do**+| **if** ``j \ne i`` **then**+| ``\sigma \leftarrow \sigma + a_{ij} \phi_j``+| **end if**+| **end** (``j``-loop)+| ``\phi_i \leftarrow \frac 1 {a_{ii}} (b_i - \sigma)``+| **end** (``i``-loop)+| check if convergence is reached+| **end** (repeat)++The should not be a caption++#### Algorithm: Gauss-sidel using `line-blocks` {#alg:gs3}++| **Inputs**: variables ``A, b``+| **Output**: ``\phi``+| +| Choose an initial guess ``\phi`` to the solution+| **repeat** until convergence+| **for** ``i`` from 1 to ``n`` **do**+| ``\sigma \leftarrow 0``+| **for** ``j`` from 1 to ``n`` **do**+| **if** ``j \ne i`` **then**+| ``\sigma \leftarrow \sigma + a_{ij} \phi_j``+| **end if**+| **end** (``j``-loop)+| ``\phi_i \leftarrow \frac 1 {a_{ii}} (b_i - \sigma)``+| **end** (``i``-loop)+| check if convergence is reached+| **end** (repeat)+This should should be a caption++## Abstract:++This is the abstract! It should show up at the beginning of the page.++## ScholarlyMarkdown Tables++### Standard Pandoc tables++The following is a normal Pandoc table++| Right | Left | Default | Center |+|------:|:-----|---------|:------:|+| 12 | 12 | 12 | 12 |+| 123 | 123 | 123 | 123 |+| 1 | 1 | 1 | 1 |++Table: Thisis a caption++This should not be a caption++### Scholarly tables++The following is a floated ScholMD table++#### Table: example ScholMD table {#tab:exscholmd}++| Right | Left | Default | Center |+|------:|:-----|---------|:------:|+| 12 | 12 | 12 | 12 |+| 123 | 123 | 123 | 123 |+| 1 | 1 | 1 | 1 |++: This is a really really really really really+ really really really really really really really+ really really really really really really really really+ really really really really really really really long caption++## ScholarlyMarkdown Code blocks++### Standard Pandoc code blocks++#### fenced blocks++```+Value <- [0-9.]+ / '(' Expr ')'+Product <- Expr (('*' / '/') Expr)*+Sum <- Expr (('+' / '-') Expr)*+Expr <- Product / Sum / Value+```++#### indented blocks++ Value <- [0-9.]+ / '(' Expr ')'+ Product <- Expr (('*' / '/') Expr)*+ Sum <- Expr (('+' / '-') Expr)*+ Expr <- Product / Sum / Value++### Scholarly code block floats++#### Code: PEG for calc {#lst:pegcalc}++``` {.c .numberLines startFrom="100"}+Value <- [0-9.]+ / '(' Expr ')'+Product <- Expr (('*' / '/') Expr)*+Sum <- Expr (('+' / '-') Expr)*+Expr <- Product / Sum / Value+```++: [Parsing Expression Grammar](http://en.wikipedia.org/wiki/Parsing_expression_grammar) rules for a simple calculator using PEG.++#### Code: PEG for calc {#lst:pegcalc}+ Value <- [0-9.]+ / '(' Expr ')'+ Product <- Expr (('*' / '/') Expr)*+ Sum <- Expr (('+' / '-') Expr)*+ Expr <- Product / Sum / Value+[Parsing Expression Grammar](http://en.wikipedia.org/wiki/Parsing_expression_grammar) rules for a simple calculator.+
@@ -0,0 +1,117 @@+[Para [Str "Simple",Space,Str "table",Space,Str "with",Space,Str "caption:"]+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.125,0.1125,0.1375,0.15]+ [[Plain [Str "Right"]]+ ,[Plain [Str "Left"]]+ ,[Plain [Str "Center"]]+ ,[Plain [Str "Default"]]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Table:",Space,Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."]+,Para [Str "Simple",Space,Str "table",Space,Str "without",Space,Str "caption:"]+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.125,0.1125,0.1375,0.15]+ [[Plain [Str "Right"]]+ ,[Plain [Str "Left"]]+ ,[Plain [Str "Center"]]+ ,[Plain [Str "Default"]]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Simple",Space,Str "table",Space,Str "indented",Space,Str "two",Space,Str "spaces:"]+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.125,0.1125,0.1375,0.15]+ [[Plain [Str "Right"]]+ ,[Plain [Str "Left"]]+ ,[Plain [Str "Center"]]+ ,[Plain [Str "Default"]]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Table:",Space,Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."]+,Para [Str "Multiline",Space,Str "table",Space,Str "with",Space,Str "caption:"]+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.175,0.1625,0.1875,0.3625]+ [[Plain [Str "Centered",Space,Str "Header"]]+ ,[Plain [Str "Left",Space,Str "Aligned"]]+ ,[Plain [Str "Right",Space,Str "Aligned"]]+ ,[Plain [Str "Default",Space,Str "aligned"]]]+ [[[Plain [Str "First"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "12.0"]]+ ,[Plain [Str "Example",Space,Str "of",Space,Str "a",Space,Str "row",Space,Str "that",Space,Str "spans",Space,Str "multiple",Space,Str "lines."]]]+ ,[[Plain [Str "Second"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "5.0"]]+ ,[Plain [Str "Here's",Space,Str "another",Space,Str "one.",Space,Str "Note",Space,Str "the",Space,Str "blank",Space,Str "line",Space,Str "between",Space,Str "rows."]]]]+,Para [Str "Table:",Space,Str "Here's",Space,Str "the",Space,Str "caption.",Space,Str "It",Space,Str "may",Space,Str "span",Space,Str "multiple",Space,Str "lines."]+,Para [Str "Multiline",Space,Str "table",Space,Str "without",Space,Str "caption:"]+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.175,0.1625,0.1875,0.3625]+ [[Plain [Str "Centered",Space,Str "Header"]]+ ,[Plain [Str "Left",Space,Str "Aligned"]]+ ,[Plain [Str "Right",Space,Str "Aligned"]]+ ,[Plain [Str "Default",Space,Str "aligned"]]]+ [[[Plain [Str "First"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "12.0"]]+ ,[Plain [Str "Example",Space,Str "of",Space,Str "a",Space,Str "row",Space,Str "that",Space,Str "spans",Space,Str "multiple",Space,Str "lines."]]]+ ,[[Plain [Str "Second"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "5.0"]]+ ,[Plain [Str "Here's",Space,Str "another",Space,Str "one.",Space,Str "Note",Space,Str "the",Space,Str "blank",Space,Str "line",Space,Str "between",Space,Str "rows."]]]]+,Para [Str "Table",Space,Str "without",Space,Str "column",Space,Str "headers:"]+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.1,0.1,0.1,0.1]+ [[]+ ,[]+ ,[]+ ,[]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Multiline",Space,Str "table",Space,Str "without",Space,Str "column",Space,Str "headers:"]+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.175,0.1625,0.1875,0.3625]+ [[]+ ,[]+ ,[]+ ,[]]+ [[[Plain [Str "First"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "12.0"]]+ ,[Plain [Str "Example",Space,Str "of",Space,Str "a",Space,Str "row",Space,Str "that",Space,Str "spans",Space,Str "multiple",Space,Str "lines."]]]+ ,[[Plain [Str "Second"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "5.0"]]+ ,[Plain [Str "Here's",Space,Str "another",Space,Str "one.",Space,Str "Note",Space,Str "the",Space,Str "blank",Space,Str "line",Space,Str "between",Space,Str "rows."]]]]]
@@ -0,0 +1,77 @@+Simple table with caption:++> Right Left Center Default+> ------- ------ -------- ---------+> 12 12 12 12+> 123 123 123 123+> 1 1 1 1+>+> Demonstration of simple table syntax.++Simple table without caption:++> Right Left Center Default+> ------- ------ -------- ---------+> 12 12 12 12+> 123 123 123 123+> 1 1 1 1++Simple table indented two spaces:++> Right Left Center Default+> ------- ------ -------- ---------+> 12 12 12 12+> 123 123 123 123+> 1 1 1 1+>+> Demonstration of simple table syntax.++Multiline table with caption:++> --------------------------------------------------------------+> Centered Left Right Default aligned+> Header Aligned Aligned +> ----------- ---------- ------------ --------------------------+> First row 12.0 Example of a row that+> spans multiple lines.+>+> Second row 5.0 Here\'s another one. Note+> the blank line between+> rows.+> --------------------------------------------------------------+>+> Here\'s the caption. It may span multiple lines.++Multiline table without caption:++> --------------------------------------------------------------+> Centered Left Right Default aligned+> Header Aligned Aligned +> ----------- ---------- ------------ --------------------------+> First row 12.0 Example of a row that+> spans multiple lines.+>+> Second row 5.0 Here\'s another one. Note+> the blank line between+> rows.+> --------------------------------------------------------------++Table without column headers:++> ----- ----- ----- -----+> 12 12 12 12+> 123 123 123 123+> 1 1 1 1+> ----- ----- ----- -----++Multiline table without column headers:++> ----------- ---------- ------------ --------------------------+> First row 12.0 Example of a row that+> spans multiple lines.+>+> Second row 5.0 Here\'s another one. Note+> the blank line between+> rows.+> ----------- ---------- ------------ --------------------------+
@@ -0,0 +1,204 @@+<p>Simple table with caption:</p>+<table>+<caption>Demonstration of simple table syntax.</caption>+<thead>+<tr class="header">+<th align="right">Right</th>+<th align="left">Left</th>+<th align="center">Center</th>+<th align="left">Default</th>+</tr>+</thead>+<tbody>+<tr class="odd">+<td align="right">12</td>+<td align="left">12</td>+<td align="center">12</td>+<td align="left">12</td>+</tr>+<tr class="even">+<td align="right">123</td>+<td align="left">123</td>+<td align="center">123</td>+<td align="left">123</td>+</tr>+<tr class="odd">+<td align="right">1</td>+<td align="left">1</td>+<td align="center">1</td>+<td align="left">1</td>+</tr>+</tbody>+</table>+<p>Simple table without caption:</p>+<table>+<thead>+<tr class="header">+<th align="right">Right</th>+<th align="left">Left</th>+<th align="center">Center</th>+<th align="left">Default</th>+</tr>+</thead>+<tbody>+<tr class="odd">+<td align="right">12</td>+<td align="left">12</td>+<td align="center">12</td>+<td align="left">12</td>+</tr>+<tr class="even">+<td align="right">123</td>+<td align="left">123</td>+<td align="center">123</td>+<td align="left">123</td>+</tr>+<tr class="odd">+<td align="right">1</td>+<td align="left">1</td>+<td align="center">1</td>+<td align="left">1</td>+</tr>+</tbody>+</table>+<p>Simple table indented two spaces:</p>+<table>+<caption>Demonstration of simple table syntax.</caption>+<thead>+<tr class="header">+<th align="right">Right</th>+<th align="left">Left</th>+<th align="center">Center</th>+<th align="left">Default</th>+</tr>+</thead>+<tbody>+<tr class="odd">+<td align="right">12</td>+<td align="left">12</td>+<td align="center">12</td>+<td align="left">12</td>+</tr>+<tr class="even">+<td align="right">123</td>+<td align="left">123</td>+<td align="center">123</td>+<td align="left">123</td>+</tr>+<tr class="odd">+<td align="right">1</td>+<td align="left">1</td>+<td align="center">1</td>+<td align="left">1</td>+</tr>+</tbody>+</table>+<p>Multiline table with caption:</p>+<table>+<caption>Here's the caption. It may span multiple lines.</caption>+<colgroup>+<col width="15%" />+<col width="13%" />+<col width="16%" />+<col width="33%" />+</colgroup>+<thead>+<tr class="header">+<th align="center">Centered Header</th>+<th align="left">Left Aligned</th>+<th align="right">Right Aligned</th>+<th align="left">Default aligned</th>+</tr>+</thead>+<tbody>+<tr class="odd">+<td align="center">First</td>+<td align="left">row</td>+<td align="right">12.0</td>+<td align="left">Example of a row that spans multiple lines.</td>+</tr>+<tr class="even">+<td align="center">Second</td>+<td align="left">row</td>+<td align="right">5.0</td>+<td align="left">Here's another one. Note the blank line between rows.</td>+</tr>+</tbody>+</table>+<p>Multiline table without caption:</p>+<table>+<colgroup>+<col width="15%" />+<col width="13%" />+<col width="16%" />+<col width="33%" />+</colgroup>+<thead>+<tr class="header">+<th align="center">Centered Header</th>+<th align="left">Left Aligned</th>+<th align="right">Right Aligned</th>+<th align="left">Default aligned</th>+</tr>+</thead>+<tbody>+<tr class="odd">+<td align="center">First</td>+<td align="left">row</td>+<td align="right">12.0</td>+<td align="left">Example of a row that spans multiple lines.</td>+</tr>+<tr class="even">+<td align="center">Second</td>+<td align="left">row</td>+<td align="right">5.0</td>+<td align="left">Here's another one. Note the blank line between rows.</td>+</tr>+</tbody>+</table>+<p>Table without column headers:</p>+<table>+<tbody>+<tr class="odd">+<td align="right">12</td>+<td align="left">12</td>+<td align="center">12</td>+<td align="right">12</td>+</tr>+<tr class="even">+<td align="right">123</td>+<td align="left">123</td>+<td align="center">123</td>+<td align="right">123</td>+</tr>+<tr class="odd">+<td align="right">1</td>+<td align="left">1</td>+<td align="center">1</td>+<td align="right">1</td>+</tr>+</tbody>+</table>+<p>Multiline table without column headers:</p>+<table>+<colgroup>+<col width="15%" />+<col width="13%" />+<col width="16%" />+<col width="33%" />+</colgroup>+<tbody>+<tr class="odd">+<td align="center">First</td>+<td align="left">row</td>+<td align="right">12.0</td>+<td align="left">Example of a row that spans multiple lines.</td>+</tr>+<tr class="even">+<td align="center">Second</td>+<td align="left">row</td>+<td align="right">5.0</td>+<td align="left">Here's another one. Note the blank line between rows.</td>+</tr>+</tbody>+</table>
@@ -0,0 +1,168 @@+Simple table with caption:++\begin{longtable}[c]{@{}rlcl@{}}+\caption{Demonstration of simple table syntax.}\tabularnewline+\toprule+Right & Left & Center & Default\tabularnewline+\midrule+\endfirsthead+\toprule+Right & Left & Center & Default\tabularnewline+\midrule+\endhead+12 & 12 & 12 & 12\tabularnewline+123 & 123 & 123 & 123\tabularnewline+1 & 1 & 1 & 1\tabularnewline+\bottomrule+\end{longtable}++Simple table without caption:++\begin{longtable}[c]{@{}rlcl@{}}+\toprule+Right & Left & Center & Default\tabularnewline+\midrule+\endhead+12 & 12 & 12 & 12\tabularnewline+123 & 123 & 123 & 123\tabularnewline+1 & 1 & 1 & 1\tabularnewline+\bottomrule+\end{longtable}++Simple table indented two spaces:++\begin{longtable}[c]{@{}rlcl@{}}+\caption{Demonstration of simple table syntax.}\tabularnewline+\toprule+Right & Left & Center & Default\tabularnewline+\midrule+\endfirsthead+\toprule+Right & Left & Center & Default\tabularnewline+\midrule+\endhead+12 & 12 & 12 & 12\tabularnewline+123 & 123 & 123 & 123\tabularnewline+1 & 1 & 1 & 1\tabularnewline+\bottomrule+\end{longtable}++Multiline table with caption:++\begin{longtable}[c]{@{}clrl@{}}+\caption{Here's the caption. It may span multiple lines.}\tabularnewline+\toprule+\begin{minipage}[b]{0.13\hsize}\centering\strut+Centered Header+\strut\end{minipage} & \begin{minipage}[b]{0.12\hsize}\raggedright\strut+Left Aligned+\strut\end{minipage} & \begin{minipage}[b]{0.14\hsize}\raggedleft\strut+Right Aligned+\strut\end{minipage} & \begin{minipage}[b]{0.30\hsize}\raggedright\strut+Default aligned+\strut\end{minipage}\tabularnewline+\midrule+\endfirsthead+\toprule+\begin{minipage}[b]{0.13\hsize}\centering\strut+Centered Header+\strut\end{minipage} & \begin{minipage}[b]{0.12\hsize}\raggedright\strut+Left Aligned+\strut\end{minipage} & \begin{minipage}[b]{0.14\hsize}\raggedleft\strut+Right Aligned+\strut\end{minipage} & \begin{minipage}[b]{0.30\hsize}\raggedright\strut+Default aligned+\strut\end{minipage}\tabularnewline+\midrule+\endhead+\begin{minipage}[t]{0.13\hsize}\centering\strut+First+\strut\end{minipage} & \begin{minipage}[t]{0.12\hsize}\raggedright\strut+row+\strut\end{minipage} & \begin{minipage}[t]{0.14\hsize}\raggedleft\strut+12.0+\strut\end{minipage} & \begin{minipage}[t]{0.30\hsize}\raggedright\strut+Example of a row that spans multiple lines.+\strut\end{minipage}\tabularnewline+\begin{minipage}[t]{0.13\hsize}\centering\strut+Second+\strut\end{minipage} & \begin{minipage}[t]{0.12\hsize}\raggedright\strut+row+\strut\end{minipage} & \begin{minipage}[t]{0.14\hsize}\raggedleft\strut+5.0+\strut\end{minipage} & \begin{minipage}[t]{0.30\hsize}\raggedright\strut+Here's another one. Note the blank line between rows.+\strut\end{minipage}\tabularnewline+\bottomrule+\end{longtable}++Multiline table without caption:++\begin{longtable}[c]{@{}clrl@{}}+\toprule+\begin{minipage}[b]{0.13\hsize}\centering\strut+Centered Header+\strut\end{minipage} & \begin{minipage}[b]{0.12\hsize}\raggedright\strut+Left Aligned+\strut\end{minipage} & \begin{minipage}[b]{0.14\hsize}\raggedleft\strut+Right Aligned+\strut\end{minipage} & \begin{minipage}[b]{0.30\hsize}\raggedright\strut+Default aligned+\strut\end{minipage}\tabularnewline+\midrule+\endhead+\begin{minipage}[t]{0.13\hsize}\centering\strut+First+\strut\end{minipage} & \begin{minipage}[t]{0.12\hsize}\raggedright\strut+row+\strut\end{minipage} & \begin{minipage}[t]{0.14\hsize}\raggedleft\strut+12.0+\strut\end{minipage} & \begin{minipage}[t]{0.30\hsize}\raggedright\strut+Example of a row that spans multiple lines.+\strut\end{minipage}\tabularnewline+\begin{minipage}[t]{0.13\hsize}\centering\strut+Second+\strut\end{minipage} & \begin{minipage}[t]{0.12\hsize}\raggedright\strut+row+\strut\end{minipage} & \begin{minipage}[t]{0.14\hsize}\raggedleft\strut+5.0+\strut\end{minipage} & \begin{minipage}[t]{0.30\hsize}\raggedright\strut+Here's another one. Note the blank line between rows.+\strut\end{minipage}\tabularnewline+\bottomrule+\end{longtable}++Table without column headers:++\begin{longtable}[c]{@{}rlcr@{}}+\toprule+12 & 12 & 12 & 12\tabularnewline+123 & 123 & 123 & 123\tabularnewline+1 & 1 & 1 & 1\tabularnewline+\bottomrule+\end{longtable}++Multiline table without column headers:++\begin{longtable}[c]{@{}clrl@{}}+\toprule+\begin{minipage}[t]{0.13\hsize}\centering\strut+First+\strut\end{minipage} & \begin{minipage}[t]{0.12\hsize}\raggedright\strut+row+\strut\end{minipage} & \begin{minipage}[t]{0.14\hsize}\raggedleft\strut+12.0+\strut\end{minipage} & \begin{minipage}[t]{0.30\hsize}\raggedright\strut+Example of a row that spans multiple lines.+\strut\end{minipage}\tabularnewline+\begin{minipage}[t]{0.13\hsize}\centering\strut+Second+\strut\end{minipage} & \begin{minipage}[t]{0.12\hsize}\raggedright\strut+row+\strut\end{minipage} & \begin{minipage}[t]{0.14\hsize}\raggedleft\strut+5.0+\strut\end{minipage} & \begin{minipage}[t]{0.30\hsize}\raggedright\strut+Here's another one. Note the blank line between rows.+\strut\end{minipage}\tabularnewline+\bottomrule+\end{longtable}
@@ -0,0 +1,267 @@+.PP+Simple table with caption:+.PP+Demonstration of simple table syntax.+.TS+tab(@);+r l c l.+T{+Right+T}@T{+Left+T}@T{+Center+T}@T{+Default+T}+_+T{+12+T}@T{+12+T}@T{+12+T}@T{+12+T}+T{+123+T}@T{+123+T}@T{+123+T}@T{+123+T}+T{+1+T}@T{+1+T}@T{+1+T}@T{+1+T}+.TE+.PP+Simple table without caption:+.PP+.TS+tab(@);+r l c l.+T{+Right+T}@T{+Left+T}@T{+Center+T}@T{+Default+T}+_+T{+12+T}@T{+12+T}@T{+12+T}@T{+12+T}+T{+123+T}@T{+123+T}@T{+123+T}@T{+123+T}+T{+1+T}@T{+1+T}@T{+1+T}@T{+1+T}+.TE+.PP+Simple table indented two spaces:+.PP+Demonstration of simple table syntax.+.TS+tab(@);+r l c l.+T{+Right+T}@T{+Left+T}@T{+Center+T}@T{+Default+T}+_+T{+12+T}@T{+12+T}@T{+12+T}@T{+12+T}+T{+123+T}@T{+123+T}@T{+123+T}@T{+123+T}+T{+1+T}@T{+1+T}@T{+1+T}@T{+1+T}+.TE+.PP+Multiline table with caption:+.PP+Here\[aq]s the caption. It may span multiple lines.+.TS+tab(@);+cw(10.5n) lw(9.6n) rw(11.4n) lw(23.6n).+T{+Centered Header+T}@T{+Left Aligned+T}@T{+Right Aligned+T}@T{+Default aligned+T}+_+T{+First+T}@T{+row+T}@T{+12.0+T}@T{+Example of a row that spans multiple lines.+T}+T{+Second+T}@T{+row+T}@T{+5.0+T}@T{+Here\[aq]s another one.+Note the blank line between rows.+T}+.TE+.PP+Multiline table without caption:+.PP+.TS+tab(@);+cw(10.5n) lw(9.6n) rw(11.4n) lw(23.6n).+T{+Centered Header+T}@T{+Left Aligned+T}@T{+Right Aligned+T}@T{+Default aligned+T}+_+T{+First+T}@T{+row+T}@T{+12.0+T}@T{+Example of a row that spans multiple lines.+T}+T{+Second+T}@T{+row+T}@T{+5.0+T}@T{+Here\[aq]s another one.+Note the blank line between rows.+T}+.TE+.PP+Table without column headers:+.PP+.TS+tab(@);+r l c r.+T{+12+T}@T{+12+T}@T{+12+T}@T{+12+T}+T{+123+T}@T{+123+T}@T{+123+T}@T{+123+T}+T{+1+T}@T{+1+T}@T{+1+T}@T{+1+T}+.TE+.PP+Multiline table without column headers:+.PP+.TS+tab(@);+cw(10.5n) lw(9.6n) rw(11.4n) lw(23.6n).+T{+First+T}@T{+row+T}@T{+12.0+T}@T{+Example of a row that spans multiple lines.+T}+T{+Second+T}@T{+row+T}@T{+5.0+T}@T{+Here\[aq]s another one.+Note the blank line between rows.+T}+.TE
@@ -0,0 +1,78 @@+Simple table with caption:++ Right Left Center Default+ ------- ------ -------- ---------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1++ : Demonstration of simple table syntax.++Simple table without caption:++ Right Left Center Default+ ------- ------ -------- ---------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1++Simple table indented two spaces:++ Right Left Center Default+ ------- ------ -------- ---------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1++ : Demonstration of simple table syntax.++Multiline table with caption:++ --------------------------------------------------------------+ Centered Left Right Default aligned+ Header Aligned Aligned + ----------- ---------- ------------ --------------------------+ First row 12.0 Example of a row that+ spans multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ --------------------------------------------------------------++ : Here's the caption. It may span multiple lines.++Multiline table without caption:++ --------------------------------------------------------------+ Centered Left Right Default aligned+ Header Aligned Aligned + ----------- ---------- ------------ --------------------------+ First row 12.0 Example of a row that+ spans multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ --------------------------------------------------------------++Table without column headers:++ ----- ----- ----- -----+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1+ ----- ----- ----- -----++Multiline table without column headers:++ ----------- ---------- ------------ --------------------------+ First row 12.0 Example of a row that+ spans multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ ----------- ---------- ------------ --------------------------++
@@ -0,0 +1,114 @@+[Para [Str "Simple",Space,Str "table",Space,Str "with",Space,Str "caption:"]+,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignRight,AlignLeft,AlignCenter,AlignDefault] [0.0,0.0,0.0,0.0]+ [[Plain [Str "Right"]]+ ,[Plain [Str "Left"]]+ ,[Plain [Str "Center"]]+ ,[Plain [Str "Default"]]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Simple",Space,Str "table",Space,Str "without",Space,Str "caption:"]+,Table [] [AlignRight,AlignLeft,AlignCenter,AlignDefault] [0.0,0.0,0.0,0.0]+ [[Plain [Str "Right"]]+ ,[Plain [Str "Left"]]+ ,[Plain [Str "Center"]]+ ,[Plain [Str "Default"]]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Simple",Space,Str "table",Space,Str "indented",Space,Str "two",Space,Str "spaces:"]+,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignRight,AlignLeft,AlignCenter,AlignDefault] [0.0,0.0,0.0,0.0]+ [[Plain [Str "Right"]]+ ,[Plain [Str "Left"]]+ ,[Plain [Str "Center"]]+ ,[Plain [Str "Default"]]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Multiline",Space,Str "table",Space,Str "with",Space,Str "caption:"]+,Table [Str "Here's",Space,Str "the",Space,Str "caption.",Space,Str "It",Space,Str "may",Space,Str "span",Space,Str "multiple",Space,Str "lines."] [AlignCenter,AlignLeft,AlignRight,AlignLeft] [0.15,0.1375,0.1625,0.3375]+ [[Plain [Str "Centered",Space,Str "Header"]]+ ,[Plain [Str "Left",Space,Str "Aligned"]]+ ,[Plain [Str "Right",Space,Str "Aligned"]]+ ,[Plain [Str "Default",Space,Str "aligned"]]]+ [[[Plain [Str "First"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "12.0"]]+ ,[Plain [Str "Example",Space,Str "of",Space,Str "a",Space,Str "row",Space,Str "that",Space,Str "spans",Space,Str "multiple",Space,Str "lines."]]]+ ,[[Plain [Str "Second"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "5.0"]]+ ,[Plain [Str "Here's",Space,Str "another",Space,Str "one.",Space,Str "Note",Space,Str "the",Space,Str "blank",Space,Str "line",Space,Str "between",Space,Str "rows."]]]]+,Para [Str "Multiline",Space,Str "table",Space,Str "without",Space,Str "caption:"]+,Table [] [AlignCenter,AlignLeft,AlignRight,AlignLeft] [0.15,0.1375,0.1625,0.3375]+ [[Plain [Str "Centered",Space,Str "Header"]]+ ,[Plain [Str "Left",Space,Str "Aligned"]]+ ,[Plain [Str "Right",Space,Str "Aligned"]]+ ,[Plain [Str "Default",Space,Str "aligned"]]]+ [[[Plain [Str "First"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "12.0"]]+ ,[Plain [Str "Example",Space,Str "of",Space,Str "a",Space,Str "row",Space,Str "that",Space,Str "spans",Space,Str "multiple",Space,Str "lines."]]]+ ,[[Plain [Str "Second"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "5.0"]]+ ,[Plain [Str "Here's",Space,Str "another",Space,Str "one.",Space,Str "Note",Space,Str "the",Space,Str "blank",Space,Str "line",Space,Str "between",Space,Str "rows."]]]]+,Para [Str "Table",Space,Str "without",Space,Str "column",Space,Str "headers:"]+,Table [] [AlignRight,AlignLeft,AlignCenter,AlignRight] [0.0,0.0,0.0,0.0]+ [[]+ ,[]+ ,[]+ ,[]]+ [[[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]+ ,[Plain [Str "12"]]]+ ,[[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]+ ,[Plain [Str "123"]]]+ ,[[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]+ ,[Plain [Str "1"]]]]+,Para [Str "Multiline",Space,Str "table",Space,Str "without",Space,Str "column",Space,Str "headers:"]+,Table [] [AlignCenter,AlignLeft,AlignRight,AlignDefault] [0.15,0.1375,0.1625,0.3375]+ [[]+ ,[]+ ,[]+ ,[]]+ [[[Plain [Str "First"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "12.0"]]+ ,[Plain [Str "Example",Space,Str "of",Space,Str "a",Space,Str "row",Space,Str "that",Space,Str "spans",Space,Str "multiple",Space,Str "lines."]]]+ ,[[Plain [Str "Second"]]+ ,[Plain [Str "row"]]+ ,[Plain [Str "5.0"]]+ ,[Plain [Str "Here's",Space,Str "another",Space,Str "one.",Space,Str "Note",Space,Str "the",Space,Str "blank",Space,Str "line",Space,Str "between",Space,Str "rows."]]]]]
@@ -0,0 +1,78 @@+Simple table with caption:++ Right Left Center Default+ ------- ------ -------- ---------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1++ : Demonstration of simple table syntax.++Simple table without caption:++ Right Left Center Default+ ------- ------ -------- ---------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1++Simple table indented two spaces:++ Right Left Center Default+ ------- ------ -------- ---------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1++ : Demonstration of simple table syntax.++Multiline table with caption:++ --------------------------------------------------------------+ Centered Left Right Default aligned+ Header Aligned Aligned + ----------- ---------- ------------ --------------------------+ First row 12.0 Example of a row that+ spans multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ --------------------------------------------------------------++ : Here's the caption. It may span multiple lines.++Multiline table without caption:++ --------------------------------------------------------------+ Centered Left Right Default aligned+ Header Aligned Aligned + ----------- ---------- ------------ --------------------------+ First row 12.0 Example of a row that+ spans multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ --------------------------------------------------------------++Table without column headers:++ ----- ----- ----- -----+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1+ ----- ----- ----- -----++Multiline table without column headers:++ ----------- ---------- ------------ --------------------------+ First row 12.0 Example of a row that+ spans multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ ----------- ---------- ------------ --------------------------++
@@ -0,0 +1,75 @@+Simple table with caption:++ Right Left Center Default +------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 ++Table: Demonstration of simple table syntax.++Simple table without caption:++ Right Left Center Default +------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 ++Simple table indented two spaces:++ Right Left Center Default + ------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 ++ : Demonstration of simple table syntax.++Multiline table with caption:++: Here's the caption.+It may span multiple lines.++---------------------------------------------------------------+ Centered Left Right+ Header Aligned Aligned Default aligned+---------- --------- ----------- ---------------------------+ First row 12.0 Example of a row that spans+ multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between rows.+---------------------------------------------------------------++Multiline table without caption:++---------------------------------------------------------------+ Centered Left Right+ Header Aligned Aligned Default aligned+---------- --------- ----------- ---------------------------+ First row 12.0 Example of a row that spans+ multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between rows.+---------------------------------------------------------------++Table without column headers:++------- ------ ---------- -------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1+------- ------ ---------- -------++Multiline table without column headers:++---------- --------- ----------- ---------------------------+ First row 12.0 Example of a row that spans+ multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between rows.+---------- --------- ----------- ---------------------------+
@@ -0,0 +1,41 @@+{-# OPTIONS_GHC -Wall #-}++module Main where++import Test.Framework+import GHC.IO.Encoding+import qualified Tests.Old+import qualified Tests.Readers.LaTeX+import qualified Tests.Readers.Markdown+import qualified Tests.Writers.LaTeX+import qualified Tests.Writers.HTML+import qualified Tests.Writers.Native+import qualified Tests.Writers.Markdown+import qualified Tests.Writers.Plain+import qualified Tests.Shared+import qualified Tests.Walk+import Text.Pandoc.Shared (inDirectory)+import System.Environment (getArgs)++tests :: [Test]+tests = [ testGroup "Old" Tests.Old.tests+ , testGroup "Shared" Tests.Shared.tests+ , testGroup "Walk" Tests.Walk.tests+ , testGroup "Writers"+ [ testGroup "Native" Tests.Writers.Native.tests+ , testGroup "LaTeX" Tests.Writers.LaTeX.tests+ , testGroup "HTML" Tests.Writers.HTML.tests+ , testGroup "Markdown" Tests.Writers.Markdown.tests+ , testGroup "Plain" Tests.Writers.Plain.tests+ ]+ , testGroup "Readers"+ [ testGroup "LaTeX" Tests.Readers.LaTeX.tests+ , testGroup "Markdown" Tests.Readers.Markdown.tests+ ]+ ]++main :: IO ()+main = do+ setLocaleEncoding utf8+ args <- getArgs+ inDirectory "tests" $ defaultMainWithArgs tests args
@@ -0,0 +1,401 @@+Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "John",Space,Str "MacFarlane"],MetaInlines [Str "Anonymous"]]),("date",MetaInlines [Str "July",Space,Str "17,",Space,Str "2006"]),("title",MetaInlines [Str "Pandoc",Space,Str "Test",Space,Str "Suite"])]})+[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc.",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber\8217s",Space,Str "markdown",Space,Str "test",Space,Str "suite."]+,HorizontalRule+,Header 1 ("headers",[],[]) [Str "Headers"]+,Header 2 ("level-2-with-an-embedded-link",[],[]) [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embedded",Space,Str "link"] ("/url","")]+,Header 3 ("level-3-with-emphasis",[],[]) [Str "Level",Space,Str "3",Space,Str "with",Space,Emph [Str "emphasis"]]+,Header 4 ("level-4",[],[]) [Str "Level",Space,Str "4"]+,Header 5 ("level-5",[],[]) [Str "Level",Space,Str "5"]+,Header 1 ("level-1",[],[]) [Str "Level",Space,Str "1"]+,Header 2 ("level-2-with-emphasis",[],[]) [Str "Level",Space,Str "2",Space,Str "with",Space,Emph [Str "emphasis"]]+,Header 3 ("level-3",[],[]) [Str "Level",Space,Str "3"]+,Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]+,Header 2 ("level-2",[],[]) [Str "Level",Space,Str "2"]+,Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]+,HorizontalRule+,Header 1 ("paragraphs",[],[]) [Str "Paragraphs"]+,Para [Str "Here\8217s",Space,Str "a",Space,Str "regular",Space,Str "paragraph."]+,Para [Str "In",Space,Str "Markdown",Space,Str "1.0.0",Space,Str "and",Space,Str "earlier.",Space,Str "Version",Space,Str "8.",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item.",Space,Str "Because",Space,Str "a",Space,Str "hard-wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item."]+,Para [Str "Here\8217s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet.",Space,Str "*",Space,Str "criminey."]+,Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break",LineBreak,Str "here."]+,HorizontalRule+,Header 1 ("block-quotes",[],[]) [Str "Block",Space,Str "Quotes"]+,Para [Str "E-mail",Space,Str "style:"]+,BlockQuote+ [Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote.",Space,Str "It",Space,Str "is",Space,Str "pretty",Space,Str "short."]]+,BlockQuote+ [Para [Str "Code",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote:"]+ ,CodeBlock ("",[],[]) "sub status {\n print \"working\";\n}"+ ,Para [Str "A",Space,Str "list:"]+ ,OrderedList (1,Decimal,Period)+ [[Plain [Str "item",Space,Str "one"]]+ ,[Plain [Str "item",Space,Str "two"]]]+ ,Para [Str "Nested",Space,Str "block",Space,Str "quotes:"]+ ,BlockQuote+ [Para [Str "nested"]]+ ,BlockQuote+ [Para [Str "nested"]]]+,Para [Str "This",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "block",Space,Str "quote:",Space,Str "2",Space,Str ">",Space,Str "1."]+,Para [Str "And",Space,Str "a",Space,Str "following",Space,Str "paragraph."]+,HorizontalRule+,Header 1 ("code-blocks",[],[]) [Str "Code",Space,Str "Blocks"]+,Para [Str "Code:"]+,CodeBlock ("",[],[]) "---- (should be four hyphens)\n\nsub status {\n print \"working\";\n}\n\nthis code block is indented by one tab"+,Para [Str "And:"]+,CodeBlock ("",[],[]) " this code block is indented by two tabs\n\nThese should not be escaped: \\$ \\\\ \\> \\[ \\{"+,HorizontalRule+,Header 1 ("lists",[],[]) [Str "Lists"]+,Header 2 ("unordered",[],[]) [Str "Unordered"]+,Para [Str "Asterisks",Space,Str "tight:"]+,BulletList+ [[Plain [Str "asterisk",Space,Str "1"]]+ ,[Plain [Str "asterisk",Space,Str "2"]]+ ,[Plain [Str "asterisk",Space,Str "3"]]]+,Para [Str "Asterisks",Space,Str "loose:"]+,BulletList+ [[Para [Str "asterisk",Space,Str "1"]]+ ,[Para [Str "asterisk",Space,Str "2"]]+ ,[Para [Str "asterisk",Space,Str "3"]]]+,Para [Str "Pluses",Space,Str "tight:"]+,BulletList+ [[Plain [Str "Plus",Space,Str "1"]]+ ,[Plain [Str "Plus",Space,Str "2"]]+ ,[Plain [Str "Plus",Space,Str "3"]]]+,Para [Str "Pluses",Space,Str "loose:"]+,BulletList+ [[Para [Str "Plus",Space,Str "1"]]+ ,[Para [Str "Plus",Space,Str "2"]]+ ,[Para [Str "Plus",Space,Str "3"]]]+,Para [Str "Minuses",Space,Str "tight:"]+,BulletList+ [[Plain [Str "Minus",Space,Str "1"]]+ ,[Plain [Str "Minus",Space,Str "2"]]+ ,[Plain [Str "Minus",Space,Str "3"]]]+,Para [Str "Minuses",Space,Str "loose:"]+,BulletList+ [[Para [Str "Minus",Space,Str "1"]]+ ,[Para [Str "Minus",Space,Str "2"]]+ ,[Para [Str "Minus",Space,Str "3"]]]+,Header 2 ("ordered",[],[]) [Str "Ordered"]+,Para [Str "Tight:"]+,OrderedList (1,Decimal,Period)+ [[Plain [Str "First"]]+ ,[Plain [Str "Second"]]+ ,[Plain [Str "Third"]]]+,Para [Str "and:"]+,OrderedList (1,Decimal,Period)+ [[Plain [Str "One"]]+ ,[Plain [Str "Two"]]+ ,[Plain [Str "Three"]]]+,Para [Str "Loose",Space,Str "using",Space,Str "tabs:"]+,OrderedList (1,Decimal,Period)+ [[Para [Str "First"]]+ ,[Para [Str "Second"]]+ ,[Para [Str "Third"]]]+,Para [Str "and",Space,Str "using",Space,Str "spaces:"]+,OrderedList (1,Decimal,Period)+ [[Para [Str "One"]]+ ,[Para [Str "Two"]]+ ,[Para [Str "Three"]]]+,Para [Str "Multiple",Space,Str "paragraphs:"]+,OrderedList (1,Decimal,Period)+ [[Para [Str "Item",Space,Str "1,",Space,Str "graf",Space,Str "one."]+ ,Para [Str "Item",Space,Str "1.",Space,Str "graf",Space,Str "two.",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog\8217s",Space,Str "back."]]+ ,[Para [Str "Item",Space,Str "2."]]+ ,[Para [Str "Item",Space,Str "3."]]]+,Header 2 ("nested",[],[]) [Str "Nested"]+,BulletList+ [[Plain [Str "Tab"]+ ,BulletList+ [[Plain [Str "Tab"]+ ,BulletList+ [[Plain [Str "Tab"]]]]]]]+,Para [Str "Here\8217s",Space,Str "another:"]+,OrderedList (1,Decimal,Period)+ [[Plain [Str "First"]]+ ,[Plain [Str "Second:"]+ ,BulletList+ [[Plain [Str "Fee"]]+ ,[Plain [Str "Fie"]]+ ,[Plain [Str "Foe"]]]]+ ,[Plain [Str "Third"]]]+,Para [Str "Same",Space,Str "thing",Space,Str "but",Space,Str "with",Space,Str "paragraphs:"]+,OrderedList (1,Decimal,Period)+ [[Para [Str "First"]]+ ,[Para [Str "Second:"]+ ,BulletList+ [[Plain [Str "Fee"]]+ ,[Plain [Str "Fie"]]+ ,[Plain [Str "Foe"]]]]+ ,[Para [Str "Third"]]]+,Header 2 ("tabs-and-spaces",[],[]) [Str "Tabs",Space,Str "and",Space,Str "spaces"]+,BulletList+ [[Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"]]+ ,[Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"]+ ,BulletList+ [[Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"]]+ ,[Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"]]]]]+,Header 2 ("fancy-list-markers",[],[]) [Str "Fancy",Space,Str "list",Space,Str "markers"]+,OrderedList (2,Decimal,TwoParens)+ [[Plain [Str "begins",Space,Str "with",Space,Str "2"]]+ ,[Para [Str "and",Space,Str "now",Space,Str "3"]+ ,Para [Str "with",Space,Str "a",Space,Str "continuation"]+ ,OrderedList (4,LowerRoman,Period)+ [[Plain [Str "sublist",Space,Str "with",Space,Str "roman",Space,Str "numerals,",Space,Str "starting",Space,Str "with",Space,Str "4"]]+ ,[Plain [Str "more",Space,Str "items"]+ ,OrderedList (1,UpperAlpha,TwoParens)+ [[Plain [Str "a",Space,Str "subsublist"]]+ ,[Plain [Str "a",Space,Str "subsublist"]]]]]]]+,Para [Str "Nesting:"]+,OrderedList (1,UpperAlpha,Period)+ [[Plain [Str "Upper",Space,Str "Alpha"]+ ,OrderedList (1,UpperRoman,Period)+ [[Plain [Str "Upper",Space,Str "Roman."]+ ,OrderedList (6,Decimal,TwoParens)+ [[Plain [Str "Decimal",Space,Str "start",Space,Str "with",Space,Str "6"]+ ,OrderedList (3,LowerAlpha,OneParen)+ [[Plain [Str "Lower",Space,Str "alpha",Space,Str "with",Space,Str "paren"]]]]]]]]]+,Para [Str "Autonumbering:"]+,OrderedList (1,DefaultStyle,DefaultDelim)+ [[Plain [Str "Autonumber."]]+ ,[Plain [Str "More."]+ ,OrderedList (1,DefaultStyle,DefaultDelim)+ [[Plain [Str "Nested."]]]]]+,Para [Str "Should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "list",Space,Str "item:"]+,Para [Str "M.A.\160\&2007"]+,Para [Str "B.",Space,Str "Williams"]+,HorizontalRule+,Header 1 ("definition-lists",[],[]) [Str "Definition",Space,Str "Lists"]+,Para [Str "Tight",Space,Str "using",Space,Str "spaces:"]+,DefinitionList+ [([Str "apple"],+ [[Plain [Str "red",Space,Str "fruit"]]])+ ,([Str "orange"],+ [[Plain [Str "orange",Space,Str "fruit"]]])+ ,([Str "banana"],+ [[Plain [Str "yellow",Space,Str "fruit"]]])]+,Para [Str "Tight",Space,Str "using",Space,Str "tabs:"]+,DefinitionList+ [([Str "apple"],+ [[Plain [Str "red",Space,Str "fruit"]]])+ ,([Str "orange"],+ [[Plain [Str "orange",Space,Str "fruit"]]])+ ,([Str "banana"],+ [[Plain [Str "yellow",Space,Str "fruit"]]])]+,Para [Str "Loose:"]+,DefinitionList+ [([Str "apple"],+ [[Para [Str "red",Space,Str "fruit"]]])+ ,([Str "orange"],+ [[Para [Str "orange",Space,Str "fruit"]]])+ ,([Str "banana"],+ [[Para [Str "yellow",Space,Str "fruit"]]])]+,Para [Str "Multiple",Space,Str "blocks",Space,Str "with",Space,Str "italics:"]+,DefinitionList+ [([Emph [Str "apple"]],+ [[Para [Str "red",Space,Str "fruit"]+ ,Para [Str "contains",Space,Str "seeds,",Space,Str "crisp,",Space,Str "pleasant",Space,Str "to",Space,Str "taste"]]])+ ,([Emph [Str "orange"]],+ [[Para [Str "orange",Space,Str "fruit"]+ ,CodeBlock ("",[],[]) "{ orange code block }"+ ,BlockQuote+ [Para [Str "orange",Space,Str "block",Space,Str "quote"]]]])]+,Para [Str "Multiple",Space,Str "definitions,",Space,Str "tight:"]+,DefinitionList+ [([Str "apple"],+ [[Plain [Str "red",Space,Str "fruit"]]+ ,[Plain [Str "computer"]]])+ ,([Str "orange"],+ [[Plain [Str "orange",Space,Str "fruit"]]+ ,[Plain [Str "bank"]]])]+,Para [Str "Multiple",Space,Str "definitions,",Space,Str "loose:"]+,DefinitionList+ [([Str "apple"],+ [[Para [Str "red",Space,Str "fruit"]]+ ,[Para [Str "computer"]]])+ ,([Str "orange"],+ [[Para [Str "orange",Space,Str "fruit"]]+ ,[Para [Str "bank"]]])]+,Para [Str "Blank",Space,Str "line",Space,Str "after",Space,Str "term,",Space,Str "indented",Space,Str "marker,",Space,Str "alternate",Space,Str "markers:"]+,DefinitionList+ [([Str "apple"],+ [[Para [Str "red",Space,Str "fruit"]]+ ,[Para [Str "computer"]]])+ ,([Str "orange"],+ [[Para [Str "orange",Space,Str "fruit"]+ ,OrderedList (1,Decimal,Period)+ [[Plain [Str "sublist"]]+ ,[Plain [Str "sublist"]]]]])]+,Header 1 ("html-blocks",[],[]) [Str "HTML",Space,Str "Blocks"]+,Para [Str "Simple",Space,Str "block",Space,Str "on",Space,Str "one",Space,Str "line:"]+,Div ("",[],[]) [Plain [Str "foo"]]+,Para [Str "And",Space,Str "nested",Space,Str "without",Space,Str "indentation:"]+,Div ("",[],[]) [Div ("",[],[]) [Div ("",[],[]) [Para [Str "foo"]]],Div ("",[],[]) [Plain [Str "bar"]]]+,Para [Str "Interpreted",Space,Str "markdown",Space,Str "in",Space,Str "a",Space,Str "table:"]+,RawBlock (Format "html") "<table>"+,RawBlock (Format "html") "<tr>"+,RawBlock (Format "html") "<td>"+,Plain [Str "This",Space,Str "is",Space,Emph [Str "emphasized"]]+,RawBlock (Format "html") "</td>"+,RawBlock (Format "html") "<td>"+,Plain [Str "And",Space,Str "this",Space,Str "is",Space,Strong [Str "strong"]]+,RawBlock (Format "html") "</td>"+,RawBlock (Format "html") "</tr>"+,RawBlock (Format "html") "</table>"+,RawBlock (Format "html") "<script type=\"text/javascript\">document.write('This *should not* be interpreted as markdown');</script>"+,Para [Str "Here\8217s",Space,Str "a",Space,Str "simple",Space,Str "block:"]+,Div ("",[],[]) [Para [Str "foo"]]+,Para [Str "This",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "code",Space,Str "block,",Space,Str "though:"]+,CodeBlock ("",[],[]) "<div>\n foo\n</div>"+,Para [Str "As",Space,Str "should",Space,Str "this:"]+,CodeBlock ("",[],[]) "<div>foo</div>"+,Para [Str "Now,",Space,Str "nested:"]+,Div ("",[],[]) [Div ("",[],[]) [Div ("",[],[]) [Plain [Str "foo"]]]]+,Para [Str "This",Space,Str "should",Space,Str "just",Space,Str "be",Space,Str "an",Space,Str "HTML",Space,Str "comment:"]+,RawBlock (Format "html") "<!-- Comment -->"+,Para [Str "Multiline:"]+,RawBlock (Format "html") "<!--\nBlah\nBlah\n-->"+,RawBlock (Format "html") "<!--\n This is another comment.\n-->"+,Para [Str "Code",Space,Str "block:"]+,CodeBlock ("",[],[]) "<!-- Comment -->"+,Para [Str "Just",Space,Str "plain",Space,Str "comment,",Space,Str "with",Space,Str "trailing",Space,Str "spaces",Space,Str "on",Space,Str "the",Space,Str "line:"]+,RawBlock (Format "html") "<!-- foo -->"+,Para [Str "Code:"]+,CodeBlock ("",[],[]) "<hr />"+,Para [Str "Hr\8217s:"]+,RawBlock (Format "html") "<hr>"+,RawBlock (Format "html") "<hr />"+,RawBlock (Format "html") "<hr />"+,RawBlock (Format "html") "<hr>"+,RawBlock (Format "html") "<hr />"+,RawBlock (Format "html") "<hr />"+,RawBlock (Format "html") "<hr class=\"foo\" id=\"bar\" />"+,RawBlock (Format "html") "<hr class=\"foo\" id=\"bar\" />"+,RawBlock (Format "html") "<hr class=\"foo\" id=\"bar\">"+,HorizontalRule+,Header 1 ("inline-markup",[],[]) [Str "Inline",Space,Str "Markup"]+,Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ",",Space,Str "and",Space,Str "so",Space,Emph [Str "is",Space,Str "this"],Str "."]+,Para [Str "This",Space,Str "is",Space,Strong [Str "strong"],Str ",",Space,Str "and",Space,Str "so",Space,Strong [Str "is",Space,Str "this"],Str "."]+,Para [Str "An",Space,Emph [Link [Str "emphasized",Space,Str "link"] ("/url","")],Str "."]+,Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]+,Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word."]+,Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]+,Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word."]+,Para [Str "This",Space,Str "is",Space,Str "code:",Space,Code ("",[],[]) ">",Str ",",Space,Code ("",[],[]) "$",Str ",",Space,Code ("",[],[]) "\\",Str ",",Space,Code ("",[],[]) "\\$",Str ",",Space,Code ("",[],[]) "<html>",Str "."]+,Para [Strikeout [Str "This",Space,Str "is",Space,Emph [Str "strikeout"],Str "."]]+,Para [Str "Superscripts:",Space,Str "a",Superscript [Str "bc"],Str "d",Space,Str "a",Superscript [Emph [Str "hello"]],Space,Str "a",Superscript [Str "hello\160there"],Str "."]+,Para [Str "Subscripts:",Space,Str "H",Subscript [Str "2"],Str "O,",Space,Str "H",Subscript [Str "23"],Str "O,",Space,Str "H",Subscript [Str "many\160of\160them"],Str "O."]+,Para [Str "These",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "superscripts",Space,Str "or",Space,Str "subscripts,",Space,Str "because",Space,Str "of",Space,Str "the",Space,Str "unescaped",Space,Str "spaces:",Space,Str "a^b",Space,Str "c^d,",Space,Str "a~b",Space,Str "c~d."]+,HorizontalRule+,Header 1 ("smart-quotes-ellipses-dashes",[],[]) [Str "Smart",Space,Str "quotes,",Space,Str "ellipses,",Space,Str "dashes"]+,Para [Quoted DoubleQuote [Str "Hello,"],Space,Str "said",Space,Str "the",Space,Str "spider.",Space,Quoted DoubleQuote [Quoted SingleQuote [Str "Shelob"],Space,Str "is",Space,Str "my",Space,Str "name."]]+,Para [Quoted SingleQuote [Str "A"],Str ",",Space,Quoted SingleQuote [Str "B"],Str ",",Space,Str "and",Space,Quoted SingleQuote [Str "C"],Space,Str "are",Space,Str "letters."]+,Para [Quoted SingleQuote [Str "Oak,"],Space,Quoted SingleQuote [Str "elm,"],Space,Str "and",Space,Quoted SingleQuote [Str "beech"],Space,Str "are",Space,Str "names",Space,Str "of",Space,Str "trees.",Space,Str "So",Space,Str "is",Space,Quoted SingleQuote [Str "pine."]]+,Para [Quoted SingleQuote [Str "He",Space,Str "said,",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70\8217s?"]+,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "quoted",Space,Quoted SingleQuote [Code ("",[],[]) "code"],Space,Str "and",Space,Str "a",Space,Quoted DoubleQuote [Link [Str "quoted",Space,Str "link"] ("http://example.com/?foo=1&bar=2","")],Str "."]+,Para [Str "Some",Space,Str "dashes:",Space,Str "one\8212two",Space,Str "\8212",Space,Str "three\8212four",Space,Str "\8212",Space,Str "five."]+,Para [Str "Dashes",Space,Str "between",Space,Str "numbers:",Space,Str "5\8211\&7,",Space,Str "255\8211\&66,",Space,Str "1987\8211\&1999."]+,Para [Str "Ellipses\8230and\8230and\8230."]+,HorizontalRule+,Header 1 ("latex",[],[]) [Str "LaTeX"]+,BulletList+ [[Plain [RawInline (Format "tex") "\\cite[22-23]{smith.1899}"]]+ ,[Plain [Math InlineMath "2+2=4"]]+ ,[Plain [Math InlineMath "x \\in y"]]+ ,[Plain [Math InlineMath "\\alpha \\wedge \\omega"]]+ ,[Plain [Math InlineMath "223"]]+ ,[Plain [Math InlineMath "p",Str "-Tree"]]+ ,[Plain [Str "Here\8217s",Space,Str "some",Space,Str "display",Space,Str "math:",Space,Math (DisplayMath ("",[],[])) "\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"]]+ ,[Plain [Str "Here\8217s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it:",Space,Math InlineMath "\\alpha + \\omega \\times x^2",Str "."]]]+,Para [Str "These",Space,Str "shouldn\8217t",Space,Str "be",Space,Str "math:"]+,BulletList+ [[Plain [Str "To",Space,Str "get",Space,Str "the",Space,Str "famous",Space,Str "equation,",Space,Str "write",Space,Code ("",[],[]) "$e = mc^2$",Str "."]]+ ,[Plain [Str "$22,000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money.",Space,Str "So",Space,Str "is",Space,Str "$34,000.",Space,Str "(It",Space,Str "worked",Space,Str "if",Space,Quoted DoubleQuote [Str "lot"],Space,Str "is",Space,Str "emphasized.)"]]+ ,[Plain [Str "Shoes",Space,Str "($20)",Space,Str "and",Space,Str "socks",Space,Str "($5)."]]+ ,[Plain [Str "Escaped",Space,Code ("",[],[]) "$",Str ":",Space,Str "$73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23$."]]]+,Para [Str "Here\8217s",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]+,RawBlock (Format "latex") "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}"+,HorizontalRule+,Header 1 ("special-characters",[],[]) [Str "Special",Space,Str "Characters"]+,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode:"]+,BulletList+ [[Plain [Str "I",Space,Str "hat:",Space,Str "\206"]]+ ,[Plain [Str "o",Space,Str "umlaut:",Space,Str "\246"]]+ ,[Plain [Str "section:",Space,Str "\167"]]+ ,[Plain [Str "set",Space,Str "membership:",Space,Str "\8712"]]+ ,[Plain [Str "copyright:",Space,Str "\169"]]]+,Para [Str "AT&T",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "their",Space,Str "name."]+,Para [Str "AT&T",Space,Str "is",Space,Str "another",Space,Str "way",Space,Str "to",Space,Str "write",Space,Str "it."]+,Para [Str "This",Space,Str "&",Space,Str "that."]+,Para [Str "4",Space,Str "<",Space,Str "5."]+,Para [Str "6",Space,Str ">",Space,Str "5."]+,Para [Str "Backslash:",Space,Str "\\"]+,Para [Str "Backtick:",Space,Str "`"]+,Para [Str "Asterisk:",Space,Str "*"]+,Para [Str "Underscore:",Space,Str "_"]+,Para [Str "Left",Space,Str "brace:",Space,Str "{"]+,Para [Str "Right",Space,Str "brace:",Space,Str "}"]+,Para [Str "Left",Space,Str "bracket:",Space,Str "["]+,Para [Str "Right",Space,Str "bracket:",Space,Str "]"]+,Para [Str "Left",Space,Str "paren:",Space,Str "("]+,Para [Str "Right",Space,Str "paren:",Space,Str ")"]+,Para [Str "Greater-than:",Space,Str ">"]+,Para [Str "Hash:",Space,Str "#"]+,Para [Str "Period:",Space,Str "."]+,Para [Str "Bang:",Space,Str "!"]+,Para [Str "Plus:",Space,Str "+"]+,Para [Str "Minus:",Space,Str "-"]+,HorizontalRule+,Header 1 ("links",[],[]) [Str "Links"]+,Header 2 ("explicit",[],[]) [Str "Explicit"]+,Para [Str "Just",Space,Str "a",Space,Link [Str "URL"] ("/url/",""),Str "."]+,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title"),Str "."]+,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title preceded by two spaces"),Str "."]+,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title preceded by a tab"),Str "."]+,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title with \"quotes\" in it")]+,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title with single quotes")]+,Para [Link [Str "with_underscore"] ("/url/with_underscore","")]+,Para [Link [Str "Email",Space,Str "link"] ("mailto:nobody@nowhere.net","")]+,Para [Link [Str "Empty"] ("",""),Str "."]+,Header 2 ("reference",[],[]) [Str "Reference"]+,Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+,Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+,Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+,Para [Str "With",Space,Link [Str "embedded",Space,Str "[brackets]"] ("/url/",""),Str "."]+,Para [Link [Str "b"] ("/url/",""),Space,Str "by",Space,Str "itself",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "link."]+,Para [Str "Indented",Space,Link [Str "once"] ("/url",""),Str "."]+,Para [Str "Indented",Space,Link [Str "twice"] ("/url",""),Str "."]+,Para [Str "Indented",Space,Link [Str "thrice"] ("/url",""),Str "."]+,Para [Str "This",Space,Str "should",Space,Str "[not][]",Space,Str "be",Space,Str "a",Space,Str "link."]+,CodeBlock ("",[],[]) "[not]: /url"+,Para [Str "Foo",Space,Link [Str "bar"] ("/url/","Title with \"quotes\" inside"),Str "."]+,Para [Str "Foo",Space,Link [Str "biz"] ("/url/","Title with \"quote\" inside"),Str "."]+,Header 2 ("with-ampersands",[],[]) [Str "With",Space,Str "ampersands"]+,Para [Str "Here\8217s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]+,Para [Str "Here\8217s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text:",Space,Link [Str "AT&T"] ("http://att.com/","AT&T"),Str "."]+,Para [Str "Here\8217s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]+,Para [Str "Here\8217s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]+,Header 2 ("autolinks",[],[]) [Str "Autolinks"]+,Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link [Str "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]+,BulletList+ [[Plain [Str "In",Space,Str "a",Space,Str "list?"]]+ ,[Plain [Link [Str "http://example.com/"] ("http://example.com/","")]]+ ,[Plain [Str "It",Space,Str "should."]]]+,Para [Str "An",Space,Str "e-mail",Space,Str "address:",Space,Link [Str "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]+,BlockQuote+ [Para [Str "Blockquoted:",Space,Link [Str "http://example.com/"] ("http://example.com/","")]]+,Para [Str "Auto-links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",Space,Code ("",[],[]) "<http://example.com/>"]+,CodeBlock ("",[],[]) "or here: <http://example.com/>"+,HorizontalRule+,Header 1 ("images",[],[]) [Str "Images"]+,Para [Str "From",Space,Quoted DoubleQuote [Str "Voyage",Space,Str "dans",Space,Str "la",Space,Str "Lune"],Space,Str "by",Space,Str "Georges",Space,Str "Melies",Space,Str "(1902):"]+,Para [Image ("",[],[]) [Str "lalune"] ("lalune.jpg","fig:Voyage dans la Lune")]+,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image ("",[],[]) [Str "movie"] ("movie.jpg",""),Space,Str "icon."]+,HorizontalRule+,Header 1 ("footnotes",[],[]) [Str "Footnotes"]+,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote.",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference.",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document."]],Space,Str "and",Space,Str "another.",Note [Para [Str "Here\8217s",Space,Str "the",Space,Str "long",Space,Str "note.",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "list",Space,Str "items)."],CodeBlock ("",[],[]) " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line,",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space.[^my",Space,Str "note]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note.",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type.",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code ("",[],[]) "]",Space,Str "verbatim",Space,Str "characters,",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[bracketed",Space,Str "text]."]]]+,BlockQuote+ [Para [Str "Notes",Space,Str "can",Space,Str "go",Space,Str "in",Space,Str "quotes.",Note [Para [Str "In",Space,Str "quote."]]]]+,OrderedList (1,Decimal,Period)+ [[Plain [Str "And",Space,Str "in",Space,Str "list",Space,Str "items.",Note [Para [Str "In",Space,Str "list."]]]]]+,Para [Str "This",Space,Str "paragraph",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "part",Space,Str "of",Space,Str "the",Space,Str "note,",Space,Str "as",Space,Str "it",Space,Str "is",Space,Str "not",Space,Str "indented."]]
@@ -0,0 +1,730 @@+% Pandoc Test Suite+% John MacFarlane; Anonymous+% July 17, 2006++This is a set of tests for pandoc. Most of them are adapted from+John Gruber's markdown test suite.++-----++# Headers++## Level 2 with an [embedded link](/url)++### Level 3 with *emphasis*++#### Level 4++##### Level 5++Level 1+=======++Level 2 with *emphasis*+-----------------------++### Level 3+with no blank line++Level 2+-------+with no blank line++----------++# Paragraphs++Here's a regular paragraph.++In Markdown 1.0.0 and earlier. Version+8. This line turns into a list item.+Because a hard-wrapped line in the+middle of a paragraph looked like a+list item.++Here's one with a bullet.+* criminey.++There should be a hard line break +here.++---++# Block Quotes++E-mail style:++> This is a block quote.+> It is pretty short.++> Code in a block quote: +> +> sub status {+> print "working";+> }+> +> A list: +> +> 1. item one+> 2. item two+>+> Nested block quotes:+>+> > nested+>+>> nested+>++This should not be a block quote: 2+> 1.++And a following paragraph.++* * * *++# Code Blocks++Code:++ ---- (should be four hyphens)++ sub status {+ print "working";+ }++ this code block is indented by one tab++And:++ this code block is indented by two tabs++ These should not be escaped: \$ \\ \> \[ \{++___________++# Lists++## Unordered++Asterisks tight:++* asterisk 1+* asterisk 2+* asterisk 3++Asterisks loose:++* asterisk 1++* asterisk 2++* asterisk 3++Pluses tight:+++ Plus 1++ Plus 2++ Plus 3++Pluses loose:+++ Plus 1+++ Plus 2+++ Plus 3++Minuses tight:++- Minus 1+- Minus 2+- Minus 3++Minuses loose:++- Minus 1++- Minus 2++- Minus 3++## Ordered++Tight:++1. First+2. Second+3. Third++and:++1. One+2. Two+3. Three++Loose using tabs:++1. First++2. Second++3. Third++and using spaces:++1. One++2. Two++3. Three++Multiple paragraphs:++1. Item 1, graf one.++ Item 1. graf two. The quick brown fox jumped over the lazy dog's+ back.+ +2. Item 2.++3. Item 3.++## Nested++* Tab+ * Tab+ * Tab++Here's another:++1. First+2. Second:+ * Fee+ * Fie+ * Foe+3. Third++Same thing but with paragraphs:++1. First++2. Second:++ * Fee+ * Fie+ * Foe++3. Third ++## Tabs and spaces+++ this is a list item+ indented with tabs+++ this is a list item+ indented with spaces++ + this is an example list item+ indented with tabs+ + + this is an example list item+ indented with spaces++## Fancy list markers++(2) begins with 2+(3) and now 3++ with a continuation++ iv. sublist with roman numerals,+ starting with 4+ v. more items+ (A) a subsublist+ (B) a subsublist++Nesting:++A. Upper Alpha+ I. Upper Roman.+ (6) Decimal start with 6+ c) Lower alpha with paren++Autonumbering:++ #. Autonumber.+ #. More.+ #. Nested.++Should not be a list item:++M.A. 2007++B. Williams++ * * * * *++# Definition Lists++Tight using spaces:++apple+: red fruit++orange+: orange fruit++banana+: yellow fruit++Tight using tabs:++apple+: red fruit++orange+: orange fruit++banana+: yellow fruit++Loose:++apple++: red fruit++orange++: orange fruit++banana++: yellow fruit++Multiple blocks with italics:++*apple*++: red fruit++ contains seeds,+ crisp, pleasant to taste++*orange*++: orange fruit++ { orange code block }++ > orange block quote++Multiple definitions, tight:++apple+: red fruit+: computer++orange+: orange fruit+: bank++Multiple definitions, loose:++apple++: red fruit++: computer++orange++: orange fruit++: bank++Blank line after term, indented marker, alternate markers:++apple++ ~ red fruit++ ~ computer++orange++ ~ orange fruit++ 1. sublist+ 2. sublist++# HTML Blocks++Simple block on one line:++<div>foo</div>++And nested without indentation:++<div>+<div>+<div>+foo+</div>+</div>+<div>bar</div>+</div>++Interpreted markdown in a table:++<table>+<tr>+<td>This is *emphasized*</td>+<td>And this is **strong**</td>+</tr>+</table>++<script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>++Here's a simple block:++<div>+foo+</div>++This should be a code block, though:++ <div>+ foo+ </div>++As should this:++ <div>foo</div>++Now, nested:++<div>+ <div>+ <div>+ foo+ </div>+ </div>+</div>++This should just be an HTML comment:++<!-- Comment -->++Multiline:++<!--+Blah+Blah+-->++<!--+ This is another comment.+-->++Code block:++ <!-- Comment -->++Just plain comment, with trailing spaces on the line:++<!-- foo --> ++Code:++ <hr />+ +Hr's:++<hr>++<hr />++<hr />++<hr> ++<hr /> ++<hr /> ++<hr class="foo" id="bar" />++<hr class="foo" id="bar" />++<hr class="foo" id="bar">++-----++# Inline Markup++This is *emphasized*, and so _is this_.++This is **strong**, and so __is this__.++An *[emphasized link](/url)*.++***This is strong and em.***++So is ***this*** word.++___This is strong and em.___++So is ___this___ word.++This is code: `>`, `$`, `\`, `\$`, `<html>`.++~~This is *strikeout*.~~++Superscripts: a^bc^d a^*hello*^ a^hello\ there^.++Subscripts: H~2~O, H~23~O, H~many\ of\ them~O.++These should not be superscripts or subscripts,+because of the unescaped spaces: a^b c^d, a~b c~d.++-----++# Smart quotes, ellipses, dashes++"Hello," said the spider. "'Shelob' is my name."++'A', 'B', and 'C' are letters.++'Oak,' 'elm,' and 'beech' are names of trees.+So is 'pine.'++'He said, "I want to go."' Were you alive in the+70's?++Here is some quoted '`code`' and a "[quoted link][1]".++Some dashes: one---two --- three---four --- five.++Dashes between numbers: 5--7, 255--66, 1987--1999. ++Ellipses...and...and....++-----++# LaTeX++- \cite[22-23]{smith.1899}+- $2+2=4$+- $x \in y$+- $\alpha \wedge \omega$+- $223$ +- $p$-Tree+- Here's some display math:+ $$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$+- Here's one that has a line break in it: $\alpha + \omega \times+x^2$. ++These shouldn't be math:++- To get the famous equation, write `$e = mc^2$`.+- $22,000 is a *lot* of money. So is $34,000.+ (It worked if "lot" is emphasized.)+- Shoes ($20) and socks ($5).+- Escaped `$`: $73 *this should be emphasized* 23\$.++Here's a LaTeX table:++\begin{tabular}{|l|l|}\hline+Animal & Number \\ \hline+Dog & 2 \\+Cat & 1 \\ \hline+\end{tabular}++* * * * *++# Special Characters++Here is some unicode:++- I hat: Î+- o umlaut: ö+- section: § +- set membership: ∈+- copyright: ©++AT&T has an ampersand in their name.++AT&T is another way to write it.++This & that.++4 < 5.++6 > 5.++Backslash: \\++Backtick: \`++Asterisk: \*++Underscore: \_++Left brace: \{++Right brace: \}++Left bracket: \[++Right bracket: \]++Left paren: \(++Right paren: \)++Greater-than: \>++Hash: \#++Period: \.++Bang: \!++Plus: \+++Minus: \-++- - - - - - - - - - - - -++# Links++## Explicit++Just a [URL](/url/).++[URL and title](/url/ "title").++[URL and title](/url/ "title preceded by two spaces").++[URL and title](/url/ "title preceded by a tab").++[URL and title](/url/ "title with "quotes" in it")++[URL and title](/url/ 'title with single quotes')++[with\_underscore](/url/with_underscore)++[Email link](mailto:nobody@nowhere.net)++[Empty]().++## Reference++Foo [bar] [a].++Foo [bar][a].++Foo [bar]+[a].++[a]: /url/++With [embedded [brackets]] [b].++[b] by itself should be a link.++Indented [once][].++Indented [twice][].++Indented [thrice][].++This should [not][] be a link.++ [once]: /url+ [twice]: /url++ [thrice]: /url++ [not]: /url++[b]: /url/++Foo [bar][].++Foo [biz](/url/ "Title with "quote" inside").++ [bar]: /url/ "Title with "quotes" inside"++## With ampersands++Here's a [link with an ampersand in the URL] [1].++Here's a link with an amersand in the link text: [AT&T] [2].++Here's an [inline link](/script?foo=1&bar=2).++Here's an [inline link in pointy braces](</script?foo=1&bar=2>).++[1]: http://example.com/?foo=1&bar=2+[2]: http://att.com/ "AT&T" ++## Autolinks++With an ampersand: <http://example.com/?foo=1&bar=2>++* In a list?+* <http://example.com/>+* It should.++An e-mail address: <nobody@nowhere.net>++> Blockquoted: <http://example.com/>++Auto-links should not occur here: `<http://example.com/>`++ or here: <http://example.com/>++----++# Images++From "Voyage dans la Lune" by Georges Melies (1902):++![lalune][]++ [lalune]: lalune.jpg "Voyage dans la Lune"++Here is a movie  icon.++----++# Footnotes++Here is a footnote reference,[^1] and another.[^longnote]+This should *not* be a footnote reference, because it +contains a space.[^my note] Here is an inline note.^[This+is *easier* to type. Inline notes may contain+[links](http://google.com) and `]` verbatim characters,+as well as [bracketed text].]++> Notes can go in quotes.^[In quote.]++1. And in list items.^[In list.]++[^longnote]: Here's the long note. This one contains multiple+blocks. ++ Subsequent blocks are indented to show that they belong to the+footnote (as with list items).++ { <code> }++ If you want, you can indent every line, but you can also be+ lazy and just indent the first line of each block.++This paragraph should not be part of the note, as it is not indented.++ [^1]: Here is the footnote. It can go anywhere after the footnote+ reference. It need not be placed at the end of the document.
@@ -0,0 +1,660 @@+This is a set of tests for pandoc. Most of them are adapted from John Gruber’s+markdown test suite.++______________________________________________________________________________++= Headers+#headers#++== Level 2 with an </url embedded link>+#level-2-with-an-embedded-link#++=== Level 3 with /emphasis/+#level-3-with-emphasis#++==== Level 4+#level-4#++===== Level 5+#level-5#++= Level 1+#level-1#++== Level 2 with /emphasis/+#level-2-with-emphasis#++=== Level 3+#level-3#++with no blank line++== Level 2+#level-2#++with no blank line++______________________________________________________________________________++= Paragraphs+#paragraphs#++Here’s a regular paragraph.++In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item.+Because a hard-wrapped line in the middle of a paragraph looked like a list+item.++Here’s one with a bullet. * criminey.++There should be a hard line break+here.++______________________________________________________________________________++= Block Quotes+#block-quotes#++E-mail style:++This is a block quote. It is pretty short.++Code in a block quote:++> sub status {+> print "working";+> }++A list:++1. item one+2. item two++Nested block quotes:++nested++nested++This should not be a block quote: 2 > 1.++And a following paragraph.++______________________________________________________________________________++= Code Blocks+#code-blocks#++Code:++> ---- (should be four hyphens)+>+> sub status {+> print "working";+> }+>+> this code block is indented by one tab++And:++> this code block is indented by two tabs+>+> These should not be escaped: \$ \\ \> \[ \{++______________________________________________________________________________++= Lists+#lists#++== Unordered+#unordered#++Asterisks tight:++- asterisk 1+- asterisk 2+- asterisk 3++Asterisks loose:++- asterisk 1++- asterisk 2++- asterisk 3++Pluses tight:++- Plus 1+- Plus 2+- Plus 3++Pluses loose:++- Plus 1++- Plus 2++- Plus 3++Minuses tight:++- Minus 1+- Minus 2+- Minus 3++Minuses loose:++- Minus 1++- Minus 2++- Minus 3++== Ordered+#ordered#++Tight:++1. First+2. Second+3. Third++and:++1. One+2. Two+3. Three++Loose using tabs:++1. First++2. Second++3. Third++and using spaces:++1. One++2. Two++3. Three++Multiple paragraphs:++1. Item 1, graf one.++ Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.++2. Item 2.++3. Item 3.++== Nested+#nested#++- Tab+ - Tab+ - Tab++Here’s another:++1. First+2. Second:+ - Fee+ - Fie+ - Foe++3. Third++Same thing but with paragraphs:++1. First++2. Second:++ - Fee+ - Fie+ - Foe++3. Third++== Tabs and spaces+#tabs-and-spaces#++- this is a list item indented with tabs++- this is a list item indented with spaces++ - this is an example list item indented with tabs++ - this is an example list item indented with spaces++== Fancy list markers+#fancy-list-markers#++(2) begins with 2+(3) and now 3++ with a continuation++ 4. sublist with roman numerals, starting with 4+ 5. more items+ (1) a subsublist+ (2) a subsublist++Nesting:++1. Upper Alpha+ 1. Upper Roman.+ (6) Decimal start with 6+ 3) Lower alpha with paren++Autonumbering:++1. Autonumber.+2. More.+ 1. Nested.++Should not be a list item:++M.A. 2007++B. Williams++______________________________________________________________________________++= Definition Lists+#definition-lists#++Tight using spaces:++[apple]+ red fruit+[orange]+ orange fruit+[banana]+ yellow fruit++Tight using tabs:++[apple]+ red fruit+[orange]+ orange fruit+[banana]+ yellow fruit++Loose:++[apple]+ red fruit++[orange]+ orange fruit++[banana]+ yellow fruit++Multiple blocks with italics:++[/apple/]+ red fruit++ contains seeds, crisp, pleasant to taste++[/orange/]+ orange fruit++ > { orange code block }++ orange block quote++Multiple definitions, tight:++[apple]+ red fruit+ computer+[orange]+ orange fruit+ bank++Multiple definitions, loose:++[apple]+ red fruit++ computer++[orange]+ orange fruit++ bank++Blank line after term, indented marker, alternate markers:++[apple]+ red fruit++ computer++[orange]+ orange fruit++ 1. sublist+ 2. sublist++= HTML Blocks+#html-blocks#++Simple block on one line:++foo++And nested without indentation:++foo++bar++Interpreted markdown in a table:++This is /emphasized/+And this is __strong__+Here’s a simple block:++foo++This should be a code block, though:++> <div>+> foo+> </div>++As should this:++> <div>foo</div>++Now, nested:++foo++This should just be an HTML comment:++Multiline:++Code block:++> <!-- Comment -->++Just plain comment, with trailing spaces on the line:++Code:++> <hr />++Hr’s:++______________________________________________________________________________++= Inline Markup+#inline-markup#++This is /emphasized/, and so /is this/.++This is __strong__, and so __is this__.++An /</url emphasized link>/.++__/This is strong and em./__++So is __/this/__ word.++__/This is strong and em./__++So is __/this/__ word.++This is code: @>@, @$@, @\\@, @\\$@, @\<html>@.++~~This is /strikeout/.~~++Superscripts: abcd a/hello/ ahello there.++Subscripts: H2O, H23O, Hmany of themO.++These should not be superscripts or subscripts, because of the unescaped+spaces: a^b c^d, a~b c~d.++______________________________________________________________________________++= Smart quotes, ellipses, dashes+#smart-quotes-ellipses-dashes#++“Hello,” said the spider. “‘Shelob’ is my name.”++‘A’, ‘B’, and ‘C’ are letters.++‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’++‘He said, “I want to go.”’ Were you alive in the 70’s?++Here is some quoted ‘@code@’ and a+“<http://example.com/?foo=1&bar=2 quoted link>”.++Some dashes: one—two — three—four — five.++Dashes between numbers: 5–7, 255–66, 1987–1999.++Ellipses…and…and….++______________________________________________________________________________++= LaTeX+#latex#++- +- 2 + 2 = 4+- /x/ ∈ /y/+- /α/ ∧ /ω/+- 223+- /p/-Tree+- Here’s some display math:+ $$\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}$$+- Here’s one that has a line break in it: /α/ + /ω/ × /x/2.++These shouldn’t be math:++- To get the famous equation, write @$e = mc^2$@.+- $22,000 is a /lot/ of money. So is $34,000. (It worked if “lot” is+ emphasized.)+- Shoes ($20) and socks ($5).+- Escaped @$@: $73 /this should be emphasized/ 23$.++Here’s a LaTeX table:++______________________________________________________________________________++= Special Characters+#special-characters#++Here is some unicode:++- I hat: Î+- o umlaut: ö+- section: §+- set membership: ∈+- copyright: ©++AT&T has an ampersand in their name.++AT&T is another way to write it.++This & that.++4 \< 5.++6 > 5.++Backslash: \\++Backtick: \`++Asterisk: *++Underscore: _++Left brace: {++Right brace: }++Left bracket: [++Right bracket: ]++Left paren: (++Right paren: )++Greater-than: >++Hash: #++Period: .++Bang: !++Plus: +++Minus: -++______________________________________________________________________________++= Links+#links#++== Explicit+#explicit#++Just a </url/ URL>.++</url/ URL and title>.++</url/ URL and title>.++</url/ URL and title>.++</url/ URL and title>++</url/ URL and title>++</url/with_underscore with_underscore>++<mailto:nobody@nowhere.net Email link>++< Empty>.++== Reference+#reference#++Foo </url/ bar>.++Foo </url/ bar>.++Foo </url/ bar>.++With </url/ embedded [brackets]>.++</url/ b> by itself should be a link.++Indented </url once>.++Indented </url twice>.++Indented </url thrice>.++This should [not][] be a link.++> [not]: /url++Foo </url/ bar>.++Foo </url/ biz>.++== With ampersands+#with-ampersands#++Here’s a <http://example.com/?foo=1&bar=2 link with an ampersand in the URL>.++Here’s a link with an amersand in the link text: <http://att.com/ AT&T>.++Here’s an </script?foo=1&bar=2 inline link>.++Here’s an </script?foo=1&bar=2 inline link in pointy braces>.++== Autolinks+#autolinks#++With an ampersand: <http://example.com/?foo=1&bar=2>++- In a list?+- <http://example.com/>+- It should.++An e-mail address: <mailto:nobody@nowhere.net nobody\@nowhere.net>++Blockquoted: <http://example.com/>++Auto-links should not occur here: @\<http:\/\/example.com\/>@++> or here: <http://example.com/>++______________________________________________________________________________++= Images+#images#++From “Voyage dans la Lune” by Georges Melies (1902):++<<lalune.jpg lalune>>++Here is a movie <<movie.jpg movie>> icon.++______________________________________________________________________________++= Footnotes+#footnotes#++Here is a footnote reference,<#notes [1]> and another.<#notes [2]> This should+/not/ be a footnote reference, because it contains a space.[^my note] Here is+an inline note.<#notes [3]>++Notes can go in quotes.<#notes [4]>++1. And in list items.<#notes [5]>++This paragraph should not be part of the note, as it is not indented.++#notes#++1. Here is the footnote. It can go anywhere after the footnote reference. It+ need not be placed at the end of the document.++2. Here’s the long note. This one contains multiple blocks.++ Subsequent blocks are indented to show that they belong to the footnote+ (as with list items).++ > { <code> }++ If you want, you can indent every line, but you can also be lazy and just+ indent the first line of each block.++3. This is /easier/ to type. Inline notes may contain+ <http://google.com links> and @]@ verbatim characters, as well as+ [bracketed text].++4. In quote.++5. In list.
@@ -0,0 +1,557 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html xmlns="http://www.w3.org/1999/xhtml">+<head>+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />+ <meta http-equiv="Content-Style-Type" content="text/css" />+ <meta name="generator" content="pandoc" />+ <meta name="author" content="John MacFarlane" />+ <meta name="author" content="Anonymous" />+ <meta name="date" content="2006-07-17" />+ <title>Pandoc Test Suite</title>+ <style type="text/css">code{white-space: pre;}</style>+</head>+<body>+<div id="header">+<h1 class="title">Pandoc Test Suite</h1>+<h2 class="author">John MacFarlane</h2>+<h2 class="author">Anonymous</h2>+<h3 class="date">July 17, 2006</h3>+</div>+<p>This is a set of tests for pandoc. Most of them are adapted from John Gruber’s markdown test suite.</p>+<hr />+<h1 id="headers">Headers</h1>+<h2 id="level-2-with-an-embedded-link">Level 2 with an <a href="/url">embedded link</a></h2>+<h3 id="level-3-with-emphasis">Level 3 with <em>emphasis</em></h3>+<h4 id="level-4">Level 4</h4>+<h5 id="level-5">Level 5</h5>+<h1 id="level-1">Level 1</h1>+<h2 id="level-2-with-emphasis">Level 2 with <em>emphasis</em></h2>+<h3 id="level-3">Level 3</h3>+<p>with no blank line</p>+<h2 id="level-2">Level 2</h2>+<p>with no blank line</p>+<hr />+<h1 id="paragraphs">Paragraphs</h1>+<p>Here’s a regular paragraph.</p>+<p>In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item.</p>+<p>Here’s one with a bullet. * criminey.</p>+<p>There should be a hard line break<br />here.</p>+<hr />+<h1 id="block-quotes">Block Quotes</h1>+<p>E-mail style:</p>+<blockquote>+<p>This is a block quote. It is pretty short.</p>+</blockquote>+<blockquote>+<p>Code in a block quote:</p>+<pre><code>sub status {+ print "working";+}</code></pre>+<p>A list:</p>+<ol style="list-style-type: decimal">+<li>item one</li>+<li>item two</li>+</ol>+<p>Nested block quotes:</p>+<blockquote>+<p>nested</p>+</blockquote>+<blockquote>+<p>nested</p>+</blockquote>+</blockquote>+<p>This should not be a block quote: 2 > 1.</p>+<p>And a following paragraph.</p>+<hr />+<h1 id="code-blocks">Code Blocks</h1>+<p>Code:</p>+<pre><code>---- (should be four hyphens)++sub status {+ print "working";+}++this code block is indented by one tab</code></pre>+<p>And:</p>+<pre><code> this code block is indented by two tabs++These should not be escaped: \$ \\ \> \[ \{</code></pre>+<hr />+<h1 id="lists">Lists</h1>+<h2 id="unordered">Unordered</h2>+<p>Asterisks tight:</p>+<ul>+<li>asterisk 1</li>+<li>asterisk 2</li>+<li>asterisk 3</li>+</ul>+<p>Asterisks loose:</p>+<ul>+<li><p>asterisk 1</p></li>+<li><p>asterisk 2</p></li>+<li><p>asterisk 3</p></li>+</ul>+<p>Pluses tight:</p>+<ul>+<li>Plus 1</li>+<li>Plus 2</li>+<li>Plus 3</li>+</ul>+<p>Pluses loose:</p>+<ul>+<li><p>Plus 1</p></li>+<li><p>Plus 2</p></li>+<li><p>Plus 3</p></li>+</ul>+<p>Minuses tight:</p>+<ul>+<li>Minus 1</li>+<li>Minus 2</li>+<li>Minus 3</li>+</ul>+<p>Minuses loose:</p>+<ul>+<li><p>Minus 1</p></li>+<li><p>Minus 2</p></li>+<li><p>Minus 3</p></li>+</ul>+<h2 id="ordered">Ordered</h2>+<p>Tight:</p>+<ol style="list-style-type: decimal">+<li>First</li>+<li>Second</li>+<li>Third</li>+</ol>+<p>and:</p>+<ol style="list-style-type: decimal">+<li>One</li>+<li>Two</li>+<li>Three</li>+</ol>+<p>Loose using tabs:</p>+<ol style="list-style-type: decimal">+<li><p>First</p></li>+<li><p>Second</p></li>+<li><p>Third</p></li>+</ol>+<p>and using spaces:</p>+<ol style="list-style-type: decimal">+<li><p>One</p></li>+<li><p>Two</p></li>+<li><p>Three</p></li>+</ol>+<p>Multiple paragraphs:</p>+<ol style="list-style-type: decimal">+<li><p>Item 1, graf one.</p>+<p>Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.</p></li>+<li><p>Item 2.</p></li>+<li><p>Item 3.</p></li>+</ol>+<h2 id="nested">Nested</h2>+<ul>+<li>Tab+<ul>+<li>Tab+<ul>+<li>Tab</li>+</ul></li>+</ul></li>+</ul>+<p>Here’s another:</p>+<ol style="list-style-type: decimal">+<li>First</li>+<li>Second:+<ul>+<li>Fee</li>+<li>Fie</li>+<li>Foe</li>+</ul></li>+<li>Third</li>+</ol>+<p>Same thing but with paragraphs:</p>+<ol style="list-style-type: decimal">+<li><p>First</p></li>+<li><p>Second:</p>+<ul>+<li>Fee</li>+<li>Fie</li>+<li>Foe</li>+</ul></li>+<li><p>Third</p></li>+</ol>+<h2 id="tabs-and-spaces">Tabs and spaces</h2>+<ul>+<li><p>this is a list item indented with tabs</p></li>+<li><p>this is a list item indented with spaces</p>+<ul>+<li><p>this is an example list item indented with tabs</p></li>+<li><p>this is an example list item indented with spaces</p></li>+</ul></li>+</ul>+<h2 id="fancy-list-markers">Fancy list markers</h2>+<ol start="2" style="list-style-type: decimal">+<li>begins with 2</li>+<li><p>and now 3</p>+<p>with a continuation</p>+<ol start="4" style="list-style-type: lower-roman">+<li>sublist with roman numerals, starting with 4</li>+<li>more items+<ol style="list-style-type: upper-alpha">+<li>a subsublist</li>+<li>a subsublist</li>+</ol></li>+</ol></li>+</ol>+<p>Nesting:</p>+<ol style="list-style-type: upper-alpha">+<li>Upper Alpha+<ol style="list-style-type: upper-roman">+<li>Upper Roman.+<ol start="6" style="list-style-type: decimal">+<li>Decimal start with 6+<ol start="3" style="list-style-type: lower-alpha">+<li>Lower alpha with paren</li>+</ol></li>+</ol></li>+</ol></li>+</ol>+<p>Autonumbering:</p>+<ol>+<li>Autonumber.</li>+<li>More.+<ol>+<li>Nested.</li>+</ol></li>+</ol>+<p>Should not be a list item:</p>+<p>M.A. 2007</p>+<p>B. Williams</p>+<hr />+<h1 id="definition-lists">Definition Lists</h1>+<p>Tight using spaces:</p>+<dl>+<dt>apple</dt>+<dd>red fruit+</dd>+<dt>orange</dt>+<dd>orange fruit+</dd>+<dt>banana</dt>+<dd>yellow fruit+</dd>+</dl>+<p>Tight using tabs:</p>+<dl>+<dt>apple</dt>+<dd>red fruit+</dd>+<dt>orange</dt>+<dd>orange fruit+</dd>+<dt>banana</dt>+<dd>yellow fruit+</dd>+</dl>+<p>Loose:</p>+<dl>+<dt>apple</dt>+<dd><p>red fruit</p>+</dd>+<dt>orange</dt>+<dd><p>orange fruit</p>+</dd>+<dt>banana</dt>+<dd><p>yellow fruit</p>+</dd>+</dl>+<p>Multiple blocks with italics:</p>+<dl>+<dt><em>apple</em></dt>+<dd><p>red fruit</p>+<p>contains seeds, crisp, pleasant to taste</p>+</dd>+<dt><em>orange</em></dt>+<dd><p>orange fruit</p>+<pre><code>{ orange code block }</code></pre>+<blockquote>+<p>orange block quote</p>+</blockquote>+</dd>+</dl>+<p>Multiple definitions, tight:</p>+<dl>+<dt>apple</dt>+<dd>red fruit+</dd>+<dd>computer+</dd>+<dt>orange</dt>+<dd>orange fruit+</dd>+<dd>bank+</dd>+</dl>+<p>Multiple definitions, loose:</p>+<dl>+<dt>apple</dt>+<dd><p>red fruit</p>+</dd>+<dd><p>computer</p>+</dd>+<dt>orange</dt>+<dd><p>orange fruit</p>+</dd>+<dd><p>bank</p>+</dd>+</dl>+<p>Blank line after term, indented marker, alternate markers:</p>+<dl>+<dt>apple</dt>+<dd><p>red fruit</p>+</dd>+<dd><p>computer</p>+</dd>+<dt>orange</dt>+<dd><p>orange fruit</p>+<ol style="list-style-type: decimal">+<li>sublist</li>+<li>sublist</li>+</ol>+</dd>+</dl>+<h1 id="html-blocks">HTML Blocks</h1>+<p>Simple block on one line:</p>+<div>+foo+</div>+<p>And nested without indentation:</p>+<div>+<div>+<div>+<p>foo</p>+</div>+</div>+<div>+bar+</div>+</div>+<p>Interpreted markdown in a table:</p>+<table>+<tr>+<td>+This is <em>emphasized</em>+</td>+<td>+And this is <strong>strong</strong>+</td>+</tr>+</table>+<script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>+<p>Here’s a simple block:</p>+<div>+<p>foo</p>+</div>+<p>This should be a code block, though:</p>+<pre><code><div>+ foo+</div></code></pre>+<p>As should this:</p>+<pre><code><div>foo</div></code></pre>+<p>Now, nested:</p>+<div>+<div>+<div>+foo+</div>+</div>+</div>+<p>This should just be an HTML comment:</p>+<!-- Comment -->+<p>Multiline:</p>+<!--+Blah+Blah+-->+<!--+ This is another comment.+-->+<p>Code block:</p>+<pre><code><!-- Comment --></code></pre>+<p>Just plain comment, with trailing spaces on the line:</p>+<!-- foo -->+<p>Code:</p>+<pre><code><hr /></code></pre>+<p>Hr’s:</p>+<hr>+<hr />+<hr />+<hr>+<hr />+<hr />+<hr class="foo" id="bar" />+<hr class="foo" id="bar" />+<hr class="foo" id="bar">+<hr />+<h1 id="inline-markup">Inline Markup</h1>+<p>This is <em>emphasized</em>, and so <em>is this</em>.</p>+<p>This is <strong>strong</strong>, and so <strong>is this</strong>.</p>+<p>An <em><a href="/url">emphasized link</a></em>.</p>+<p><strong><em>This is strong and em.</em></strong></p>+<p>So is <strong><em>this</em></strong> word.</p>+<p><strong><em>This is strong and em.</em></strong></p>+<p>So is <strong><em>this</em></strong> word.</p>+<p>This is code: <code>></code>, <code>$</code>, <code>\</code>, <code>\$</code>, <code><html></code>.</p>+<p><del>This is <em>strikeout</em>.</del></p>+<p>Superscripts: a<sup>bc</sup>d a<sup><em>hello</em></sup> a<sup>hello there</sup>.</p>+<p>Subscripts: H<sub>2</sub>O, H<sub>23</sub>O, H<sub>many of them</sub>O.</p>+<p>These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.</p>+<hr />+<h1 id="smart-quotes-ellipses-dashes">Smart quotes, ellipses, dashes</h1>+<p>“Hello,” said the spider. “‘Shelob’ is my name.”</p>+<p>‘A’, ‘B’, and ‘C’ are letters.</p>+<p>‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’</p>+<p>‘He said, “I want to go.”’ Were you alive in the 70’s?</p>+<p>Here is some quoted ‘<code>code</code>’ and a “<a href="http://example.com/?foo=1&bar=2">quoted link</a>”.</p>+<p>Some dashes: one—two — three—four — five.</p>+<p>Dashes between numbers: 5–7, 255–66, 1987–1999.</p>+<p>Ellipses…and…and….</p>+<hr />+<h1 id="latex">LaTeX</h1>+<ul>+<li></li>+<li><span class="math">2 + 2 = 4</span></li>+<li><span class="math"><em>x</em> ∈ <em>y</em></span></li>+<li><span class="math"><em>α</em> ∧ <em>ω</em></span></li>+<li><span class="math">223</span></li>+<li><span class="math"><em>p</em></span>-Tree</li>+<li>Here’s some display math: <br /><span class="math">$$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$</span><br /></li>+<li>Here’s one that has a line break in it: <span class="math"><em>α</em> + <em>ω</em> × <em>x</em><sup>2</sup></span>.</li>+</ul>+<p>These shouldn’t be math:</p>+<ul>+<li>To get the famous equation, write <code>$e = mc^2$</code>.</li>+<li>$22,000 is a <em>lot</em> of money. So is $34,000. (It worked if “lot” is emphasized.)</li>+<li>Shoes ($20) and socks ($5).</li>+<li>Escaped <code>$</code>: $73 <em>this should be emphasized</em> 23$.</li>+</ul>+<p>Here’s a LaTeX table:</p>++<hr />+<h1 id="special-characters">Special Characters</h1>+<p>Here is some unicode:</p>+<ul>+<li>I hat: Î</li>+<li>o umlaut: ö</li>+<li>section: §</li>+<li>set membership: ∈</li>+<li>copyright: ©</li>+</ul>+<p>AT&T has an ampersand in their name.</p>+<p>AT&T is another way to write it.</p>+<p>This & that.</p>+<p>4 < 5.</p>+<p>6 > 5.</p>+<p>Backslash: \</p>+<p>Backtick: `</p>+<p>Asterisk: *</p>+<p>Underscore: _</p>+<p>Left brace: {</p>+<p>Right brace: }</p>+<p>Left bracket: [</p>+<p>Right bracket: ]</p>+<p>Left paren: (</p>+<p>Right paren: )</p>+<p>Greater-than: ></p>+<p>Hash: #</p>+<p>Period: .</p>+<p>Bang: !</p>+<p>Plus: +</p>+<p>Minus: -</p>+<hr />+<h1 id="links">Links</h1>+<h2 id="explicit">Explicit</h2>+<p>Just a <a href="/url/">URL</a>.</p>+<p><a href="/url/" title="title">URL and title</a>.</p>+<p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p>+<p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p>+<p><a href="/url/" title="title with "quotes" in it">URL and title</a></p>+<p><a href="/url/" title="title with single quotes">URL and title</a></p>+<p><a href="/url/with_underscore">with_underscore</a></p>+<p><script type="text/javascript">+<!--+h='nowhere.net';a='@';n='nobody';e=n+a+h;+document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'" clas'+'s="em' + 'ail">'+'Email link'+'<\/'+'a'+'>');+// -->+</script><noscript>Email link (nobody at nowhere dot net)</noscript></p>+<p><a href="">Empty</a>.</p>+<h2 id="reference">Reference</h2>+<p>Foo <a href="/url/">bar</a>.</p>+<p>Foo <a href="/url/">bar</a>.</p>+<p>Foo <a href="/url/">bar</a>.</p>+<p>With <a href="/url/">embedded [brackets]</a>.</p>+<p><a href="/url/">b</a> by itself should be a link.</p>+<p>Indented <a href="/url">once</a>.</p>+<p>Indented <a href="/url">twice</a>.</p>+<p>Indented <a href="/url">thrice</a>.</p>+<p>This should [not][] be a link.</p>+<pre><code>[not]: /url</code></pre>+<p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p>+<p>Foo <a href="/url/" title="Title with "quote" inside">biz</a>.</p>+<h2 id="with-ampersands">With ampersands</h2>+<p>Here’s a <a href="http://example.com/?foo=1&bar=2">link with an ampersand in the URL</a>.</p>+<p>Here’s a link with an amersand in the link text: <a href="http://att.com/" title="AT&T">AT&T</a>.</p>+<p>Here’s an <a href="/script?foo=1&bar=2">inline link</a>.</p>+<p>Here’s an <a href="/script?foo=1&bar=2">inline link in pointy braces</a>.</p>+<h2 id="autolinks">Autolinks</h2>+<p>With an ampersand: <a href="http://example.com/?foo=1&bar=2" class="uri">http://example.com/?foo=1&bar=2</a></p>+<ul>+<li>In a list?</li>+<li><a href="http://example.com/" class="uri">http://example.com/</a></li>+<li>It should.</li>+</ul>+<p>An e-mail address: <script type="text/javascript">+<!--+h='nowhere.net';a='@';n='nobody';e=n+a+h;+document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'" clas'+'s="em' + 'ail">'+e+'<\/'+'a'+'>');+// -->+</script><noscript>nobody at nowhere dot net</noscript></p>+<blockquote>+<p>Blockquoted: <a href="http://example.com/" class="uri">http://example.com/</a></p>+</blockquote>+<p>Auto-links should not occur here: <code><http://example.com/></code></p>+<pre><code>or here: <http://example.com/></code></pre>+<hr />+<h1 id="images">Images</h1>+<p>From “Voyage dans la Lune” by Georges Melies (1902):</p>+<figure class="scholmd-float scholmd-figure">+<div class="scholmd-float-content"><figure class="scholmd-subfig" style="display: inline-block; width: ">+<img src="lalune.jpg" title="Voyage dans la Lune" />+</figure></div>+<div class="scholmd-float-caption"><figcaption><span class="scholmd-caption-text">lalune</span></figcaption></div>+</figure>+<p>Here is a movie <img src="movie.jpg" alt="movie" /> icon.</p>+<hr />+<h1 id="footnotes">Footnotes</h1>+<p>Here is a footnote reference,<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a> and another.<a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a> This should <em>not</em> be a footnote reference, because it contains a space.[^my note] Here is an inline note.<a href="#fn3" class="footnoteRef" id="fnref3"><sup>3</sup></a></p>+<blockquote>+<p>Notes can go in quotes.<a href="#fn4" class="footnoteRef" id="fnref4"><sup>4</sup></a></p>+</blockquote>+<ol style="list-style-type: decimal">+<li>And in list items.<a href="#fn5" class="footnoteRef" id="fnref5"><sup>5</sup></a></li>+</ol>+<p>This paragraph should not be part of the note, as it is not indented.</p>+<div class="footnotes">+<hr />+<ol>+<li id="fn1"><p>Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.<a href="#fnref1">↩</a></p></li>+<li id="fn2"><p>Here’s the long note. This one contains multiple blocks.</p>+<p>Subsequent blocks are indented to show that they belong to the footnote (as with list items).</p>+<pre><code> { <code> }</code></pre>+<p>If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.<a href="#fnref2">↩</a></p></li>+<li id="fn3"><p>This is <em>easier</em> to type. Inline notes may contain <a href="http://google.com">links</a> and <code>]</code> verbatim characters, as well as [bracketed text].<a href="#fnref3">↩</a></p></li>+<li id="fn4"><p>In quote.<a href="#fnref4">↩</a></p></li>+<li id="fn5"><p>In list.<a href="#fnref5">↩</a></p></li>+</ol>+</div>+</body>+</html>
@@ -0,0 +1,963 @@+\documentclass[]{article}+\usepackage{lmodern}+\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}+\else % if luatex or xelatex+ \ifxetex+ \usepackage{mathspec}+ \usepackage{xltxtra,xunicode}+ \else+ \usepackage{fontspec}+ \fi+ \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}+ \newcommand{\euro}{€}+\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+}{}+\usepackage{fancyvrb}+\VerbatimFootnotes+\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}+\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={John MacFarlane; Anonymous},+ pdftitle={Pandoc Test Suite},+ colorlinks=true,+ citecolor=blue,+ urlcolor=blue,+ linkcolor=magenta,+ pdfborder={0 0 0}}+\urlstyle{same} % don't use monospace font for urls+\usepackage[normalem]{ulem}+% avoid problems with \sout in headers with hyperref:+\pdfstringdefDisableCommands{\renewcommand{\sout}{}}+\setlength{\parindent}{0pt}+\setlength{\parskip}{6pt plus 2pt minus 1pt}+\setlength{\emergencystretch}{3em} % prevent overfull lines+\setcounter{secnumdepth}{0}+\VerbatimFootnotes % allows verbatim text in footnotes++\title{Pandoc Test Suite}+\author{John MacFarlane \and Anonymous}+\date{July 17, 2006}++\begin{document}+\maketitle++This is a set of tests for pandoc. Most of them are adapted from John Gruber's+markdown test suite.++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Headers}\label{headers}++\subsection{Level 2 with an \href{/url}{embedded+link}}\label{level-2-with-an-embedded-link}++\subsubsection{Level 3 with \emph{emphasis}}\label{level-3-with-emphasis}++\paragraph{Level 4}\label{level-4}++\subparagraph{Level 5}\label{level-5}++\section{Level 1}\label{level-1}++\subsection{Level 2 with \emph{emphasis}}\label{level-2-with-emphasis}++\subsubsection{Level 3}\label{level-3}++with no blank line++\subsection{Level 2}\label{level-2}++with no blank line++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Paragraphs}\label{paragraphs}++Here's a regular paragraph.++In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item.+Because a hard-wrapped line in the middle of a paragraph looked like a list+item.++Here's one with a bullet. * criminey.++There should be a hard line break\\here.++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Block Quotes}\label{block-quotes}++E-mail style:++\begin{quote}+This is a block quote. It is pretty short.+\end{quote}++\begin{quote}+Code in a block quote:++\begin{verbatim}+sub status {+ print "working";+}+\end{verbatim}++A list:++\begin{enumerate}+\def\labelenumi{\arabic{enumi}.}+\itemsep1pt\parskip0pt\parsep0pt+\item+ item one+\item+ item two+\end{enumerate}++Nested block quotes:++\begin{quote}+nested+\end{quote}++\begin{quote}+nested+\end{quote}+\end{quote}++This should not be a block quote: 2 \textgreater{} 1.++And a following paragraph.++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Code Blocks}\label{code-blocks}++Code:++\begin{verbatim}+---- (should be four hyphens)++sub status {+ print "working";+}++this code block is indented by one tab+\end{verbatim}++And:++\begin{verbatim}+ this code block is indented by two tabs++These should not be escaped: \$ \\ \> \[ \{+\end{verbatim}++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Lists}\label{lists}++\subsection{Unordered}\label{unordered}++Asterisks tight:++\begin{itemize}+\itemsep1pt\parskip0pt\parsep0pt+\item+ asterisk 1+\item+ asterisk 2+\item+ asterisk 3+\end{itemize}++Asterisks loose:++\begin{itemize}+\item+ asterisk 1+\item+ asterisk 2+\item+ asterisk 3+\end{itemize}++Pluses tight:++\begin{itemize}+\itemsep1pt\parskip0pt\parsep0pt+\item+ Plus 1+\item+ Plus 2+\item+ Plus 3+\end{itemize}++Pluses loose:++\begin{itemize}+\item+ Plus 1+\item+ Plus 2+\item+ Plus 3+\end{itemize}++Minuses tight:++\begin{itemize}+\itemsep1pt\parskip0pt\parsep0pt+\item+ Minus 1+\item+ Minus 2+\item+ Minus 3+\end{itemize}++Minuses loose:++\begin{itemize}+\item+ Minus 1+\item+ Minus 2+\item+ Minus 3+\end{itemize}++\subsection{Ordered}\label{ordered}++Tight:++\begin{enumerate}+\def\labelenumi{\arabic{enumi}.}+\itemsep1pt\parskip0pt\parsep0pt+\item+ First+\item+ Second+\item+ Third+\end{enumerate}++and:++\begin{enumerate}+\def\labelenumi{\arabic{enumi}.}+\itemsep1pt\parskip0pt\parsep0pt+\item+ One+\item+ Two+\item+ Three+\end{enumerate}++Loose using tabs:++\begin{enumerate}+\def\labelenumi{\arabic{enumi}.}+\item+ First+\item+ Second+\item+ Third+\end{enumerate}++and using spaces:++\begin{enumerate}+\def\labelenumi{\arabic{enumi}.}+\item+ One+\item+ Two+\item+ Three+\end{enumerate}++Multiple paragraphs:++\begin{enumerate}+\def\labelenumi{\arabic{enumi}.}+\item+ Item 1, graf one.++ Item 1. graf two. The quick brown fox jumped over the lazy dog's back.+\item+ Item 2.+\item+ Item 3.+\end{enumerate}++\subsection{Nested}\label{nested}++\begin{itemize}+\itemsep1pt\parskip0pt\parsep0pt+\item+ Tab++ \begin{itemize}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ Tab++ \begin{itemize}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ Tab+ \end{itemize}+ \end{itemize}+\end{itemize}++Here's another:++\begin{enumerate}+\def\labelenumi{\arabic{enumi}.}+\itemsep1pt\parskip0pt\parsep0pt+\item+ First+\item+ Second:++ \begin{itemize}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ Fee+ \item+ Fie+ \item+ Foe+ \end{itemize}+\item+ Third+\end{enumerate}++Same thing but with paragraphs:++\begin{enumerate}+\def\labelenumi{\arabic{enumi}.}+\item+ First+\item+ Second:++ \begin{itemize}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ Fee+ \item+ Fie+ \item+ Foe+ \end{itemize}+\item+ Third+\end{enumerate}++\subsection{Tabs and spaces}\label{tabs-and-spaces}++\begin{itemize}+\item+ this is a list item indented with tabs+\item+ this is a list item indented with spaces++ \begin{itemize}+ \item+ this is an example list item indented with tabs+ \item+ this is an example list item indented with spaces+ \end{itemize}+\end{itemize}++\subsection{Fancy list markers}\label{fancy-list-markers}++\begin{enumerate}+\def\labelenumi{(\arabic{enumi})}+\setcounter{enumi}{1}+\item+ begins with 2+\item+ and now 3++ with a continuation++ \begin{enumerate}+ \def\labelenumii{\roman{enumii}.}+ \setcounter{enumii}{3}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ sublist with roman numerals, starting with 4+ \item+ more items++ \begin{enumerate}+ \def\labelenumiii{(\Alph{enumiii})}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ a subsublist+ \item+ a subsublist+ \end{enumerate}+ \end{enumerate}+\end{enumerate}++Nesting:++\begin{enumerate}+\def\labelenumi{\Alph{enumi}.}+\itemsep1pt\parskip0pt\parsep0pt+\item+ Upper Alpha++ \begin{enumerate}+ \def\labelenumii{\Roman{enumii}.}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ Upper Roman.++ \begin{enumerate}+ \def\labelenumiii{(\arabic{enumiii})}+ \setcounter{enumiii}{5}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ Decimal start with 6++ \begin{enumerate}+ \def\labelenumiv{\alph{enumiv})}+ \setcounter{enumiv}{2}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ Lower alpha with paren+ \end{enumerate}+ \end{enumerate}+ \end{enumerate}+\end{enumerate}++Autonumbering:++\begin{enumerate}+\itemsep1pt\parskip0pt\parsep0pt+\item+ Autonumber.+\item+ More.++ \begin{enumerate}+ \itemsep1pt\parskip0pt\parsep0pt+ \item+ Nested.+ \end{enumerate}+\end{enumerate}++Should not be a list item:++M.A.~2007++B. Williams++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Definition Lists}\label{definition-lists}++Tight using spaces:++\begin{description}+\itemsep1pt\parskip0pt\parsep0pt+\item[apple]+red fruit+\item[orange]+orange fruit+\item[banana]+yellow fruit+\end{description}++Tight using tabs:++\begin{description}+\itemsep1pt\parskip0pt\parsep0pt+\item[apple]+red fruit+\item[orange]+orange fruit+\item[banana]+yellow fruit+\end{description}++Loose:++\begin{description}+\item[apple]+red fruit+\item[orange]+orange fruit+\item[banana]+yellow fruit+\end{description}++Multiple blocks with italics:++\begin{description}+\item[\emph{apple}]+red fruit++contains seeds, crisp, pleasant to taste+\item[\emph{orange}]+orange fruit++\begin{verbatim}+{ orange code block }+\end{verbatim}++\begin{quote}+orange block quote+\end{quote}+\end{description}++Multiple definitions, tight:++\begin{description}+\itemsep1pt\parskip0pt\parsep0pt+\item[apple]+red fruit++computer+\item[orange]+orange fruit++bank+\end{description}++Multiple definitions, loose:++\begin{description}+\item[apple]+red fruit++computer+\item[orange]+orange fruit++bank+\end{description}++Blank line after term, indented marker, alternate markers:++\begin{description}+\item[apple]+red fruit++computer+\item[orange]+orange fruit++\begin{enumerate}+\def\labelenumi{\arabic{enumi}.}+\itemsep1pt\parskip0pt\parsep0pt+\item+ sublist+\item+ sublist+\end{enumerate}+\end{description}++\section{HTML Blocks}\label{html-blocks}++Simple block on one line:++foo++And nested without indentation:++foo++bar++Interpreted markdown in a table:++This is \emph{emphasized}++And this is \textbf{strong}++Here's a simple block:++foo++This should be a code block, though:++\begin{verbatim}+<div>+ foo+</div>+\end{verbatim}++As should this:++\begin{verbatim}+<div>foo</div>+\end{verbatim}++Now, nested:++foo++This should just be an HTML comment:++Multiline:++Code block:++\begin{verbatim}+<!-- Comment -->+\end{verbatim}++Just plain comment, with trailing spaces on the line:++Code:++\begin{verbatim}+<hr />+\end{verbatim}++Hr's:++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Inline Markup}\label{inline-markup}++This is \emph{emphasized}, and so \emph{is this}.++This is \textbf{strong}, and so \textbf{is this}.++An \emph{\href{/url}{emphasized link}}.++\textbf{\emph{This is strong and em.}}++So is \textbf{\emph{this}} word.++\textbf{\emph{This is strong and em.}}++So is \textbf{\emph{this}} word.++This is code: \texttt{\textgreater{}}, \texttt{\$}, \texttt{\textbackslash{}},+\texttt{\textbackslash{}\$}, \texttt{\textless{}html\textgreater{}}.++\sout{This is \emph{strikeout}.}++Superscripts: a\textsuperscript{bc}d a\textsuperscript{\emph{hello}}+a\textsuperscript{hello~there}.++Subscripts: H\textsubscript{2}O, H\textsubscript{23}O,+H\textsubscript{many~of~them}O.++These should not be superscripts or subscripts, because of the unescaped+spaces: a\^{}b c\^{}d, a\textasciitilde{}b c\textasciitilde{}d.++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Smart quotes, ellipses, dashes}\label{smart-quotes-ellipses-dashes}++``Hello,'' said the spider. ``\,`Shelob' is my name.''++`A', `B', and `C' are letters.++`Oak,' `elm,' and `beech' are names of trees. So is `pine.'++`He said, ``I want to go.''\,' Were you alive in the 70's?++Here is some quoted `\texttt{code}' and a+``\href{http://example.com/?foo=1\&bar=2}{quoted link}''.++Some dashes: one---two --- three---four --- five.++Dashes between numbers: 5--7, 255--66, 1987--1999.++Ellipses\ldots{}and\ldots{}and\ldots{}.++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{LaTeX}\label{latex}++\begin{itemize}+\itemsep1pt\parskip0pt\parsep0pt+\item+ \cite[22-23]{smith.1899}+\item+ $2+2=4$+\item+ $x \in y$+\item+ $\alpha \wedge \omega$+\item+ $223$+\item+ $p$-Tree+\item+ Here's some display math:+ %+ \begin{equation*}+ \frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}+ \end{equation*}+ %+\item+ Here's one that has a line break in it: $\alpha + \omega \times x^2$.+\end{itemize}++These shouldn't be math:++\begin{itemize}+\itemsep1pt\parskip0pt\parsep0pt+\item+ To get the famous equation, write \texttt{\$e = mc\^{}2\$}.+\item+ \$22,000 is a \emph{lot} of money. So is \$34,000. (It worked if ``lot'' is+ emphasized.)+\item+ Shoes (\$20) and socks (\$5).+\item+ Escaped \texttt{\$}: \$73 \emph{this should be emphasized} 23\$.+\end{itemize}++Here's a LaTeX table:++\begin{tabular}{|l|l|}\hline+Animal & Number \\ \hline+Dog & 2 \\+Cat & 1 \\ \hline+\end{tabular}++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Special Characters}\label{special-characters}++Here is some unicode:++\begin{itemize}+\itemsep1pt\parskip0pt\parsep0pt+\item+ I hat: Î+\item+ o umlaut: ö+\item+ section: §+\item+ set membership: ∈+\item+ copyright: ©+\end{itemize}++AT\&T has an ampersand in their name.++AT\&T is another way to write it.++This \& that.++4 \textless{} 5.++6 \textgreater{} 5.++Backslash: \textbackslash{}++Backtick: `++Asterisk: *++Underscore: \_++Left brace: \{++Right brace: \}++Left bracket: {[}++Right bracket: {]}++Left paren: (++Right paren: )++Greater-than: \textgreater{}++Hash: \#++Period: .++Bang: !++Plus: +++Minus: -++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Links}\label{links}++\subsection{Explicit}\label{explicit}++Just a \href{/url/}{URL}.++\href{/url/}{URL and title}.++\href{/url/}{URL and title}.++\href{/url/}{URL and title}.++\href{/url/}{URL and title}++\href{/url/}{URL and title}++\href{/url/with_underscore}{with\_underscore}++\href{mailto:nobody@nowhere.net}{Email link}++\href{}{Empty}.++\subsection{Reference}\label{reference}++Foo \href{/url/}{bar}.++Foo \href{/url/}{bar}.++Foo \href{/url/}{bar}.++With \href{/url/}{embedded {[}brackets{]}}.++\href{/url/}{b} by itself should be a link.++Indented \href{/url}{once}.++Indented \href{/url}{twice}.++Indented \href{/url}{thrice}.++This should {[}not{]}{[}{]} be a link.++\begin{verbatim}+[not]: /url+\end{verbatim}++Foo \href{/url/}{bar}.++Foo \href{/url/}{biz}.++\subsection{With ampersands}\label{with-ampersands}++Here's a \href{http://example.com/?foo=1\&bar=2}{link with an ampersand in the+URL}.++Here's a link with an amersand in the link text:+\href{http://att.com/}{AT\&T}.++Here's an \href{/script?foo=1\&bar=2}{inline link}.++Here's an \href{/script?foo=1\&bar=2}{inline link in pointy braces}.++\subsection{Autolinks}\label{autolinks}++With an ampersand: \url{http://example.com/?foo=1\&bar=2}++\begin{itemize}+\itemsep1pt\parskip0pt\parsep0pt+\item+ In a list?+\item+ \url{http://example.com/}+\item+ It should.+\end{itemize}++An e-mail address:+\href{mailto:nobody@nowhere.net}{\nolinkurl{nobody@nowhere.net}}++\begin{quote}+Blockquoted: \url{http://example.com/}+\end{quote}++Auto-links should not occur here:+\texttt{\textless{}http://example.com/\textgreater{}}++\begin{verbatim}+or here: <http://example.com/>+\end{verbatim}++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Images}\label{images}++From ``Voyage dans la Lune'' by Georges Melies (1902):++\begin{figure}+\centering+\includegraphics[]{lalune.jpg}+\caption*{lalune}+\end{figure}++Here is a movie \includegraphics[]{movie.jpg} icon.++\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}++\section{Footnotes}\label{footnotes}++Here is a footnote reference,\footnote{Here is the footnote. It can go+ anywhere after the footnote reference. It need not be placed at the end of+ the document.} and another.\footnote{Here's the long note. This one contains+ multiple blocks.++ Subsequent blocks are indented to show that they belong to the footnote (as+ with list items).++\begin{Verbatim}+ { <code> }+\end{Verbatim}++ If you want, you can indent every line, but you can also be lazy and just+ indent the first line of each block.} This should \emph{not} be a footnote+reference, because it contains a space.{[}\^{}my note{]} Here is an inline+note.\footnote{This is \emph{easier} to type. Inline notes may contain+ \href{http://google.com}{links} and \texttt{{]}} verbatim characters, as+ well as {[}bracketed text{]}.}++\begin{quote}+Notes can go in quotes.\footnote{In quote.}+\end{quote}++\begin{enumerate}+\def\labelenumi{\arabic{enumi}.}+\itemsep1pt\parskip0pt\parsep0pt+\item+ And in list items.\footnote{In list.}+\end{enumerate}++This paragraph should not be part of the note, as it is not indented.++\end{document}
@@ -0,0 +1,794 @@+.TH "Pandoc Test Suite" "" "July 17, 2006" "" ""+.PP+This is a set of tests for pandoc.+Most of them are adapted from John Gruber's markdown test suite.+.PP+ * * * * *+.SH Headers+.SS Level 2 with an embedded link (/url)+.SS Level 3 with \f[I]emphasis\f[]+.SS Level 4+.SS Level 5+.SH Level 1+.SS Level 2 with \f[I]emphasis\f[]+.SS Level 3+.PP+with no blank line+.SS Level 2+.PP+with no blank line+.PP+ * * * * *+.SH Paragraphs+.PP+Here's a regular paragraph.+.PP+In Markdown 1.0.0 and earlier.+Version 8.+This line turns into a list item.+Because a hard\-wrapped line in the middle of a paragraph looked like a list+item.+.PP+Here's one with a bullet.+* criminey.+.PP+There should be a hard line break+.PD 0+.P+.PD+here.+.PP+ * * * * *+.SH Block Quotes+.PP+E\-mail style:+.RS+.PP+This is a block quote.+It is pretty short.+.RE+.RS+.PP+Code in a block quote:+.IP+.nf+\f[C]+sub\ status\ {+\ \ \ \ print\ "working";+}+\f[]+.fi+.PP+A list:+.IP "1." 3+item one+.IP "2." 3+item two+.PP+Nested block quotes:+.RS+.PP+nested+.RE+.RS+.PP+nested+.RE+.RE+.PP+This should not be a block quote: 2 > 1.+.PP+And a following paragraph.+.PP+ * * * * *+.SH Code Blocks+.PP+Code:+.IP+.nf+\f[C]+\-\-\-\-\ (should\ be\ four\ hyphens)++sub\ status\ {+\ \ \ \ print\ "working";+}++this\ code\ block\ is\ indented\ by\ one\ tab+\f[]+.fi+.PP+And:+.IP+.nf+\f[C]+\ \ \ \ this\ code\ block\ is\ indented\ by\ two\ tabs++These\ should\ not\ be\ escaped:\ \ \\$\ \\\\\ \\>\ \\[\ \\{+\f[]+.fi+.PP+ * * * * *+.SH Lists+.SS Unordered+.PP+Asterisks tight:+.IP \[bu] 2+asterisk 1+.IP \[bu] 2+asterisk 2+.IP \[bu] 2+asterisk 3+.PP+Asterisks loose:+.IP \[bu] 2+asterisk 1+.IP \[bu] 2+asterisk 2+.IP \[bu] 2+asterisk 3+.PP+Pluses tight:+.IP \[bu] 2+Plus 1+.IP \[bu] 2+Plus 2+.IP \[bu] 2+Plus 3+.PP+Pluses loose:+.IP \[bu] 2+Plus 1+.IP \[bu] 2+Plus 2+.IP \[bu] 2+Plus 3+.PP+Minuses tight:+.IP \[bu] 2+Minus 1+.IP \[bu] 2+Minus 2+.IP \[bu] 2+Minus 3+.PP+Minuses loose:+.IP \[bu] 2+Minus 1+.IP \[bu] 2+Minus 2+.IP \[bu] 2+Minus 3+.SS Ordered+.PP+Tight:+.IP "1." 3+First+.IP "2." 3+Second+.IP "3." 3+Third+.PP+and:+.IP "1." 3+One+.IP "2." 3+Two+.IP "3." 3+Three+.PP+Loose using tabs:+.IP "1." 3+First+.IP "2." 3+Second+.IP "3." 3+Third+.PP+and using spaces:+.IP "1." 3+One+.IP "2." 3+Two+.IP "3." 3+Three+.PP+Multiple paragraphs:+.IP "1." 3+Item 1, graf one.+.RS 4+.PP+Item 1.+graf two.+The quick brown fox jumped over the lazy dog's back.+.RE+.IP "2." 3+Item 2.+.IP "3." 3+Item 3.+.SS Nested+.IP \[bu] 2+Tab+.RS 2+.IP \[bu] 2+Tab+.RS 2+.IP \[bu] 2+Tab+.RE+.RE+.PP+Here's another:+.IP "1." 3+First+.IP "2." 3+Second:+.RS 4+.IP \[bu] 2+Fee+.IP \[bu] 2+Fie+.IP \[bu] 2+Foe+.RE+.IP "3." 3+Third+.PP+Same thing but with paragraphs:+.IP "1." 3+First+.IP "2." 3+Second:+.RS 4+.IP \[bu] 2+Fee+.IP \[bu] 2+Fie+.IP \[bu] 2+Foe+.RE+.IP "3." 3+Third+.SS Tabs and spaces+.IP \[bu] 2+this is a list item indented with tabs+.IP \[bu] 2+this is a list item indented with spaces+.RS 2+.IP \[bu] 2+this is an example list item indented with tabs+.IP \[bu] 2+this is an example list item indented with spaces+.RE+.SS Fancy list markers+.IP "(2)" 4+begins with 2+.IP "(3)" 4+and now 3+.RS 4+.PP+with a continuation+.IP "iv." 4+sublist with roman numerals, starting with 4+.IP " v." 4+more items+.RS 4+.IP "(A)" 4+a subsublist+.IP "(B)" 4+a subsublist+.RE+.RE+.PP+Nesting:+.IP "A." 3+Upper Alpha+.RS 4+.IP "I." 3+Upper Roman.+.RS 4+.IP "(6)" 4+Decimal start with 6+.RS 4+.IP "c)" 3+Lower alpha with paren+.RE+.RE+.RE+.PP+Autonumbering:+.IP "1." 3+Autonumber.+.IP "2." 3+More.+.RS 4+.IP "1." 3+Nested.+.RE+.PP+Should not be a list item:+.PP+M.A.\ 2007+.PP+B.+Williams+.PP+ * * * * *+.SH Definition Lists+.PP+Tight using spaces:+.TP+.B apple+red fruit+.RS+.RE+.TP+.B orange+orange fruit+.RS+.RE+.TP+.B banana+yellow fruit+.RS+.RE+.PP+Tight using tabs:+.TP+.B apple+red fruit+.RS+.RE+.TP+.B orange+orange fruit+.RS+.RE+.TP+.B banana+yellow fruit+.RS+.RE+.PP+Loose:+.TP+.B apple+red fruit+.RS+.RE+.TP+.B orange+orange fruit+.RS+.RE+.TP+.B banana+yellow fruit+.RS+.RE+.PP+Multiple blocks with italics:+.TP+.B \f[I]apple\f[]+red fruit+.RS+.PP+contains seeds, crisp, pleasant to taste+.RE+.TP+.B \f[I]orange\f[]+orange fruit+.RS+.IP+.nf+\f[C]+{\ orange\ code\ block\ }+\f[]+.fi+.RS+.PP+orange block quote+.RE+.RE+.PP+Multiple definitions, tight:+.TP+.B apple+red fruit+.RS+.RE+computer+.RS+.RE+.TP+.B orange+orange fruit+.RS+.RE+bank+.RS+.RE+.PP+Multiple definitions, loose:+.TP+.B apple+red fruit+.RS+.RE+computer+.RS+.RE+.TP+.B orange+orange fruit+.RS+.RE+bank+.RS+.RE+.PP+Blank line after term, indented marker, alternate markers:+.TP+.B apple+red fruit+.RS+.RE+computer+.RS+.RE+.TP+.B orange+orange fruit+.RS+.IP "1." 3+sublist+.IP "2." 3+sublist+.RE+.SH HTML Blocks+.PP+Simple block on one line:+foo+.PP+And nested without indentation:+.PP+foo+bar+.PP+Interpreted markdown in a table:+This is \f[I]emphasized\f[]+And this is \f[B]strong\f[]+.PP+Here's a simple block:+.PP+foo+.PP+This should be a code block, though:+.IP+.nf+\f[C]+<div>+\ \ \ \ foo+</div>+\f[]+.fi+.PP+As should this:+.IP+.nf+\f[C]+<div>foo</div>+\f[]+.fi+.PP+Now, nested:+foo+.PP+This should just be an HTML comment:+.PP+Multiline:+.PP+Code block:+.IP+.nf+\f[C]+<!\-\-\ Comment\ \-\->+\f[]+.fi+.PP+Just plain comment, with trailing spaces on the line:+.PP+Code:+.IP+.nf+\f[C]+<hr\ />+\f[]+.fi+.PP+Hr's:+.PP+ * * * * *+.SH Inline Markup+.PP+This is \f[I]emphasized\f[], and so \f[I]is this\f[].+.PP+This is \f[B]strong\f[], and so \f[B]is this\f[].+.PP+An \f[I]emphasized link (/url)\f[].+.PP+\f[B]\f[I]This is strong and em.\f[]\f[]+.PP+So is \f[B]\f[I]this\f[]\f[] word.+.PP+\f[B]\f[I]This is strong and em.\f[]\f[]+.PP+So is \f[B]\f[I]this\f[]\f[] word.+.PP+This is code: \f[C]>\f[], \f[C]$\f[], \f[C]\\\f[], \f[C]\\$\f[],+\f[C]<html>\f[].+.PP+[STRIKEOUT:This is \f[I]strikeout\f[].]+.PP+Superscripts: a^bc^d a^\f[I]hello\f[]^ a^hello\ there^.+.PP+Subscripts: H~2~O, H~23~O, H~many\ of\ them~O.+.PP+These should not be superscripts or subscripts, because of the unescaped+spaces: a^b c^d, a~b c~d.+.PP+ * * * * *+.SH Smart quotes, ellipses, dashes+.PP+\[lq]Hello,\[rq] said the spider.+\[lq]`Shelob' is my name.\[rq]+.PP+`A', `B', and `C' are letters.+.PP+`Oak,' `elm,' and `beech' are names of trees.+So is `pine.'+.PP+`He said, \[lq]I want to go.\[rq]' Were you alive in the 70's?+.PP+Here is some quoted `\f[C]code\f[]' and a \[lq]quoted+link (http://example.com/?foo=1&bar=2)\[rq].+.PP+Some dashes: one\[em]two \[em] three\[em]four \[em] five.+.PP+Dashes between numbers: 5\[en]7, 255\[en]66, 1987\[en]1999.+.PP+Ellipses\&...and\&...and\&....+.PP+ * * * * *+.SH LaTeX+.IP \[bu] 2+.IP \[bu] 2+2 + 2 = 4+.IP \[bu] 2+\f[I]x\f[] ∈ \f[I]y\f[]+.IP \[bu] 2+\f[I]α\f[] ∧ \f[I]ω\f[]+.IP \[bu] 2+223+.IP \[bu] 2+\f[I]p\f[]\-Tree+.IP \[bu] 2+Here's some display math:+.RS+$$\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)\-f(x)}{h}$$+.RE+.IP \[bu] 2+Here's one that has a line break in it:+\f[I]α\f[] + \f[I]ω\f[] × \f[I]x\f[]^2^.+.PP+These shouldn't be math:+.IP \[bu] 2+To get the famous equation, write \f[C]$e\ =\ mc^2$\f[].+.IP \[bu] 2+$22,000 is a \f[I]lot\f[] of money.+So is $34,000.+(It worked if \[lq]lot\[rq] is emphasized.)+.IP \[bu] 2+Shoes ($20) and socks ($5).+.IP \[bu] 2+Escaped \f[C]$\f[]: $73 \f[I]this should be emphasized\f[] 23$.+.PP+Here's a LaTeX table:+.PP+ * * * * *+.SH Special Characters+.PP+Here is some unicode:+.IP \[bu] 2+I hat: Î+.IP \[bu] 2+o umlaut: ö+.IP \[bu] 2+section: §+.IP \[bu] 2+set membership: ∈+.IP \[bu] 2+copyright: ©+.PP+AT&T has an ampersand in their name.+.PP+AT&T is another way to write it.+.PP+This & that.+.PP+4 < 5.+.PP+6 > 5.+.PP+Backslash: \\+.PP+Backtick: `+.PP+Asterisk: *+.PP+Underscore: _+.PP+Left brace: {+.PP+Right brace: }+.PP+Left bracket: [+.PP+Right bracket: ]+.PP+Left paren: (+.PP+Right paren: )+.PP+Greater\-than: >+.PP+Hash: #+.PP+Period: .+.PP+Bang: !+.PP+Plus: ++.PP+Minus: \-+.PP+ * * * * *+.SH Links+.SS Explicit+.PP+Just a URL (/url/).+.PP+URL and title (/url/).+.PP+URL and title (/url/).+.PP+URL and title (/url/).+.PP+URL and title (/url/)+.PP+URL and title (/url/)+.PP+with_underscore (/url/with_underscore)+.PP+Email link (mailto:nobody@nowhere.net)+.PP+Empty ().+.SS Reference+.PP+Foo bar (/url/).+.PP+Foo bar (/url/).+.PP+Foo bar (/url/).+.PP+With embedded [brackets] (/url/).+.PP+b (/url/) by itself should be a link.+.PP+Indented once (/url).+.PP+Indented twice (/url).+.PP+Indented thrice (/url).+.PP+This should [not][] be a link.+.IP+.nf+\f[C]+[not]:\ /url+\f[]+.fi+.PP+Foo bar (/url/).+.PP+Foo biz (/url/).+.SS With ampersands+.PP+Here's a link with an ampersand in the URL (http://example.com/?foo=1&bar=2).+.PP+Here's a link with an amersand in the link text: AT&T (http://att.com/).+.PP+Here's an inline link (/script?foo=1&bar=2).+.PP+Here's an inline link in pointy braces (/script?foo=1&bar=2).+.SS Autolinks+.PP+With an ampersand: <http://example.com/?foo=1&bar=2>+.IP \[bu] 2+In a list?+.IP \[bu] 2+<http://example.com/>+.IP \[bu] 2+It should.+.PP+An e\-mail address: <nobody@nowhere.net>+.RS+.PP+Blockquoted: <http://example.com/>+.RE+.PP+Auto\-links should not occur here: \f[C]<http://example.com/>\f[]+.IP+.nf+\f[C]+or\ here:\ <http://example.com/>+\f[]+.fi+.PP+ * * * * *+.SH Images+.PP+From \[lq]Voyage dans la Lune\[rq] by Georges Melies (1902):+.PP+[IMAGE: lalune (lalune.jpg)]+.PP+Here is a movie [IMAGE: movie (movie.jpg)] icon.+.PP+ * * * * *+.SH Footnotes+.PP+Here is a footnote reference,[1] and another.[2] This should \f[I]not\f[] be a+footnote reference, because it contains a space.[^my note] Here is an inline+note.[3]+.RS+.PP+Notes can go in quotes.[4]+.RE+.IP "1." 3+And in list items.[5]+.PP+This paragraph should not be part of the note, as it is not indented.+.SH NOTES+.SS [1]+.PP+Here is the footnote.+It can go anywhere after the footnote reference.+It need not be placed at the end of the document.+.SS [2]+.PP+Here's the long note.+This one contains multiple blocks.+.PP+Subsequent blocks are indented to show that they belong to the footnote (as+with list items).+.IP+.nf+\f[C]+\ \ {\ <code>\ }+\f[]+.fi+.PP+If you want, you can indent every line, but you can also be lazy and just+indent the first line of each block.+.SS [3]+.PP+This is \f[I]easier\f[] to type.+Inline notes may contain links (http://google.com) and \f[C]]\f[] verbatim+characters, as well as [bracketed text].+.SS [4]+.PP+In quote.+.SS [5]+.PP+In list.+.SH AUTHORS+John MacFarlane; Anonymous.
@@ -0,0 +1,747 @@+---+author:+- John MacFarlane+- Anonymous+date: 'July 17, 2006'+title: Pandoc Test Suite+...++This is a set of tests for pandoc. Most of them are adapted from John Gruber’s+markdown test suite.++------------------------------------------------------------------------------++Headers+=======++Level 2 with an [embedded link](/url)+-------------------------------------++### Level 3 with *emphasis*++#### Level 4++##### Level 5++Level 1+=======++Level 2 with *emphasis*+-----------------------++### Level 3++with no blank line++Level 2+-------++with no blank line++------------------------------------------------------------------------------++Paragraphs+==========++Here’s a regular paragraph.++In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item.+Because a hard-wrapped line in the middle of a paragraph looked like a list+item.++Here’s one with a bullet. \* criminey.++There should be a hard line break\+here.++------------------------------------------------------------------------------++Block Quotes+============++E-mail style:++> This is a block quote. It is pretty short.++> Code in a block quote:+>+> sub status {+> print "working";+> }+>+> A list:+>+> 1. item one+> 2. item two+>+> Nested block quotes:+>+> > nested+>+> > nested++This should not be a block quote: 2 \> 1.++And a following paragraph.++------------------------------------------------------------------------------++Code Blocks+===========++Code:++ ---- (should be four hyphens)++ sub status {+ print "working";+ }++ this code block is indented by one tab++And:++ this code block is indented by two tabs++ These should not be escaped: \$ \\ \> \[ \{++------------------------------------------------------------------------------++Lists+=====++Unordered+---------++Asterisks tight:++- asterisk 1+- asterisk 2+- asterisk 3++Asterisks loose:++- asterisk 1++- asterisk 2++- asterisk 3++Pluses tight:++- Plus 1+- Plus 2+- Plus 3++Pluses loose:++- Plus 1++- Plus 2++- Plus 3++Minuses tight:++- Minus 1+- Minus 2+- Minus 3++Minuses loose:++- Minus 1++- Minus 2++- Minus 3++Ordered+-------++Tight:++1. First+2. Second+3. Third++and:++1. One+2. Two+3. Three++Loose using tabs:++1. First++2. Second++3. Third++and using spaces:++1. One++2. Two++3. Three++Multiple paragraphs:++1. Item 1, graf one.++ Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.++2. Item 2.++3. Item 3.++Nested+------++- Tab+ - Tab+ - Tab++Here’s another:++1. First+2. Second:+ - Fee+ - Fie+ - Foe++3. Third++Same thing but with paragraphs:++1. First++2. Second:++ - Fee+ - Fie+ - Foe++3. Third++Tabs and spaces+---------------++- this is a list item indented with tabs++- this is a list item indented with spaces++ - this is an example list item indented with tabs++ - this is an example list item indented with spaces++Fancy list markers+------------------++(2) begins with 2+(3) and now 3++ with a continuation++ iv. sublist with roman numerals, starting with 4+ v. more items+ (A) a subsublist+ (B) a subsublist++Nesting:++A. Upper Alpha+ I. Upper Roman.+ (6) Decimal start with 6+ c) Lower alpha with paren++Autonumbering:++1. Autonumber.+2. More.+ 1. Nested.++Should not be a list item:++M.A. 2007++B. Williams++------------------------------------------------------------------------------++Definition Lists+================++Tight using spaces:++apple+: red fruit++orange+: orange fruit++banana+: yellow fruit++Tight using tabs:++apple+: red fruit++orange+: orange fruit++banana+: yellow fruit++Loose:++apple++: red fruit++orange++: orange fruit++banana++: yellow fruit++Multiple blocks with italics:++*apple*++: red fruit++ contains seeds, crisp, pleasant to taste++*orange*++: orange fruit++ { orange code block }++ > orange block quote++Multiple definitions, tight:++apple+: red fruit+: computer++orange+: orange fruit+: bank++Multiple definitions, loose:++apple++: red fruit++: computer++orange++: orange fruit++: bank++Blank line after term, indented marker, alternate markers:++apple++: red fruit++: computer++orange++: orange fruit++ 1. sublist+ 2. sublist++HTML Blocks+===========++Simple block on one line:++<div>++foo++</div>++And nested without indentation:++<div>++<div>++<div>++foo++</div>++</div>++<div>++bar++</div>++</div>++Interpreted markdown in a table:++<table>+<tr>+<td>+This is *emphasized*+</td>+<td>+And this is **strong**+</td>+</tr>+</table>+<script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>+Here’s a simple block:++<div>++foo++</div>++This should be a code block, though:++ <div>+ foo+ </div>++As should this:++ <div>foo</div>++Now, nested:++<div>++<div>++<div>++foo++</div>++</div>++</div>++This should just be an HTML comment:++<!-- Comment -->+Multiline:++<!--+Blah+Blah+-->+<!--+ This is another comment.+-->+Code block:++ <!-- Comment -->++Just plain comment, with trailing spaces on the line:++<!-- foo -->+Code:++ <hr />++Hr’s:++<hr>+<hr />+<hr />+<hr>+<hr />+<hr />+<hr class="foo" id="bar" />+<hr class="foo" id="bar" />+<hr class="foo" id="bar">++------------------------------------------------------------------------------++Inline Markup+=============++This is *emphasized*, and so *is this*.++This is **strong**, and so **is this**.++An *[emphasized link](/url)*.++***This is strong and em.***++So is ***this*** word.++***This is strong and em.***++So is ***this*** word.++This is code: `>`, `$`, `\`, `\$`, `<html>`.++~~This is *strikeout*.~~++Superscripts: a^bc^d a^*hello*^ a^hello there^.++Subscripts: H~2~O, H~23~O, H~many of them~O.++These should not be superscripts or subscripts, because of the unescaped+spaces: a\^b c\^d, a\~b c\~d.++------------------------------------------------------------------------------++Smart quotes, ellipses, dashes+==============================++“Hello,” said the spider. “‘Shelob’ is my name.”++‘A’, ‘B’, and ‘C’ are letters.++‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’++‘He said, “I want to go.”’ Were you alive in the 70’s?++Here is some quoted ‘`code`’ and a “[quoted+link](http://example.com/?foo=1&bar=2)”.++Some dashes: one—two — three—four — five.++Dashes between numbers: 5–7, 255–66, 1987–1999.++Ellipses…and…and….++------------------------------------------------------------------------------++LaTeX+=====++- \cite[22-23]{smith.1899}+- $2+2=4$+- $x \in y$+- $\alpha \wedge \omega$+- $223$+- $p$-Tree+- Here’s some display math:+ $$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$+- Here’s one that has a line break in it: $\alpha + \omega \times x^2$.++These shouldn’t be math:++- To get the famous equation, write `$e = mc^2$`.+- \$22,000 is a *lot* of money. So is \$34,000. (It worked if “lot” is+ emphasized.)+- Shoes (\$20) and socks (\$5).+- Escaped `$`: \$73 *this should be emphasized* 23\$.++Here’s a LaTeX table:++\begin{tabular}{|l|l|}\hline+Animal & Number \\ \hline+Dog & 2 \\+Cat & 1 \\ \hline+\end{tabular}++------------------------------------------------------------------------------++Special Characters+==================++Here is some unicode:++- I hat: Î+- o umlaut: ö+- section: §+- set membership: ∈+- copyright: ©++AT&T has an ampersand in their name.++AT&T is another way to write it.++This & that.++4 \< 5.++6 \> 5.++Backslash: \\++Backtick: \`++Asterisk: \*++Underscore: \_++Left brace: {++Right brace: }++Left bracket: [++Right bracket: ]++Left paren: (++Right paren: )++Greater-than: \>++Hash: \#++Period: .++Bang: !++Plus: +++Minus: -++------------------------------------------------------------------------------++Links+=====++Explicit+--------++Just a [URL](/url/).++[URL and title](/url/ "title").++[URL and title](/url/ "title preceded by two spaces").++[URL and title](/url/ "title preceded by a tab").++[URL and title](/url/ "title with "quotes" in it")++[URL and title](/url/ "title with single quotes")++[with\_underscore](/url/with_underscore)++[Email link](mailto:nobody@nowhere.net)++[Empty]().++Reference+---------++Foo [bar](/url/).++Foo [bar](/url/).++Foo [bar](/url/).++With [embedded [brackets]](/url/).++[b](/url/) by itself should be a link.++Indented [once](/url).++Indented [twice](/url).++Indented [thrice](/url).++This should [not][] be a link.++ [not]: /url++Foo [bar](/url/ "Title with "quotes" inside").++Foo [biz](/url/ "Title with "quote" inside").++With ampersands+---------------++Here’s a [link with an ampersand in the URL](http://example.com/?foo=1&bar=2).++Here’s a link with an amersand in the link text:+[AT&T](http://att.com/ "AT&T").++Here’s an [inline link](/script?foo=1&bar=2).++Here’s an [inline link in pointy braces](/script?foo=1&bar=2).++Autolinks+---------++With an ampersand: <http://example.com/?foo=1&bar=2>++- In a list?+- <http://example.com/>+- It should.++An e-mail address: <nobody@nowhere.net>++> Blockquoted: <http://example.com/>++Auto-links should not occur here: `<http://example.com/>`++ or here: <http://example.com/>++------------------------------------------------------------------------------++Images+======++From “Voyage dans la Lune” by Georges Melies (1902):++++Here is a movie  icon.++------------------------------------------------------------------------------++Footnotes+=========++Here is a footnote reference,[^1] and another.[^2] This should *not* be a+footnote reference, because it contains a space.[\^my note] Here is an inline+note.[^3]++> Notes can go in quotes.[^4]++1. And in list items.[^5]++This paragraph should not be part of the note, as it is not indented.++[^1]: Here is the footnote. It can go anywhere after the footnote reference.+ It need not be placed at the end of the document.++[^2]: Here’s the long note. This one contains multiple blocks.++ Subsequent blocks are indented to show that they belong to the footnote+ (as with list items).++ { <code> }++ If you want, you can indent every line, but you can also be lazy and just+ indent the first line of each block.++[^3]: This is *easier* to type. Inline notes may contain+ [links](http://google.com) and `]` verbatim characters, as well as+ [bracketed text].++[^4]: In quote.++[^5]: In list.
@@ -0,0 +1,401 @@+Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "John",Space,Str "MacFarlane"],MetaInlines [Str "Anonymous"]]),("date",MetaInlines [Str "July",Space,Str "17,",Space,Str "2006"]),("title",MetaInlines [Str "Pandoc",Space,Str "Test",Space,Str "Suite"])]})+[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc.",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber\8217s",Space,Str "markdown",Space,Str "test",Space,Str "suite."]+,HorizontalRule+,Header 1 ("headers",[],[]) [Str "Headers"]+,Header 2 ("level-2-with-an-embedded-link",[],[]) [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embedded",Space,Str "link"] ("/url","")]+,Header 3 ("level-3-with-emphasis",[],[]) [Str "Level",Space,Str "3",Space,Str "with",Space,Emph [Str "emphasis"]]+,Header 4 ("level-4",[],[]) [Str "Level",Space,Str "4"]+,Header 5 ("level-5",[],[]) [Str "Level",Space,Str "5"]+,Header 1 ("level-1",[],[]) [Str "Level",Space,Str "1"]+,Header 2 ("level-2-with-emphasis",[],[]) [Str "Level",Space,Str "2",Space,Str "with",Space,Emph [Str "emphasis"]]+,Header 3 ("level-3",[],[]) [Str "Level",Space,Str "3"]+,Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]+,Header 2 ("level-2",[],[]) [Str "Level",Space,Str "2"]+,Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]+,HorizontalRule+,Header 1 ("paragraphs",[],[]) [Str "Paragraphs"]+,Para [Str "Here\8217s",Space,Str "a",Space,Str "regular",Space,Str "paragraph."]+,Para [Str "In",Space,Str "Markdown",Space,Str "1.0.0",Space,Str "and",Space,Str "earlier.",Space,Str "Version",Space,Str "8.",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item.",Space,Str "Because",Space,Str "a",Space,Str "hard-wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item."]+,Para [Str "Here\8217s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet.",Space,Str "*",Space,Str "criminey."]+,Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break",LineBreak,Str "here."]+,HorizontalRule+,Header 1 ("block-quotes",[],[]) [Str "Block",Space,Str "Quotes"]+,Para [Str "E-mail",Space,Str "style:"]+,BlockQuote+ [Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote.",Space,Str "It",Space,Str "is",Space,Str "pretty",Space,Str "short."]]+,BlockQuote+ [Para [Str "Code",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote:"]+ ,CodeBlock ("",[],[]) "sub status {\n print \"working\";\n}"+ ,Para [Str "A",Space,Str "list:"]+ ,OrderedList (1,Decimal,Period)+ [[Plain [Str "item",Space,Str "one"]]+ ,[Plain [Str "item",Space,Str "two"]]]+ ,Para [Str "Nested",Space,Str "block",Space,Str "quotes:"]+ ,BlockQuote+ [Para [Str "nested"]]+ ,BlockQuote+ [Para [Str "nested"]]]+,Para [Str "This",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "block",Space,Str "quote:",Space,Str "2",Space,Str ">",Space,Str "1."]+,Para [Str "And",Space,Str "a",Space,Str "following",Space,Str "paragraph."]+,HorizontalRule+,Header 1 ("code-blocks",[],[]) [Str "Code",Space,Str "Blocks"]+,Para [Str "Code:"]+,CodeBlock ("",[],[]) "---- (should be four hyphens)\n\nsub status {\n print \"working\";\n}\n\nthis code block is indented by one tab"+,Para [Str "And:"]+,CodeBlock ("",[],[]) " this code block is indented by two tabs\n\nThese should not be escaped: \\$ \\\\ \\> \\[ \\{"+,HorizontalRule+,Header 1 ("lists",[],[]) [Str "Lists"]+,Header 2 ("unordered",[],[]) [Str "Unordered"]+,Para [Str "Asterisks",Space,Str "tight:"]+,BulletList+ [[Plain [Str "asterisk",Space,Str "1"]]+ ,[Plain [Str "asterisk",Space,Str "2"]]+ ,[Plain [Str "asterisk",Space,Str "3"]]]+,Para [Str "Asterisks",Space,Str "loose:"]+,BulletList+ [[Para [Str "asterisk",Space,Str "1"]]+ ,[Para [Str "asterisk",Space,Str "2"]]+ ,[Para [Str "asterisk",Space,Str "3"]]]+,Para [Str "Pluses",Space,Str "tight:"]+,BulletList+ [[Plain [Str "Plus",Space,Str "1"]]+ ,[Plain [Str "Plus",Space,Str "2"]]+ ,[Plain [Str "Plus",Space,Str "3"]]]+,Para [Str "Pluses",Space,Str "loose:"]+,BulletList+ [[Para [Str "Plus",Space,Str "1"]]+ ,[Para [Str "Plus",Space,Str "2"]]+ ,[Para [Str "Plus",Space,Str "3"]]]+,Para [Str "Minuses",Space,Str "tight:"]+,BulletList+ [[Plain [Str "Minus",Space,Str "1"]]+ ,[Plain [Str "Minus",Space,Str "2"]]+ ,[Plain [Str "Minus",Space,Str "3"]]]+,Para [Str "Minuses",Space,Str "loose:"]+,BulletList+ [[Para [Str "Minus",Space,Str "1"]]+ ,[Para [Str "Minus",Space,Str "2"]]+ ,[Para [Str "Minus",Space,Str "3"]]]+,Header 2 ("ordered",[],[]) [Str "Ordered"]+,Para [Str "Tight:"]+,OrderedList (1,Decimal,Period)+ [[Plain [Str "First"]]+ ,[Plain [Str "Second"]]+ ,[Plain [Str "Third"]]]+,Para [Str "and:"]+,OrderedList (1,Decimal,Period)+ [[Plain [Str "One"]]+ ,[Plain [Str "Two"]]+ ,[Plain [Str "Three"]]]+,Para [Str "Loose",Space,Str "using",Space,Str "tabs:"]+,OrderedList (1,Decimal,Period)+ [[Para [Str "First"]]+ ,[Para [Str "Second"]]+ ,[Para [Str "Third"]]]+,Para [Str "and",Space,Str "using",Space,Str "spaces:"]+,OrderedList (1,Decimal,Period)+ [[Para [Str "One"]]+ ,[Para [Str "Two"]]+ ,[Para [Str "Three"]]]+,Para [Str "Multiple",Space,Str "paragraphs:"]+,OrderedList (1,Decimal,Period)+ [[Para [Str "Item",Space,Str "1,",Space,Str "graf",Space,Str "one."]+ ,Para [Str "Item",Space,Str "1.",Space,Str "graf",Space,Str "two.",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog\8217s",Space,Str "back."]]+ ,[Para [Str "Item",Space,Str "2."]]+ ,[Para [Str "Item",Space,Str "3."]]]+,Header 2 ("nested",[],[]) [Str "Nested"]+,BulletList+ [[Plain [Str "Tab"]+ ,BulletList+ [[Plain [Str "Tab"]+ ,BulletList+ [[Plain [Str "Tab"]]]]]]]+,Para [Str "Here\8217s",Space,Str "another:"]+,OrderedList (1,Decimal,Period)+ [[Plain [Str "First"]]+ ,[Plain [Str "Second:"]+ ,BulletList+ [[Plain [Str "Fee"]]+ ,[Plain [Str "Fie"]]+ ,[Plain [Str "Foe"]]]]+ ,[Plain [Str "Third"]]]+,Para [Str "Same",Space,Str "thing",Space,Str "but",Space,Str "with",Space,Str "paragraphs:"]+,OrderedList (1,Decimal,Period)+ [[Para [Str "First"]]+ ,[Para [Str "Second:"]+ ,BulletList+ [[Plain [Str "Fee"]]+ ,[Plain [Str "Fie"]]+ ,[Plain [Str "Foe"]]]]+ ,[Para [Str "Third"]]]+,Header 2 ("tabs-and-spaces",[],[]) [Str "Tabs",Space,Str "and",Space,Str "spaces"]+,BulletList+ [[Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"]]+ ,[Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"]+ ,BulletList+ [[Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"]]+ ,[Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"]]]]]+,Header 2 ("fancy-list-markers",[],[]) [Str "Fancy",Space,Str "list",Space,Str "markers"]+,OrderedList (2,Decimal,TwoParens)+ [[Plain [Str "begins",Space,Str "with",Space,Str "2"]]+ ,[Para [Str "and",Space,Str "now",Space,Str "3"]+ ,Para [Str "with",Space,Str "a",Space,Str "continuation"]+ ,OrderedList (4,LowerRoman,Period)+ [[Plain [Str "sublist",Space,Str "with",Space,Str "roman",Space,Str "numerals,",Space,Str "starting",Space,Str "with",Space,Str "4"]]+ ,[Plain [Str "more",Space,Str "items"]+ ,OrderedList (1,UpperAlpha,TwoParens)+ [[Plain [Str "a",Space,Str "subsublist"]]+ ,[Plain [Str "a",Space,Str "subsublist"]]]]]]]+,Para [Str "Nesting:"]+,OrderedList (1,UpperAlpha,Period)+ [[Plain [Str "Upper",Space,Str "Alpha"]+ ,OrderedList (1,UpperRoman,Period)+ [[Plain [Str "Upper",Space,Str "Roman."]+ ,OrderedList (6,Decimal,TwoParens)+ [[Plain [Str "Decimal",Space,Str "start",Space,Str "with",Space,Str "6"]+ ,OrderedList (3,LowerAlpha,OneParen)+ [[Plain [Str "Lower",Space,Str "alpha",Space,Str "with",Space,Str "paren"]]]]]]]]]+,Para [Str "Autonumbering:"]+,OrderedList (1,DefaultStyle,DefaultDelim)+ [[Plain [Str "Autonumber."]]+ ,[Plain [Str "More."]+ ,OrderedList (1,DefaultStyle,DefaultDelim)+ [[Plain [Str "Nested."]]]]]+,Para [Str "Should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "list",Space,Str "item:"]+,Para [Str "M.A.\160\&2007"]+,Para [Str "B.",Space,Str "Williams"]+,HorizontalRule+,Header 1 ("definition-lists",[],[]) [Str "Definition",Space,Str "Lists"]+,Para [Str "Tight",Space,Str "using",Space,Str "spaces:"]+,DefinitionList+ [([Str "apple"],+ [[Plain [Str "red",Space,Str "fruit"]]])+ ,([Str "orange"],+ [[Plain [Str "orange",Space,Str "fruit"]]])+ ,([Str "banana"],+ [[Plain [Str "yellow",Space,Str "fruit"]]])]+,Para [Str "Tight",Space,Str "using",Space,Str "tabs:"]+,DefinitionList+ [([Str "apple"],+ [[Plain [Str "red",Space,Str "fruit"]]])+ ,([Str "orange"],+ [[Plain [Str "orange",Space,Str "fruit"]]])+ ,([Str "banana"],+ [[Plain [Str "yellow",Space,Str "fruit"]]])]+,Para [Str "Loose:"]+,DefinitionList+ [([Str "apple"],+ [[Para [Str "red",Space,Str "fruit"]]])+ ,([Str "orange"],+ [[Para [Str "orange",Space,Str "fruit"]]])+ ,([Str "banana"],+ [[Para [Str "yellow",Space,Str "fruit"]]])]+,Para [Str "Multiple",Space,Str "blocks",Space,Str "with",Space,Str "italics:"]+,DefinitionList+ [([Emph [Str "apple"]],+ [[Para [Str "red",Space,Str "fruit"]+ ,Para [Str "contains",Space,Str "seeds,",Space,Str "crisp,",Space,Str "pleasant",Space,Str "to",Space,Str "taste"]]])+ ,([Emph [Str "orange"]],+ [[Para [Str "orange",Space,Str "fruit"]+ ,CodeBlock ("",[],[]) "{ orange code block }"+ ,BlockQuote+ [Para [Str "orange",Space,Str "block",Space,Str "quote"]]]])]+,Para [Str "Multiple",Space,Str "definitions,",Space,Str "tight:"]+,DefinitionList+ [([Str "apple"],+ [[Plain [Str "red",Space,Str "fruit"]]+ ,[Plain [Str "computer"]]])+ ,([Str "orange"],+ [[Plain [Str "orange",Space,Str "fruit"]]+ ,[Plain [Str "bank"]]])]+,Para [Str "Multiple",Space,Str "definitions,",Space,Str "loose:"]+,DefinitionList+ [([Str "apple"],+ [[Para [Str "red",Space,Str "fruit"]]+ ,[Para [Str "computer"]]])+ ,([Str "orange"],+ [[Para [Str "orange",Space,Str "fruit"]]+ ,[Para [Str "bank"]]])]+,Para [Str "Blank",Space,Str "line",Space,Str "after",Space,Str "term,",Space,Str "indented",Space,Str "marker,",Space,Str "alternate",Space,Str "markers:"]+,DefinitionList+ [([Str "apple"],+ [[Para [Str "red",Space,Str "fruit"]]+ ,[Para [Str "computer"]]])+ ,([Str "orange"],+ [[Para [Str "orange",Space,Str "fruit"]+ ,OrderedList (1,Decimal,Period)+ [[Plain [Str "sublist"]]+ ,[Plain [Str "sublist"]]]]])]+,Header 1 ("html-blocks",[],[]) [Str "HTML",Space,Str "Blocks"]+,Para [Str "Simple",Space,Str "block",Space,Str "on",Space,Str "one",Space,Str "line:"]+,Div ("",[],[]) [Plain [Str "foo"]]+,Para [Str "And",Space,Str "nested",Space,Str "without",Space,Str "indentation:"]+,Div ("",[],[]) [Div ("",[],[]) [Div ("",[],[]) [Para [Str "foo"]]],Div ("",[],[]) [Plain [Str "bar"]]]+,Para [Str "Interpreted",Space,Str "markdown",Space,Str "in",Space,Str "a",Space,Str "table:"]+,RawBlock (Format "html") "<table>"+,RawBlock (Format "html") "<tr>"+,RawBlock (Format "html") "<td>"+,Plain [Str "This",Space,Str "is",Space,Emph [Str "emphasized"]]+,RawBlock (Format "html") "</td>"+,RawBlock (Format "html") "<td>"+,Plain [Str "And",Space,Str "this",Space,Str "is",Space,Strong [Str "strong"]]+,RawBlock (Format "html") "</td>"+,RawBlock (Format "html") "</tr>"+,RawBlock (Format "html") "</table>"+,RawBlock (Format "html") "<script type=\"text/javascript\">document.write('This *should not* be interpreted as markdown');</script>"+,Para [Str "Here\8217s",Space,Str "a",Space,Str "simple",Space,Str "block:"]+,Div ("",[],[]) [Para [Str "foo"]]+,Para [Str "This",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "code",Space,Str "block,",Space,Str "though:"]+,CodeBlock ("",[],[]) "<div>\n foo\n</div>"+,Para [Str "As",Space,Str "should",Space,Str "this:"]+,CodeBlock ("",[],[]) "<div>foo</div>"+,Para [Str "Now,",Space,Str "nested:"]+,Div ("",[],[]) [Div ("",[],[]) [Div ("",[],[]) [Plain [Str "foo"]]]]+,Para [Str "This",Space,Str "should",Space,Str "just",Space,Str "be",Space,Str "an",Space,Str "HTML",Space,Str "comment:"]+,RawBlock (Format "html") "<!-- Comment -->"+,Para [Str "Multiline:"]+,RawBlock (Format "html") "<!--\nBlah\nBlah\n-->"+,RawBlock (Format "html") "<!--\n This is another comment.\n-->"+,Para [Str "Code",Space,Str "block:"]+,CodeBlock ("",[],[]) "<!-- Comment -->"+,Para [Str "Just",Space,Str "plain",Space,Str "comment,",Space,Str "with",Space,Str "trailing",Space,Str "spaces",Space,Str "on",Space,Str "the",Space,Str "line:"]+,RawBlock (Format "html") "<!-- foo -->"+,Para [Str "Code:"]+,CodeBlock ("",[],[]) "<hr />"+,Para [Str "Hr\8217s:"]+,RawBlock (Format "html") "<hr>"+,RawBlock (Format "html") "<hr />"+,RawBlock (Format "html") "<hr />"+,RawBlock (Format "html") "<hr>"+,RawBlock (Format "html") "<hr />"+,RawBlock (Format "html") "<hr />"+,RawBlock (Format "html") "<hr class=\"foo\" id=\"bar\" />"+,RawBlock (Format "html") "<hr class=\"foo\" id=\"bar\" />"+,RawBlock (Format "html") "<hr class=\"foo\" id=\"bar\">"+,HorizontalRule+,Header 1 ("inline-markup",[],[]) [Str "Inline",Space,Str "Markup"]+,Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ",",Space,Str "and",Space,Str "so",Space,Emph [Str "is",Space,Str "this"],Str "."]+,Para [Str "This",Space,Str "is",Space,Strong [Str "strong"],Str ",",Space,Str "and",Space,Str "so",Space,Strong [Str "is",Space,Str "this"],Str "."]+,Para [Str "An",Space,Emph [Link [Str "emphasized",Space,Str "link"] ("/url","")],Str "."]+,Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]+,Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word."]+,Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]+,Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word."]+,Para [Str "This",Space,Str "is",Space,Str "code:",Space,Code ("",[],[]) ">",Str ",",Space,Code ("",[],[]) "$",Str ",",Space,Code ("",[],[]) "\\",Str ",",Space,Code ("",[],[]) "\\$",Str ",",Space,Code ("",[],[]) "<html>",Str "."]+,Para [Strikeout [Str "This",Space,Str "is",Space,Emph [Str "strikeout"],Str "."]]+,Para [Str "Superscripts:",Space,Str "a",Superscript [Str "bc"],Str "d",Space,Str "a",Superscript [Emph [Str "hello"]],Space,Str "a",Superscript [Str "hello\160there"],Str "."]+,Para [Str "Subscripts:",Space,Str "H",Subscript [Str "2"],Str "O,",Space,Str "H",Subscript [Str "23"],Str "O,",Space,Str "H",Subscript [Str "many\160of\160them"],Str "O."]+,Para [Str "These",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "superscripts",Space,Str "or",Space,Str "subscripts,",Space,Str "because",Space,Str "of",Space,Str "the",Space,Str "unescaped",Space,Str "spaces:",Space,Str "a^b",Space,Str "c^d,",Space,Str "a~b",Space,Str "c~d."]+,HorizontalRule+,Header 1 ("smart-quotes-ellipses-dashes",[],[]) [Str "Smart",Space,Str "quotes,",Space,Str "ellipses,",Space,Str "dashes"]+,Para [Quoted DoubleQuote [Str "Hello,"],Space,Str "said",Space,Str "the",Space,Str "spider.",Space,Quoted DoubleQuote [Quoted SingleQuote [Str "Shelob"],Space,Str "is",Space,Str "my",Space,Str "name."]]+,Para [Quoted SingleQuote [Str "A"],Str ",",Space,Quoted SingleQuote [Str "B"],Str ",",Space,Str "and",Space,Quoted SingleQuote [Str "C"],Space,Str "are",Space,Str "letters."]+,Para [Quoted SingleQuote [Str "Oak,"],Space,Quoted SingleQuote [Str "elm,"],Space,Str "and",Space,Quoted SingleQuote [Str "beech"],Space,Str "are",Space,Str "names",Space,Str "of",Space,Str "trees.",Space,Str "So",Space,Str "is",Space,Quoted SingleQuote [Str "pine."]]+,Para [Quoted SingleQuote [Str "He",Space,Str "said,",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70\8217s?"]+,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "quoted",Space,Quoted SingleQuote [Code ("",[],[]) "code"],Space,Str "and",Space,Str "a",Space,Quoted DoubleQuote [Link [Str "quoted",Space,Str "link"] ("http://example.com/?foo=1&bar=2","")],Str "."]+,Para [Str "Some",Space,Str "dashes:",Space,Str "one\8212two",Space,Str "\8212",Space,Str "three\8212four",Space,Str "\8212",Space,Str "five."]+,Para [Str "Dashes",Space,Str "between",Space,Str "numbers:",Space,Str "5\8211\&7,",Space,Str "255\8211\&66,",Space,Str "1987\8211\&1999."]+,Para [Str "Ellipses\8230and\8230and\8230."]+,HorizontalRule+,Header 1 ("latex",[],[]) [Str "LaTeX"]+,BulletList+ [[Plain [RawInline (Format "tex") "\\cite[22-23]{smith.1899}"]]+ ,[Plain [Math InlineMath "2+2=4"]]+ ,[Plain [Math InlineMath "x \\in y"]]+ ,[Plain [Math InlineMath "\\alpha \\wedge \\omega"]]+ ,[Plain [Math InlineMath "223"]]+ ,[Plain [Math InlineMath "p",Str "-Tree"]]+ ,[Plain [Str "Here\8217s",Space,Str "some",Space,Str "display",Space,Str "math:",Space,Math (DisplayMath ("",[],[])) "\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"]]+ ,[Plain [Str "Here\8217s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it:",Space,Math InlineMath "\\alpha + \\omega \\times x^2",Str "."]]]+,Para [Str "These",Space,Str "shouldn\8217t",Space,Str "be",Space,Str "math:"]+,BulletList+ [[Plain [Str "To",Space,Str "get",Space,Str "the",Space,Str "famous",Space,Str "equation,",Space,Str "write",Space,Code ("",[],[]) "$e = mc^2$",Str "."]]+ ,[Plain [Str "$22,000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money.",Space,Str "So",Space,Str "is",Space,Str "$34,000.",Space,Str "(It",Space,Str "worked",Space,Str "if",Space,Quoted DoubleQuote [Str "lot"],Space,Str "is",Space,Str "emphasized.)"]]+ ,[Plain [Str "Shoes",Space,Str "($20)",Space,Str "and",Space,Str "socks",Space,Str "($5)."]]+ ,[Plain [Str "Escaped",Space,Code ("",[],[]) "$",Str ":",Space,Str "$73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23$."]]]+,Para [Str "Here\8217s",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]+,RawBlock (Format "latex") "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}"+,HorizontalRule+,Header 1 ("special-characters",[],[]) [Str "Special",Space,Str "Characters"]+,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode:"]+,BulletList+ [[Plain [Str "I",Space,Str "hat:",Space,Str "\206"]]+ ,[Plain [Str "o",Space,Str "umlaut:",Space,Str "\246"]]+ ,[Plain [Str "section:",Space,Str "\167"]]+ ,[Plain [Str "set",Space,Str "membership:",Space,Str "\8712"]]+ ,[Plain [Str "copyright:",Space,Str "\169"]]]+,Para [Str "AT&T",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "their",Space,Str "name."]+,Para [Str "AT&T",Space,Str "is",Space,Str "another",Space,Str "way",Space,Str "to",Space,Str "write",Space,Str "it."]+,Para [Str "This",Space,Str "&",Space,Str "that."]+,Para [Str "4",Space,Str "<",Space,Str "5."]+,Para [Str "6",Space,Str ">",Space,Str "5."]+,Para [Str "Backslash:",Space,Str "\\"]+,Para [Str "Backtick:",Space,Str "`"]+,Para [Str "Asterisk:",Space,Str "*"]+,Para [Str "Underscore:",Space,Str "_"]+,Para [Str "Left",Space,Str "brace:",Space,Str "{"]+,Para [Str "Right",Space,Str "brace:",Space,Str "}"]+,Para [Str "Left",Space,Str "bracket:",Space,Str "["]+,Para [Str "Right",Space,Str "bracket:",Space,Str "]"]+,Para [Str "Left",Space,Str "paren:",Space,Str "("]+,Para [Str "Right",Space,Str "paren:",Space,Str ")"]+,Para [Str "Greater-than:",Space,Str ">"]+,Para [Str "Hash:",Space,Str "#"]+,Para [Str "Period:",Space,Str "."]+,Para [Str "Bang:",Space,Str "!"]+,Para [Str "Plus:",Space,Str "+"]+,Para [Str "Minus:",Space,Str "-"]+,HorizontalRule+,Header 1 ("links",[],[]) [Str "Links"]+,Header 2 ("explicit",[],[]) [Str "Explicit"]+,Para [Str "Just",Space,Str "a",Space,Link [Str "URL"] ("/url/",""),Str "."]+,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title"),Str "."]+,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title preceded by two spaces"),Str "."]+,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title preceded by a tab"),Str "."]+,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title with \"quotes\" in it")]+,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title with single quotes")]+,Para [Link [Str "with_underscore"] ("/url/with_underscore","")]+,Para [Link [Str "Email",Space,Str "link"] ("mailto:nobody@nowhere.net","")]+,Para [Link [Str "Empty"] ("",""),Str "."]+,Header 2 ("reference",[],[]) [Str "Reference"]+,Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+,Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+,Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+,Para [Str "With",Space,Link [Str "embedded",Space,Str "[brackets]"] ("/url/",""),Str "."]+,Para [Link [Str "b"] ("/url/",""),Space,Str "by",Space,Str "itself",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "link."]+,Para [Str "Indented",Space,Link [Str "once"] ("/url",""),Str "."]+,Para [Str "Indented",Space,Link [Str "twice"] ("/url",""),Str "."]+,Para [Str "Indented",Space,Link [Str "thrice"] ("/url",""),Str "."]+,Para [Str "This",Space,Str "should",Space,Str "[not][]",Space,Str "be",Space,Str "a",Space,Str "link."]+,CodeBlock ("",[],[]) "[not]: /url"+,Para [Str "Foo",Space,Link [Str "bar"] ("/url/","Title with \"quotes\" inside"),Str "."]+,Para [Str "Foo",Space,Link [Str "biz"] ("/url/","Title with \"quote\" inside"),Str "."]+,Header 2 ("with-ampersands",[],[]) [Str "With",Space,Str "ampersands"]+,Para [Str "Here\8217s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]+,Para [Str "Here\8217s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text:",Space,Link [Str "AT&T"] ("http://att.com/","AT&T"),Str "."]+,Para [Str "Here\8217s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]+,Para [Str "Here\8217s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]+,Header 2 ("autolinks",[],[]) [Str "Autolinks"]+,Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link [Str "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]+,BulletList+ [[Plain [Str "In",Space,Str "a",Space,Str "list?"]]+ ,[Plain [Link [Str "http://example.com/"] ("http://example.com/","")]]+ ,[Plain [Str "It",Space,Str "should."]]]+,Para [Str "An",Space,Str "e-mail",Space,Str "address:",Space,Link [Str "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]+,BlockQuote+ [Para [Str "Blockquoted:",Space,Link [Str "http://example.com/"] ("http://example.com/","")]]+,Para [Str "Auto-links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",Space,Code ("",[],[]) "<http://example.com/>"]+,CodeBlock ("",[],[]) "or here: <http://example.com/>"+,HorizontalRule+,Header 1 ("images",[],[]) [Str "Images"]+,Para [Str "From",Space,Quoted DoubleQuote [Str "Voyage",Space,Str "dans",Space,Str "la",Space,Str "Lune"],Space,Str "by",Space,Str "Georges",Space,Str "Melies",Space,Str "(1902):"]+,Para [Image ("",[],[]) [Str "lalune"] ("lalune.jpg","fig:Voyage dans la Lune")]+,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image ("",[],[]) [Str "movie"] ("movie.jpg",""),Space,Str "icon."]+,HorizontalRule+,Header 1 ("footnotes",[],[]) [Str "Footnotes"]+,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote.",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference.",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document."]],Space,Str "and",Space,Str "another.",Note [Para [Str "Here\8217s",Space,Str "the",Space,Str "long",Space,Str "note.",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "list",Space,Str "items)."],CodeBlock ("",[],[]) " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line,",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space.[^my",Space,Str "note]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note.",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type.",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code ("",[],[]) "]",Space,Str "verbatim",Space,Str "characters,",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[bracketed",Space,Str "text]."]]]+,BlockQuote+ [Para [Str "Notes",Space,Str "can",Space,Str "go",Space,Str "in",Space,Str "quotes.",Note [Para [Str "In",Space,Str "quote."]]]]+,OrderedList (1,Decimal,Period)+ [[Plain [Str "And",Space,Str "in",Space,Str "list",Space,Str "items.",Note [Para [Str "In",Space,Str "list."]]]]]+,Para [Str "This",Space,Str "paragraph",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "part",Space,Str "of",Space,Str "the",Space,Str "note,",Space,Str "as",Space,Str "it",Space,Str "is",Space,Str "not",Space,Str "indented."]]
@@ -0,0 +1,696 @@+Pandoc Test Suite+John MacFarlane; Anonymous+July 17, 2006++This is a set of tests for pandoc. Most of them are adapted from John Gruber’s+markdown test suite.++------------------------------------------------------------------------------++++HEADERS+++Level 2 with an embedded link++Level 3 with _emphasis_++Level 4++Level 5++++LEVEL 1+++Level 2 with _emphasis_++Level 3++with no blank line+++Level 2++with no blank line++------------------------------------------------------------------------------++++PARAGRAPHS+++Here’s a regular paragraph.++In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item.+Because a hard-wrapped line in the middle of a paragraph looked like a list+item.++Here’s one with a bullet. * criminey.++There should be a hard line break+here.++------------------------------------------------------------------------------++++BLOCK QUOTES+++E-mail style:++ This is a block quote. It is pretty short.++ Code in a block quote:++ sub status {+ print "working";+ }++ A list:++ 1. item one+ 2. item two++ Nested block quotes:++ nested++ nested++This should not be a block quote: 2 > 1.++And a following paragraph.++------------------------------------------------------------------------------++++CODE BLOCKS+++Code:++ ---- (should be four hyphens)++ sub status {+ print "working";+ }++ this code block is indented by one tab++And:++ this code block is indented by two tabs++ These should not be escaped: \$ \\ \> \[ \{++------------------------------------------------------------------------------++++LISTS+++Unordered++Asterisks tight:++- asterisk 1+- asterisk 2+- asterisk 3++Asterisks loose:++- asterisk 1++- asterisk 2++- asterisk 3++Pluses tight:++- Plus 1+- Plus 2+- Plus 3++Pluses loose:++- Plus 1++- Plus 2++- Plus 3++Minuses tight:++- Minus 1+- Minus 2+- Minus 3++Minuses loose:++- Minus 1++- Minus 2++- Minus 3+++Ordered++Tight:++1. First+2. Second+3. Third++and:++1. One+2. Two+3. Three++Loose using tabs:++1. First++2. Second++3. Third++and using spaces:++1. One++2. Two++3. Three++Multiple paragraphs:++1. Item 1, graf one.++ Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.++2. Item 2.++3. Item 3.+++Nested++- Tab+ - Tab+ - Tab++Here’s another:++1. First+2. Second:+ - Fee+ - Fie+ - Foe++3. Third++Same thing but with paragraphs:++1. First++2. Second:++ - Fee+ - Fie+ - Foe++3. Third+++Tabs and spaces++- this is a list item indented with tabs++- this is a list item indented with spaces++ - this is an example list item indented with tabs++ - this is an example list item indented with spaces+++Fancy list markers++(2) begins with 2+(3) and now 3++ with a continuation++ iv. sublist with roman numerals, starting with 4+ v. more items+ (A) a subsublist+ (B) a subsublist++Nesting:++A. Upper Alpha+ I. Upper Roman.+ (6) Decimal start with 6+ c) Lower alpha with paren++Autonumbering:++1. Autonumber.+2. More.+ 1. Nested.++Should not be a list item:++M.A. 2007++B. Williams++------------------------------------------------------------------------------++++DEFINITION LISTS+++Tight using spaces:++apple+ red fruit++orange+ orange fruit++banana+ yellow fruit++Tight using tabs:++apple+ red fruit++orange+ orange fruit++banana+ yellow fruit++Loose:++apple++ red fruit++orange++ orange fruit++banana++ yellow fruit++Multiple blocks with italics:++_apple_++ red fruit++ contains seeds, crisp, pleasant to taste++_orange_++ orange fruit++ { orange code block }++ orange block quote++Multiple definitions, tight:++apple+ red fruit+ computer++orange+ orange fruit+ bank++Multiple definitions, loose:++apple++ red fruit++ computer++orange++ orange fruit++ bank++Blank line after term, indented marker, alternate markers:++apple++ red fruit++ computer++orange++ orange fruit++ 1. sublist+ 2. sublist++++HTML BLOCKS+++Simple block on one line:++foo++And nested without indentation:++foo++bar++Interpreted markdown in a table:++This is _emphasized_+And this is STRONG+Here’s a simple block:++foo++This should be a code block, though:++ <div>+ foo+ </div>++As should this:++ <div>foo</div>++Now, nested:++foo++This should just be an HTML comment:++Multiline:++Code block:++ <!-- Comment -->++Just plain comment, with trailing spaces on the line:++Code:++ <hr />++Hr’s:++------------------------------------------------------------------------------++++INLINE MARKUP+++This is _emphasized_, and so _is this_.++This is STRONG, and so IS THIS.++An _emphasized link_.++_THIS IS STRONG AND EM._++So is _THIS_ word.++_THIS IS STRONG AND EM._++So is _THIS_ word.++This is code: >, $, \, \$, <html>.++~~This is _strikeout_.~~++Superscripts: a^bc^d a^_hello_^ a^hello there^.++Subscripts: H~2~O, H~23~O, H~many of them~O.++These should not be superscripts or subscripts, because of the unescaped+spaces: a^b c^d, a~b c~d.++------------------------------------------------------------------------------++++SMART QUOTES, ELLIPSES, DASHES+++“Hello,” said the spider. “‘Shelob’ is my name.”++‘A’, ‘B’, and ‘C’ are letters.++‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’++‘He said, “I want to go.”’ Were you alive in the 70’s?++Here is some quoted ‘code’ and a “quoted link”.++Some dashes: one—two — three—four — five.++Dashes between numbers: 5–7, 255–66, 1987–1999.++Ellipses…and…and….++------------------------------------------------------------------------------++++LATEX+++- +- 2 + 2 = 4+- x ∈ y+- α ∧ ω+- 223+- p-Tree+- Here’s some display math:+ $$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$+- Here’s one that has a line break in it: α + ω × x^2^.++These shouldn’t be math:++- To get the famous equation, write $e = mc^2$.+- $22,000 is a _lot_ of money. So is $34,000. (It worked if “lot” is+ emphasized.)+- Shoes ($20) and socks ($5).+- Escaped $: $73 _this should be emphasized_ 23$.++Here’s a LaTeX table:++------------------------------------------------------------------------------++++SPECIAL CHARACTERS+++Here is some unicode:++- I hat: Î+- o umlaut: ö+- section: §+- set membership: ∈+- copyright: ©++AT&T has an ampersand in their name.++AT&T is another way to write it.++This & that.++4 < 5.++6 > 5.++Backslash: \++Backtick: `++Asterisk: *++Underscore: _++Left brace: {++Right brace: }++Left bracket: [++Right bracket: ]++Left paren: (++Right paren: )++Greater-than: >++Hash: #++Period: .++Bang: !++Plus: +++Minus: -++------------------------------------------------------------------------------++++LINKS+++Explicit++Just a URL.++URL and title.++URL and title.++URL and title.++URL and title++URL and title++with_underscore++Email link++Empty.+++Reference++Foo bar.++Foo bar.++Foo bar.++With embedded [brackets].++b by itself should be a link.++Indented once.++Indented twice.++Indented thrice.++This should [not][] be a link.++ [not]: /url++Foo bar.++Foo biz.+++With ampersands++Here’s a link with an ampersand in the URL.++Here’s a link with an amersand in the link text: AT&T.++Here’s an inline link.++Here’s an inline link in pointy braces.+++Autolinks++With an ampersand: http://example.com/?foo=1&bar=2++- In a list?+- http://example.com/+- It should.++An e-mail address: nobody@nowhere.net++ Blockquoted: http://example.com/++Auto-links should not occur here: <http://example.com/>++ or here: <http://example.com/>++------------------------------------------------------------------------------++++IMAGES+++From “Voyage dans la Lune” by Georges Melies (1902):++[lalune]++Here is a movie [movie] icon.++------------------------------------------------------------------------------++++FOOTNOTES+++Here is a footnote reference,[1] and another.[2] This should _not_ be a+footnote reference, because it contains a space.[^my note] Here is an inline+note.[3]++ Notes can go in quotes.[4]++1. And in list items.[5]++This paragraph should not be part of the note, as it is not indented.++[1] Here is the footnote. It can go anywhere after the footnote reference. It+need not be placed at the end of the document.++[2] Here’s the long note. This one contains multiple blocks.++Subsequent blocks are indented to show that they belong to the footnote (as+with list items).++ { <code> }++If you want, you can indent every line, but you can also be lazy and just+indent the first line of each block.++[3] This is _easier_ to type. Inline notes may contain links and ] verbatim+characters, as well as [bracketed text].++[4] In quote.++[5] In list.
@@ -0,0 +1,96 @@+<!doctype html>+<html lang="en">+<head>+ <meta charset="utf-8">+ <title>Dingus | ScholarlyMarkdown</title>+ <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>+ <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>+ <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">+ <script type="text/javascript">+(function($) { // http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values+ $.QueryString = (function(a) {+ if (a == "") return {};+ var b = {};+ for (var i = 0; i < a.length; ++i)+ {+ var p=a[i].split('=');+ if (p.length != 2) continue;+ b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));+ }+ return b;+ })(window.location.search.substr(1).split('&'))+})(jQuery);++function newpage() {+ var from = "markdown_scholarly";+ var input = $("#text").val();+ var to = $("#to").val();+ var href = window.location.href;+ window.location.href = href.replace(/([?].*)?$/,"?" + $.param({text: input, from: from, to: to}));+};++function process(res) {+ $("#results").text(res.result);+ $("#version").text(res.version);+}++$(document).ready(function() {+ var from = "markdown_scholarly";+ var text = $.QueryString["text"];+ $("#text").val(text);+ var to = $.QueryString["to"] || "html5";+ $("#to").val(to);+ if (text && text != "") {+ $.getJSON("http://scholarlymarkdown.com/cgi-bin/tryscholdoc", { from: from, to: to, text: text }, process);+ };+ $("#convert").click(newpage);+});+ </script>+ <style type="text/css">+ h1 { margin-bottom: 1em; }+ body { margin: auto; }+ textarea { height: auto; width: 100%; font-family: monospace; margin-top: 15px; }+ div.alert { margin: 1em; }+ h3 { margin-top: 0; margin-bottom: 0; padding: 0; font-size: 100%; }+ pre#results { width: 100%; margin-top: 15px; }+ footer { color: #555; text-align: center; margin: 1em; }+ p.version { color: #555; }+ button#convert { vertical-align: bottom; }+ </style>+</head>+<body>+<div class="container">+ <div class="row">+ <h1>ScholarlyMarkdown Dingus</h1>+ </div>+ <div class="row">+ <div class="col-md-6">+ <label for="from">+ ScholarlyMarkdown source+ </label>+ <br/>+ <textarea id="text" maxlength="3000" rows="15" placeholder="Type ScholarlyMarkdown here, then press the Convert button on the right"></textarea>+ </div>+ <div class="col-md-6">+ <label for="to">+ to+ </label>+ <select id="to">+ <option value="html5" selected>HTML 5</option>+ <option value="latex">LaTeX</option>+ <option value="beamer">LaTeX Beamer</option>+ </select>+ + <button class="btn btn-primary btn-xs" id="convert">Convert</button>+ <br/>+ <pre id="results"></pre>+ </div>+ </div>+</div>+<footer>+ <p class="version">Using scholdoc <span id="version"></span></p>+ <p>© 2014 <a href="https://github.com/timtylin/">Tim T.Y. Lin</a></p>+ based on trypandoc <p>© 2013–2014 <a href="http://johnmacfarlane.net">John MacFarlane</a></p>+</footer>+</body>+</html>
@@ -0,0 +1,81 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where+import Network.Wai.Handler.CGI+import Network.Wai+import Control.Applicative ((<$>))+import Data.Maybe (mapMaybe, fromMaybe)+import Network.HTTP.Types.Status (status200)+import Network.HTTP.Types.Header (hContentType)+import Network.HTTP.Types.URI (queryToQueryText)+import Text.Pandoc+import Text.Pandoc.Shared (tabFilter)+import Text.Highlighting.Kate (pygments)+import Data.Aeson+import qualified Data.Text as T+import Data.Text (Text)++main :: IO ()+main = run app++app :: Application+app req respond = do+ let query = queryToQueryText $ queryString req+ let getParam x = maybe (error $ T.unpack x ++ " paramater not set")+ return $ lookup x query+ text <- getParam "text" >>= checkLength . fromMaybe T.empty+ fromFormat <- fromMaybe "" <$> getParam "from"+ toFormat <- fromMaybe "" <$> getParam "to"+ reader <- maybe (error $ "could not find reader for " ++ T.unpack fromFormat) return+ $ lookup fromFormat fromFormats+ let writer = maybe (error $ "could not find writer for " ++ T.unpack toFormat) id+ $ lookup toFormat toFormats+ let result = T.pack $ writer $ reader $ tabFilter 4 $ T.unpack text+ let output = encode $ object [ T.pack "result" .= result+ , T.pack "name" .=+ if fromFormat == "markdown_strict"+ then T.pack "scholdoc (strict)"+ else T.pack "scholdoc"+ , T.pack "version" .= pandocVersion]+ respond $ responseLBS status200 [(hContentType,"text/json; charset=UTF-8")] output++checkLength :: Text -> IO Text+checkLength t =+ if T.length t > 10000+ then error "exceeds length limit of 10,000 characters"+ else return t++writerOpts :: WriterOptions+writerOpts = def { writerReferenceLinks = True,+ writerEmailObfuscation = NoObfuscation,+ writerHTMLMathMethod = MathJax "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full",+ writerScholarly = True,+ writerHighlight = True,+ writerHighlightStyle = pygments }++readerOpts :: ReaderOptions+readerOpts = def { readerParseRaw = True,+ readerSmart = True }++fromFormats :: [(Text, String -> Pandoc)]+fromFormats = [+ ("native" , readNative)+ ,("json" , Text.Pandoc.readJSON readerOpts)+ ,("markdown_scholarly", readMarkdown readerOpts{+ readerExtensions = scholarlyMarkdownExtensions})+ ]++toFormats :: [(Text, Pandoc -> String)]+toFormats = mapMaybe (\(x,y) ->+ case y of+ PureStringWriter w -> Just (T.pack x, w writerOpts{+ writerExtensions =+ case x of+ "markdown_strict" -> strictExtensions+ "markdown_phpextra" -> phpMarkdownExtraExtensions+ "markdown_mmd" -> multimarkdownExtensions+ "markdown_github" -> githubMarkdownExtensions+ "markdown" -> pandocExtensions+ _ -> scholarlyMarkdownExtensions+ })+ _ -> Nothing) writers+