pandoc 2.11.2 → 2.11.3
raw patch · 133 files changed
+3850/−2131 lines, 133 filesdep ~binarydep ~citeprocdep ~doctemplatesbinary-added
Dependency ranges changed: binary, citeproc, doctemplates, skylighting, skylighting-core
Files
- AUTHORS.md +8/−0
- CONTRIBUTING.md +69/−6
- MANUAL.txt +59/−13
- app/pandoc.hs +22/−0
- cabal.project +5/−4
- changelog.md +291/−0
- data/templates/article.jats_publishing +4/−3
- data/templates/default.epub2 +1/−1
- data/templates/default.epub3 +1/−1
- data/templates/default.jats_articleauthoring +4/−3
- data/templates/default.latex +9/−5
- data/translations/zh-Hans.yaml +22/−0
- data/translations/zh-Hant.yaml +22/−0
- man/pandoc.1 +61/−14
- pandoc.cabal +16/−14
- pandoc.hs +0/−22
- src/Text/Pandoc/App.hs +3/−3
- src/Text/Pandoc/CSS.hs +23/−24
- src/Text/Pandoc/Citeproc.hs +42/−26
- src/Text/Pandoc/Citeproc/BibTeX.hs +7/−8
- src/Text/Pandoc/Extensions.hs +10/−3
- src/Text/Pandoc/ImageSize.hs +43/−333
- src/Text/Pandoc/Lua/Marshaling/Context.hs +1/−0
- src/Text/Pandoc/Options.hs +1/−0
- src/Text/Pandoc/Parsing.hs +32/−9
- src/Text/Pandoc/Readers/CSV.hs +1/−1
- src/Text/Pandoc/Readers/CommonMark.hs +16/−6
- src/Text/Pandoc/Readers/DocBook.hs +12/−2
- src/Text/Pandoc/Readers/DokuWiki.hs +1/−1
- src/Text/Pandoc/Readers/HTML.hs +41/−409
- src/Text/Pandoc/Readers/HTML/Parsing.hs +225/−0
- src/Text/Pandoc/Readers/HTML/Table.hs +263/−0
- src/Text/Pandoc/Readers/HTML/TagCategories.hs +78/−0
- src/Text/Pandoc/Readers/HTML/Types.hs +97/−0
- src/Text/Pandoc/Readers/LaTeX.hs +21/−3
- src/Text/Pandoc/Readers/Org/Inlines.hs +4/−5
- src/Text/Pandoc/Readers/Org/Meta.hs +2/−0
- src/Text/Pandoc/Writers/Docbook.hs +65/−27
- src/Text/Pandoc/Writers/Docx.hs +87/−64
- src/Text/Pandoc/Writers/EPUB.hs +10/−3
- src/Text/Pandoc/Writers/HTML.hs +12/−20
- src/Text/Pandoc/Writers/ICML.hs +6/−1
- src/Text/Pandoc/Writers/JATS.hs +3/−2
- src/Text/Pandoc/Writers/JATS/Table.hs +212/−46
- src/Text/Pandoc/Writers/LaTeX.hs +44/−253
- src/Text/Pandoc/Writers/LaTeX/Caption.hs +48/−0
- src/Text/Pandoc/Writers/LaTeX/Notes.hs +34/−0
- src/Text/Pandoc/Writers/LaTeX/Table.hs +181/−0
- src/Text/Pandoc/Writers/LaTeX/Types.hs +80/−0
- src/Text/Pandoc/Writers/Markdown.hs +8/−1
- src/Text/Pandoc/Writers/OpenDocument.hs +116/−32
- src/Text/Pandoc/Writers/RST.hs +21/−9
- src/Text/Pandoc/Writers/Shared.hs +1/−2
- stack.yaml +8/−10
- test/Tests/Old.hs +1/−1
- test/Tests/Readers/HTML.hs +3/−11
- test/Tests/Readers/Org/Meta.hs +8/−2
- test/Tests/Writers/Docbook.hs +66/−0
- test/Tests/Writers/Docx.hs +10/−0
- test/command/1881.md +13/−13
- test/command/2378.md +3/−3
- test/command/4420.md +0/−11
- test/command/4742.md +2/−2
- test/command/5367.md +5/−10
- test/command/5541-nesting.md +1/−0
- test/command/5986.md +3/−2
- test/command/6388.md +16/−0
- test/command/6755.md +11/−0
- test/command/6774.md +63/−0
- test/command/6791.md +32/−0
- test/command/6792.md +66/−0
- test/command/6869.md +6/−0
- test/command/6873.md +7/−0
- test/command/6890.md +36/−0
- test/command/6925.md +34/−0
- test/command/6948.md +31/−0
- test/command/6951.md +18/−0
- test/command/latex-center.md +13/−0
- test/command/pandoc-citeproc-53.md +4/−2
- test/command/svg.md +4/−0
- test/docx/golden/block_quotes.docx binary
- test/docx/golden/codeblock.docx binary
- test/docx/golden/comments.docx binary
- test/docx/golden/custom_style_no_reference.docx binary
- test/docx/golden/custom_style_preserve.docx binary
- test/docx/golden/custom_style_reference.docx binary
- test/docx/golden/definition_list.docx binary
- test/docx/golden/document-properties-short-desc.docx binary
- test/docx/golden/document-properties.docx binary
- test/docx/golden/headers.docx binary
- test/docx/golden/image.docx binary
- test/docx/golden/inline_code.docx binary
- test/docx/golden/inline_formatting.docx binary
- test/docx/golden/inline_images.docx binary
- test/docx/golden/link_in_notes.docx binary
- test/docx/golden/links.docx binary
- test/docx/golden/lists.docx binary
- test/docx/golden/lists_continuing.docx binary
- test/docx/golden/lists_multiple_initial.docx binary
- test/docx/golden/lists_restarting.docx binary
- test/docx/golden/nested_anchors_in_header.docx binary
- test/docx/golden/notes.docx binary
- test/docx/golden/raw-blocks.docx binary
- test/docx/golden/raw-bookmarks.docx binary
- test/docx/golden/table_one_row.docx binary
- test/docx/golden/table_with_list_cell.docx binary
- test/docx/golden/tables.docx binary
- test/docx/golden/track_changes_deletion.docx binary
- test/docx/golden/track_changes_insertion.docx binary
- test/docx/golden/track_changes_move.docx binary
- test/docx/golden/track_changes_scrubbed_metadata.docx binary
- test/docx/golden/unicode.docx binary
- test/docx/golden/verbatim_subsuper.docx binary
- test/docx/raw-blocks.native +6/−0
- test/docx/raw-bookmarks.native +3/−0
- test/epub/wasteland.native +4/−4
- test/html-reader.html +76/−0
- test/html-reader.native +146/−36
- test/latex-reader.native +26/−13
- test/lhs-test.html +1/−0
- test/lhs-test.html+lhs +1/−0
- test/lhs-test.latex +1/−2
- test/lhs-test.latex+lhs +1/−2
- test/tables.jats_archiving +98/−106
- test/tables.jats_articleauthoring +98/−106
- test/tables.jats_publishing +98/−106
- test/tables.latex +50/−128
- test/tables/nordics.native +60/−33
- test/tables/planets.native +215/−112
- test/tables/students.native +49/−32
- test/writer.icml +2/−0
- test/writer.latex +1/−2
- test/writers-lang-and-dir.latex +5/−3
@@ -1,11 +1,13 @@ # Contributors - Anabra+- Aner Lucero - Arata Mizuki - Arfon Smith - Aaron Wolen - Albert Krewinkel - Alex Ivkin+- Alex Toldaiev - Alex Vong - Alexander Kondratskiy - Alexander Krotov@@ -104,6 +106,7 @@ - Hubert Plociniczak - Ian Max Andolina - Igor Khorlo+- Igor Pashev - Ilya V. Portnov - Ivan Trubach - Ivo Clarysse@@ -117,6 +120,7 @@ - Jamie F. Olson - Jan Larres - Jan Schulz+- Jan Tojnar - Jan-Otto Kröpke - Jason Ronallo - Jeff Arnold@@ -227,6 +231,7 @@ - Shahbaz Youssefi - Shaun Attfield - Shim Myeongseob+- Shin Sang-jae - Sidarth Kapur - Sidharth Kapur - Simon Hengel@@ -270,6 +275,7 @@ - bucklereed - bumper314 - chinapedia+- cholonam - csforste - dbecher-ito - d-dorazio@@ -292,6 +298,8 @@ - rski - shreevatsa.public - takahashim+- taotieren+- TEC - tgkokk - the-solipsist - thsutton
@@ -1,6 +1,64 @@ Contributing to pandoc ====================== +Welcome to pandoc! Very soon after its beginnings in 2006, pandoc+has been influenced, improved, and modified, by users, devs, and+newcomers alike. The project thrives on its active community. It is+great to have you here.++How can I help?+---------------++There are many ways in which you can support pandoc. Here are a few+ideas:++ * Participate in online discussions. The [pandoc-discuss] mailing+ list is a good place for this. This gives valuable input and+ makes it easier to improve the program.++ * Help with questions. Every request that is answered by the wider+ community frees time for programming contributors. This will+ speed up development of new features and issue fixes. Don't+ underestimate your knowledge, please share it!++ Good places to help are the [pandoc-discuss] mailing list, Q/A+ sites like StackOverflow, community forums (e.g.+ [RStudio][RStudio Community], [Zettlr][Zettlr Forum]), and, for+ technical questions, the GitHub [issue tracker].++ * Write or improve documentation. If you ran into a problem which+ took more time to figure out than expected, please consider to+ save other users from the same experience. People writing the+ documentation tend to lack an outside few, so please help+ provide one. Good documentation is both difficult and extremely+ important.++ The official docs are not the only place for documentation.+ Pandoc also has a [Wiki][pandoc wiki]. Private blogs can serve+ as documentation just as the official manual can.++ * Contribute code. No matter whether it's a small fix in a format+ template or a huge lump of Haskell code: help is welcome. It's+ usually a good idea to talk about the plans early, as this can+ prevent unnecessary work. See below for more information.++ * Last but not least: consider funding the development and+ maintenance of pandoc financially. You can find sponsor buttons+ on the [pandoc website] and the [GitHub repository][GitHub+ repo].++A rich ecosystem of libraries, editors, filters, and templates has+developed around pandoc; conversely, pandoc builds and depends on a+large number of libraries. Contributing to any of these projects is+another way that can help to ensure stability, and to keep pushing+the boundaries of what is possible with pandoc.++[RStudio Community]: https://community.rstudio.com/+[Zettlr Forum]: https://forum.zettlr.com/+[pandoc wiki]: https://github.com/jgm/pandoc/wiki+[pandoc website]: https://pandoc.org+[GitHub repo]: https://github.com/jgm/pandoc+ Have a question? ---------------- @@ -105,7 +163,12 @@ feature be useful? Consider also any possible drawbacks, including backwards compatibility, new library dependencies, and performance issues. -It is best to discuss a potential new feature on [pandoc-discuss]+Features are very rarely "implement and forget", as all code must be+maintained. This is especially relevant for large or complex+contributions. It is helpful to be sympathetic to that fact, and to+communicate future plans and availability clearly.++Any potential new feature is best discussed on [pandoc-discuss] before opening an issue. Patches and pull requests@@ -225,7 +288,7 @@ before creating a commit: #!/bin/sh- git diff --cached --name-only | grep '.hs$' | xargs hlint+ git diff --cached --name-only | grep '\.hs$' | xargs hlint Saving this to `.git/hooks/pre-commit`, and making the script executable, will prevent accidental introduction of potentially@@ -258,10 +321,10 @@ We recommend using the following `.ghci` file (which can be placed in the source directory): - :set -fobject-code- :set -XTypeSynonymInstances- :set -XScopedTypeVariables- :set -XOverloadedStrings+ :set -fobject-code+ :set -XTypeSynonymInstances+ :set -XScopedTypeVariables+ :set -XOverloadedStrings Profiling ---------
@@ -1,7 +1,7 @@ --- title: Pandoc User's Guide author: John MacFarlane-date: November 19, 2020+date: December 17, 2020 --- # Synopsis@@ -899,11 +899,6 @@ `--resource-path=.:test` will search the working directory and the `test` subdirectory, in that order. - `--resource-path` only has an effect if (a) the output- format embeds images (for example, `docx`, `pdf`, or `html`- with `--self-contained`) or (b) it is used together with- `--extract-media`.- `--request-header=`*NAME*`:`*VAL* : Set the request header *NAME* to the value *VAL* when making@@ -1000,8 +995,8 @@ `-N`, `--number-sections` -: Number section headings in LaTeX, ConTeXt, HTML, Docx, or EPUB output.- By default, sections are not numbered. Sections with class+: Number section headings in LaTeX, ConTeXt, HTML, Docx, ms, or EPUB+ output. By default, sections are not numbered. Sections with class `unnumbered` will never be numbered, even if `--number-sections` is specified. @@ -1334,7 +1329,10 @@ : Set the `bibliography` field in the document's metadata to *FILE*, overriding any value set in the metadata. If you supply this argument multiple times, each *FILE* will be added to- bibliography.+ bibliography. If *FILE* is a URL, it will be fetched+ via HTTP. If *FILE* is not found relative to the+ working directory, it will be sought in the resource path+ (see `--resource-path`). `--csl=`*FILE* @@ -1343,8 +1341,8 @@ `--metadata csl=FILE`.) If *FILE* is a URL, it will be fetched via HTTP. If *FILE* is not found relative to the working directory, it will be sought in the resource path- and finally in the `csl` subdirectory of the- pandoc user data directory.+ (see `--resource-path`) and finally in the `csl`+ subdirectory of the pandoc user data directory. `--citation-abbreviations=`*FILE* @@ -1353,8 +1351,8 @@ `--metadata citation-abbreviations=FILE`.) If *FILE* is a URL, it will be fetched via HTTP. If *FILE* is not found relative to the working directory, it will be sought- in the resource path and finally in the `csl` subdirectory- of the pandoc user data directory.+ in the resource path (see `--resource-path`) and finally in+ the `csl` subdirectory of the pandoc user data directory. `--natbib` @@ -3027,6 +3025,43 @@ output formats : `odt`, `opendocument` +#### Extension: `xrefs_name` ####++Links to headings, figures and tables inside the document are+substituted with cross-references that will use the name or caption+of the referenced item. The original link text is replaced once+the generated document is refreshed. This extension can be combined+with `xrefs_number` in which case numbers will appear before the+name.++Text in cross-references is only made consistent with the referenced+item once the document has been refreshed.++This extension can be enabled/disabled for the following formats:++output formats+: `odt`, `opendocument`++#### Extension: `xrefs_number` ####++Links to headings, figures and tables inside the document are+substituted with cross-references that will use the number+of the referenced item. The original link text is discarded.+This extension can be combined with `xrefs_name` in which case+the name or caption numbers will appear after the number.++For the `xrefs_number` to be useful heading numbers must be enabled+in the generated document, also table and figure captions must be enabled+using for example the `native_numbering` extension.++Numbers in cross-references are only visible in the final document once+it has been refreshed.++This extension can be enabled/disabled for the following formats:++output formats+: `odt`, `opendocument`+ #### Extension: `styles` #### {#ext-styles} When converting from docx, read all docx styles as divs (for@@ -5090,6 +5125,13 @@ [Project Gutenberg]: https://www.gutenberg.org +#### Extension: `sourcepos` ####++Include source position attributes when parsing `commonmark`.+For elements that accept attributes, a `data-pos` attribute+is added; other elements are placed in a surrounding+Div or Span elemnet with a `data-pos` attribute.+ ## Markdown variants In addition to pandoc's extended Markdown, the following Markdown@@ -5203,6 +5245,10 @@ URL: https://www.nature.com/articles/171737a0 language: en-GB ...++If both an external bibliography and inline (YAML metadata)+references are provided, both will be used. In case of+conflicting `id`s, the inline references will take precedence. Note that `pandoc` can be used to produce such a YAML metadata section from a BibTeX, BibLaTeX, or CSL JSON bibliography:
@@ -0,0 +1,22 @@+{-# LANGUAGE NoImplicitPrelude #-}+{- |+ Module : Main+ Copyright : Copyright (C) 2006-2020 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 Prelude+import qualified Control.Exception as E+import Text.Pandoc.App (convertWithOpts, defaultOpts, options, parseOptions)+import Text.Pandoc.Error (handleError)++main :: IO ()+main = E.catch (parseOptions options defaultOpts >>= convertWithOpts)+ (handleError . Left)
@@ -1,11 +1,12 @@ packages: pandoc.cabal +tests: True+ package pandoc flags: +embed_data_files -trypandoc ghc-options: -j +RTS -A64m -RTS -- source-repository-package--- type: git--- location: https://github.com/jgm/citeproc--- tag: 0.1.1.1-+-- type: git+-- location: https://github.com/jgm/citeproc+-- tag: a8193fe375fa2354049bf9a967ba3bad4b1ba053
@@ -1,5 +1,296 @@ # Revision history for pandoc +## pandoc 2.11.3 (2020-12-17)++ * With `--bibliography` (or `bibliography` in metadata), a+ URL may now be provided, and pandoc will fetch the resource.+ In addition, if a file path is provided and it is not+ found relative to the working directory, the resource+ path will be searched (#6940).++ * Add `sourcepos` extension for `commonmark`, `gfm`, `commonmark_x`+ (#4565). With the `sourcepos` extension set set, `data-pos`+ attributes are added to the AST by the commonmark reader. No other+ readers are affected. The `data-pos` attributes are put on elements+ that accept attributes; for other elements, an enlosing Div or Span+ is added to hold the attributes.++ * Change extensions for `commonmark_x`: replace `auto_identifiers`+ with `gfm_auto_identifiers` (#6863). `commonmark_x` never actually+ supported `auto_identifiers` (it didn't do anything), because the+ underlying library implements gfm-style identifiers only. Attempts+ to add the `auto_identifiers` extension to `commonmark` will now+ fail with an error.++ * HTML reader:++ + Split module into several submodules (Albert Krewinkel). Reducing+ module size should reduce memory use during compilation.+ + Support advanced table features (Albert Krewinkel):+ block level content in captions, row and colspans,+ body headers, row head columns, footers, attributes.+ + Disable round-trip testing for tables. Information for cell+ alignment in a column is not preserved during round-trips (Albert+ Krewinkel).+ + Allow finer grained options for tag omission (Albert Krewinkel).+ + Simplify list attribute handling (Albert Krewinkel).+ + Pay attention to `lang` attributes on body element (#6938).+ These (as well as `lang` attributes on the html element) should update+ lang in metadata.+ + Retain attribute prefixes and avoid duplicates (#6938).+ Previously we stripped attribute prefixes, reading `xml:lang` as+ `lang` for example. This resulted in two duplicate `lang`+ attributes when `xml:lang` and `lang` were both used. This commit+ causes the prefixes to be retained, and also avoids invald+ duplicate attributes.++ * Commonmark reader:++ + Refactor `specFor`.+ + Set input name to `""` to avoid clutter in sourcepos output.++ * Org reader:++ + Parse `#+LANGUAGE` into `lang` metadata field (#6845, Albert+ Krewinkel).+ + Preserve targets of spurious links (#6916, Albert+ Krewinkel). Links with (internal) targets that the reader doesn't+ know about are converted into emphasized text. Information on the+ link target is now preserved by wrapping the text in a Span of class+ `spurious-link`, with an attribute `target` set to the link's+ original target. This allows to recover and fix broken or unknown+ links with filters.++ * DocBook reader:++ + Table text width support (#6791, Nils Carlson).+ Table width in relation to text width is not natively supported+ by docbook but is by the docbook `fo` stylesheets through an XML+ processing instruction, `<?dbfo table-width="50%"?>`.++ * LaTeX reader:++ + Improve parsing of command options (#6869, #6873).+ In cases where we run into trouble parsing inlines til the+ closing `]`, e.g. quotes, we return a plain string with the+ option contents. Previously we mistakenly included the brackets+ in this string.+ + Preserve center environment (#6852, Igor Pashev).+ The contents of the `center` environment are put in a `Div`+ with class `center`.+ + Don't parse `\rule` with width 0 as horizontal rule. These are+ sometimes used as spacers in LaTeX.+ + Don't apply theorem default styling to a figure inside (#6925).+ If we put an image in italics, then when rendering to Markdown+ we no longer get an implicit figure.++ * Dokuwiki reader:++ + Handle unknown interwiki links better (#6932).+ DokuWiki lets the user define his own Interwiki links. Previously+ pandoc reacted to these by emitting a google search link, which is+ not helpful. Instead, we now just emit the full URL including the+ wikilink prefix, e.g. `faquk>FAQ-mathml`. This at least gives users+ the ability to modify the links using filters.++ * Markdown writer:++ + Properly handle boolean values in writing YAML metadata (#6388).+ + Ensure that a new csl-block begins on a new line (#6921).+ This just looks better and doesn't affect the semantics.++ * RST writer:++ + Better image handling (#6948). An image alone in its paragraph+ (but not a figure) is now rendered as an independent image, with an+ `alt` attribute if a description is supplied. An inline image that+ is not alone in its paragraph will be rendered, as before, using a+ substitution. Such an image cannot have a "center", "left", or+ "right" alignment, so the classes `align-center`, `align-left`, or+ `align-right` are ignored. However, `align-top`, `align-middle`,+ `align-bottom` will generate a corresponding `align` attribute.++ * Docx writer:++ + Keep raw openxml strings verbatim (#6933, Albert Krewinkel).+ + Use Content instead of Element. This allows us to inject+ raw OpenXML into the document without reparsing it into an+ Element, which is necessary if you want to inject an open+ tag or close tag.+ + Fix bullets/lists indentation, so that the first level is slightly+ indented to the right instead of right on the margin (cholonam).+ + Support bold and italic in "complex script" (#6911).+ Previously bold and italics didn't work properly in LTR+ text. This commit causes the w:bCs and w:iCs attributes+ to be used, in addition to w:b and w:i, for bold and+ italics respectively.++ * ICML writer:++ + Fix image bounding box for custom widths/heighta (Mauro Bieg, #6936).++ * LaTeX writer:++ + Improve table spacing (#6842, #6860).+ Remove the `\strut` that was added at the end of minipage+ environments in cells. Replace `\tabularnewline` with+ `\\ \addlinespace`.+ + Improve calculation of column spacing (#6883).+ + Extract table handling into separate module (Albert Krewinkel).+ + Fix bug with nested `csl-` display Spans (#6921).+ + Improve longtable output (#6883). Don't create minipages for+ regular paragraphs. Put width and alignment information in the+ longtable column descriptors.++ * OpenDocument writer:++ + Support for table width as a percentage of text width+ (#6792, Nils Carson).+ + Implement Div and Span ident support (#6755, Nils Carson).+ Spans and Divs containing an ident in the Attr will become bookmarks+ or sections with idents in OpenDocument format.+ + Add two extensions, `xrefs_name` and `xrefs_number` (#6774, Nils+ Carlson). Links to headings, figures and tables inside the+ document are substituted with cross-references that will use the+ name or caption of the referenced item for `xrefs_name` or the+ number for `xrefs_number`. For the `xrefs_number` to be useful+ heading numbers must be enabled in the generated document and+ table and figure captions must be enabled using for example the+ `native_numbering` extension. In order for numbers and reference+ text to be updated the generated document must be refreshed.++ * JATS writer:++ + Support advanced table features (Albert Krewinkel).+ + Support author affiliations (#6687, Albert Krewinkel).++ * Docbook writer:++ + Use correct id attribute consistently (Jan Tojnar).+ DocBook5 should always use `xml:id` instead of `id`.+ + Handle admonition titles better (Jan Tojnar).+ Docbook reader produces a `Div` with `title` class for `<title>`+ element within an “admonition” element. Markdown writer then turns+ this into a fenced div with `title` class attribute. Since fenced+ divs are block elements, their content is recognized as a+ paragraph by the Markdown reader. This is an issue for Docbook+ writer because it would produce an invalid DocBook document from+ such AST – the `<title>` element can only contain “inline”+ elements. Handle this special case separately by unwrapping+ the paragraph before creating the `<title>` element.+ + Add XML namespaces to top-level elements (#6923, Jan Tojnar).+ Previously, we only added `xmlns` attributes to chapter+ elements, even when running with `--top-level-division=section`.+ These namespaces are now added to part and section elements too,+ when they are the selected top-level divisions.+ We do not need to add namespaces to documents produced with+ `--standalone` flag, since those will already have xmlns attribute on+ the root element in the template.++ * HTML writer:++ + Fix handling of nested `csl-` display spans (#6921).+ Previously inner Spans used to represent CSL display attributes were+ not rendered as div tags as intended.++ * EPUB writer:++ + Include title page in landmarks (#6919).+ Note that the toc is also included if `--toc` is specified.+ + Add frontmatter type on body element for nav.xhtml (#6918).++ * EPUB templates: use preserveAspectRatio="xMidYMid" for cover image (#6895,+ Shin Sang-jae). This change affects both the epub2 and the epub3+ templates. It avoids distortion of the cover image by requiring that the+ aspect ratio be preserved.++ * LaTeX template:++ + Include `csquotes` package if `csquotes` variable set.+ + Put back `amssymb`. We need it for checkboxes in todo lists,+ and maybe for other things. In this location it seems compatible+ with the cases that prompted #6469 and PR #6762.+ + Disable language-specific shorthands in babel (#6817, #6887).+ Babel defines "shorthands" for some languages, and these can+ produce unexpected results. For example, in Spanish, `1.22`+ gets rendered as `122`, and `et~al.` as `etal`.+ One would think that babel's `shorthands=off` option (which+ we were using) would disable these, but it doesn't. So we+ remove `shorthands=off` and add some code that redefines+ the shorthands macro. Eventually this will be fixed in babel,+ I hope, and we can revert to something simpler.++ * JATS template: allow array of persistent institute ids in `pid`+ (Albert Krewinkel).++ * Text.Pandoc.Parsing: minor code and efficiency improvements.++ * Text.Pandoc.Extension:++ + Add `Ext_sourcepos` constructor for `Extension` [API change].+ + Add `Ext_xrefs_name` and `Ext_xrefs_number` constructors for+ `Extension` (Nils Carson) [API change].++ * Text.Pandoc.Citeproc:++ + Fix truncation of `[Citation]` list in `Cite` inside footnotes (#6890).+ This affected author-in-text citations in footnotes. It didn't cause+ problems for the printed output, but for filters that expected the+ citation id and other information.+ + Allow the use of both inline and external references (#6951),+ as with pandoc-citeproc. References defined in the document's+ metadata take priority over references with the same id defined in+ an external bibliography.+ + Use `fetchItem` to get external bibliography (#6940).+ + Ensure that BCP47 lang codes can be used. We ignore the variants+ and just use the base lang code and country code when passing off+ to citeproc.+ + Citeproc BibTeX parser: revert change in `getRawField`+ which was made (for reasons forgotten) when transferring+ this code from pandoc-citeproc. The change led to `--` in+ URLs being interpreted as en-dashes, which is unwanted (#6874).++ * Text.Pandoc.ImageSize:++ + Default to DPI 72 if the format specifies DPI of 0 (#6880).+ This shouldn't happen, in general, but it can happen with+ JPEGs that don't conform to the spec. Having a DPI of 0+ will blow up size calculations (division by 0).+ + ImageSize: use JuicyPixels to determine size for png, jpeg, and+ gif, instead of doing our own binary parsing (#6936). This+ gives more reliable results.++ * Text.Pandoc.CSS:++ + Remove `foldOrElse` (internal module) (Albert Krewinkel).++ * Use skylighting 0.10.2 (#6625).++ * Use citeproc 0.3. This fixes issues with references with+ duplicate ids (jgm/citeproc#36).++ * Use doctemplates 0.9. This fixes issues with boolean+ metadata values in the Markdown writer (#6388)+ and in `meta-json` (#6650). It also fixes+ issues with nested for loops in templates.++ * Add translations zh-Hans.yaml and zh-Hant.yaml (#6904, #6909,+ Kolen Cheung, taotieren).++ * Add tests: True to cabal.project.+ This fixes some CI failures for cabal.++ * Normalize test/tables/*.native (#6888, Kolen Cheung).++ * Move executable to `app` directory to avoid problems with cabal repl.++ * CONTRIBUTING: add section "How can I help?" (#6892, Albert Krewinkel).+ Also adds a paragraph aimed at highlighting the importance of feature+ maintenance.++ * MANUAL: Document that --number-sections works in `ms` (#6935).++ ## pandoc 2.11.2 (2020-11-19) * Default to using ATX (`##`-style) headings for Markdown output
@@ -101,14 +101,15 @@ $if(author.email)$ <email>$author.email$</email> $endif$-$if(author.aff-id)$-<xref ref-type="aff" rid="aff-$contrib.aff-id$"/>-$endif$+$for(author.affiliation)$+<xref ref-type="aff" rid="aff-$author.affiliation$"/>+$endfor$ $if(author.cor-id)$ <xref ref-type="corresp" rid="cor-$author.cor-id$"><sup>*</sup></xref> $endif$ </contrib> $endfor$+${ affiliations.jats() } </contrib-group> $endif$ $if(article.author-notes)$
@@ -48,7 +48,7 @@ $else$ $if(coverpage)$ <div id="cover-image">-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" viewBox="0 0 $cover-image-width$ $cover-image-height$" preserveAspectRatio="none">+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" viewBox="0 0 $cover-image-width$ $cover-image-height$" preserveAspectRatio="xMidYMid"> <image width="$cover-image-width$" height="$cover-image-height$" xlink:href="../media/$cover-image$" /> </svg> </div>
@@ -49,7 +49,7 @@ $else$ $if(coverpage)$ <div id="cover-image">-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" viewBox="0 0 $cover-image-width$ $cover-image-height$" preserveAspectRatio="none">+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" viewBox="0 0 $cover-image-width$ $cover-image-height$" preserveAspectRatio="xMidYMid"> <image width="$cover-image-width$" height="$cover-image-height$" xlink:href="../media/$cover-image$" /> </svg> </div>
@@ -34,14 +34,15 @@ $if(author.email)$ <email>$author.email$</email> $endif$-$if(author.aff-id)$-<xref ref-type="aff" rid="aff-$contrib.aff-id$"/>-$endif$+$for(author.affiliation)$+<xref ref-type="aff" rid="aff-$author.affiliation$"/>+$endfor$ $if(author.cor-id)$ <xref ref-type="corresp" rid="cor-$author.cor-id$"><sup>*</sup></xref> $endif$ </contrib> $endfor$+${ affiliations.jats() } </contrib-group> $endif$ $if(copyright)$
@@ -89,6 +89,7 @@ $if(beamerarticle)$ \usepackage{beamerarticle} % needs to be loaded first $endif$+\usepackage{amsmath,amssymb} $if(fontfamily)$ \usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$} $else$@@ -97,17 +98,14 @@ $if(linestretch)$ \usepackage{setspace} $endif$-\usepackage{amsmath} \usepackage{ifxetex,ifluatex} \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc} \usepackage[utf8]{inputenc} \usepackage{textcomp} % provide euro and other symbols- \usepackage{amssymb} \else % if luatex or xetex $if(mathspec)$ \ifxetex- \usepackage{amssymb} \usepackage{mathspec} \else \usepackage{unicode-math}@@ -256,7 +254,7 @@ $highlighting-macros$ $endif$ $if(tables)$-\usepackage{longtable,booktabs}+\usepackage{longtable,booktabs,array} \usepackage{calc} % for calculating minipage widths $if(beamer)$ \usepackage{caption}@@ -336,7 +334,10 @@ \setotherlanguage[$for(polyglossia-otherlangs.options)$$polyglossia-otherlangs.options$$sep$,$endfor$]{$polyglossia-otherlangs.name$} $endfor$ \else- \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel}+ \usepackage[$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel}+% get rid of language-specific shorthands (see #6817):+\let\LanguageShortHands\languageshorthands+\def\languageshorthands#1{} $if(babel-newcommands)$ $babel-newcommands$ $endif$@@ -389,6 +390,9 @@ \newcommand{\CSLLeftMargin}[1]{\parbox[t]{\csllabelwidth}{#1}} \newcommand{\CSLRightInline}[1]{\parbox[t]{\linewidth - \csllabelwidth}{#1}\break} \newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1}+$endif$+$if(csquotes)$+\usepackage{csquotes} $endif$ $if(title)$
@@ -0,0 +1,22 @@+Abstract: 摘要+Appendix: 附录+Bibliography: 文献目录+Cc: 副本+Chapter: 章+Contents: 目录+Encl: 附件+Figure: 图+Glossary: 术语+Index: 索引+Listing: 列表+ListOfFigures: 附图目录+ListOfTables: 表格索引+Page: 页+Part: 段+Preface: 序+Proof: 校对+References: 参考文献+See: 见+SeeAlso: 参见+Table: 表+To: 到
@@ -0,0 +1,22 @@+Abstract: 摘要+Appendix: 附錄+Bibliography: 文獻目錄+Cc: 副本+Chapter: 章+Contents: 目錄+Encl: 附件+Figure: 圖+Glossary: 術語+Index: 索引+Listing: 列表+ListOfFigures: 附圖目錄+ListOfTables: 表格索引+Page: 頁+Part: 段+Preface: 序+Proof: 校對+References: 參考文獻+See: 見+SeeAlso: 參見+Table: 表+To: 到
@@ -1,7 +1,7 @@ '\" t-.\" Automatically generated by Pandoc 2.11.2+.\" Automatically generated by Pandoc 2.11.3 .\"-.TH "Pandoc User\[cq]s Guide" "" "November 19, 2020" "pandoc 2.11.2" ""+.TH "Pandoc User\[cq]s Guide" "" "December 17, 2020" "pandoc 2.11.3" "" .hy .SH NAME pandoc - general markup converter@@ -933,13 +933,6 @@ directory must be explicitly listed or it will not be searched. For example: \f[C]--resource-path=.:test\f[R] will search the working directory and the \f[C]test\f[R] subdirectory, in that order.-.RS-.PP-\f[C]--resource-path\f[R] only has an effect if (a) the output format-embeds images (for example, \f[C]docx\f[R], \f[C]pdf\f[R], or-\f[C]html\f[R] with \f[C]--self-contained\f[R]) or (b) it is used-together with \f[C]--extract-media\f[R].-.RE .TP \f[B]\f[CB]--request-header=\f[B]\f[R]\f[I]NAME\f[R]\f[B]\f[CB]:\f[B]\f[R]\f[I]VAL\f[R] Set the request header \f[I]NAME\f[R] to the value \f[I]VAL\f[R] when@@ -1034,7 +1027,8 @@ their default type. .TP \f[B]\f[CB]-N\f[B]\f[R], \f[B]\f[CB]--number-sections\f[B]\f[R]-Number section headings in LaTeX, ConTeXt, HTML, Docx, or EPUB output.+Number section headings in LaTeX, ConTeXt, HTML, Docx, ms, or EPUB+output. By default, sections are not numbered. Sections with class \f[C]unnumbered\f[R] will never be numbered, even if \f[C]--number-sections\f[R] is specified.@@ -1426,6 +1420,9 @@ \f[I]FILE\f[R], overriding any value set in the metadata. If you supply this argument multiple times, each \f[I]FILE\f[R] will be added to bibliography.+If \f[I]FILE\f[R] is a URL, it will be fetched via HTTP.+If \f[I]FILE\f[R] is not found relative to the working directory, it+will be sought in the resource path (see \f[C]--resource-path\f[R]). .TP \f[B]\f[CB]--csl=\f[B]\f[R]\f[I]FILE\f[R] Set the \f[C]csl\f[R] field in the document\[cq]s metadata to@@ -1433,8 +1430,9 @@ (This is equivalent to \f[C]--metadata csl=FILE\f[R].) If \f[I]FILE\f[R] is a URL, it will be fetched via HTTP. If \f[I]FILE\f[R] is not found relative to the working directory, it-will be sought in the resource path and finally in the \f[C]csl\f[R]-subdirectory of the pandoc user data directory.+will be sought in the resource path (see \f[C]--resource-path\f[R]) and+finally in the \f[C]csl\f[R] subdirectory of the pandoc user data+directory. .TP \f[B]\f[CB]--citation-abbreviations=\f[B]\f[R]\f[I]FILE\f[R] Set the \f[C]citation-abbreviations\f[R] field in the document\[cq]s@@ -1443,8 +1441,9 @@ \f[C]--metadata citation-abbreviations=FILE\f[R].) If \f[I]FILE\f[R] is a URL, it will be fetched via HTTP. If \f[I]FILE\f[R] is not found relative to the working directory, it-will be sought in the resource path and finally in the \f[C]csl\f[R]-subdirectory of the pandoc user data directory.+will be sought in the resource path (see \f[C]--resource-path\f[R]) and+finally in the \f[C]csl\f[R] subdirectory of the pandoc user data+directory. .TP \f[B]\f[CB]--natbib\f[B]\f[R] Use \f[C]natbib\f[R] for citations in LaTeX output.@@ -3376,6 +3375,43 @@ .TP output formats \f[C]odt\f[R], \f[C]opendocument\f[R]+.SS Extension: \f[C]xrefs_name\f[R]+.PP+Links to headings, figures and tables inside the document are+substituted with cross-references that will use the name or caption of+the referenced item.+The original link text is replaced once the generated document is+refreshed.+This extension can be combined with \f[C]xrefs_number\f[R] in which case+numbers will appear before the name.+.PP+Text in cross-references is only made consistent with the referenced+item once the document has been refreshed.+.PP+This extension can be enabled/disabled for the following formats:+.TP+output formats+\f[C]odt\f[R], \f[C]opendocument\f[R]+.SS Extension: \f[C]xrefs_number\f[R]+.PP+Links to headings, figures and tables inside the document are+substituted with cross-references that will use the number of the+referenced item.+The original link text is discarded.+This extension can be combined with \f[C]xrefs_name\f[R] in which case+the name or caption numbers will appear after the number.+.PP+For the \f[C]xrefs_number\f[R] to be useful heading numbers must be+enabled in the generated document, also table and figure captions must+be enabled using for example the \f[C]native_numbering\f[R] extension.+.PP+Numbers in cross-references are only visible in the final document once+it has been refreshed.+.PP+This extension can be enabled/disabled for the following formats:+.TP+output formats+\f[C]odt\f[R], \f[C]opendocument\f[R] .SS Extension: \f[C]styles\f[R] .PP When converting from docx, read all docx styles as divs (for paragraph@@ -5920,6 +5956,12 @@ Use Project Gutenberg conventions for \f[C]plain\f[R] output: all-caps for strong emphasis, surround by underscores for regular emphasis, add extra blank space around headings.+.SS Extension: \f[C]sourcepos\f[R]+.PP+Include source position attributes when parsing \f[C]commonmark\f[R].+For elements that accept attributes, a \f[C]data-pos\f[R] attribute is+added; other elements are placed in a surrounding Div or Span elemnet+with a \f[C]data-pos\f[R] attribute. .SS Markdown variants .PP In addition to pandoc\[cq]s extended Markdown, the following Markdown@@ -6078,6 +6120,11 @@ \&... \f[R] .fi+.PP+If both an external bibliography and inline (YAML metadata) references+are provided, both will be used.+In case of conflicting \f[C]id\f[R]s, the inline references will take+precedence. .PP Note that \f[C]pandoc\f[R] can be used to produce such a YAML metadata section from a BibTeX, BibLaTeX, or CSL JSON bibliography:
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: pandoc-version: 2.11.2+version: 2.11.3 build-type: Simple license: GPL-2.0-or-later license-file: COPYING.md@@ -395,12 +395,12 @@ aeson-pretty >= 0.8.5 && < 0.9, attoparsec >= 0.12 && < 0.14, base64-bytestring >= 0.1 && < 1.2,- binary >= 0.5 && < 0.11,+ binary >= 0.7 && < 0.11, blaze-html >= 0.9 && < 0.10, blaze-markup >= 0.8 && < 0.9, bytestring >= 0.9 && < 0.12, case-insensitive >= 1.2 && < 1.3,- citeproc >= 0.2 && < 0.3,+ citeproc >= 0.3 && < 0.4, commonmark >= 0.1.1.2 && < 0.2, commonmark-extensions >= 0.2.0.4 && < 0.3, commonmark-pandoc >= 0.2 && < 0.3,@@ -410,7 +410,7 @@ deepseq >= 1.3 && < 1.5, directory >= 1.2.3 && < 1.4, doclayout >= 0.3 && < 0.4,- doctemplates >= 0.8.2 && < 0.9,+ doctemplates >= 0.9 && < 0.10, emojis >= 0.1 && < 0.2, exceptions >= 0.8 && < 0.11, file-embed >= 0.0 && < 0.1,@@ -433,8 +433,8 @@ random >= 1 && < 1.2, safe >= 0.3 && < 0.4, scientific >= 0.3 && < 0.4,- skylighting >= 0.10 && < 0.11,- skylighting-core >= 0.10 && < 0.11,+ skylighting >= 0.10.2 && < 0.11,+ skylighting-core >= 0.10.2 && < 0.11, split >= 0.2 && < 0.3, syb >= 0.1 && < 0.8, tagsoup >= 0.14.6 && < 0.15,@@ -477,7 +477,6 @@ if impl(ghc >= 8.4) ghc-options: -Wincomplete-uni-patterns -Widentities- -Werror=missing-home-modules -fhide-source-paths default-language: Haskell2010@@ -599,6 +598,10 @@ Text.Pandoc.Readers.Docx.Parse.Styles, Text.Pandoc.Readers.Docx.Util, Text.Pandoc.Readers.Docx.Fields,+ Text.Pandoc.Readers.HTML.Parsing,+ Text.Pandoc.Readers.HTML.Table,+ Text.Pandoc.Readers.HTML.TagCategories,+ Text.Pandoc.Readers.HTML.Types, Text.Pandoc.Readers.LaTeX.Parsing, Text.Pandoc.Readers.LaTeX.Lang, Text.Pandoc.Readers.LaTeX.SIunitx,@@ -627,6 +630,10 @@ Text.Pandoc.Writers.Docx.StyleMap, Text.Pandoc.Writers.JATS.Table, Text.Pandoc.Writers.JATS.Types,+ Text.Pandoc.Writers.LaTeX.Caption,+ Text.Pandoc.Writers.LaTeX.Notes,+ Text.Pandoc.Writers.LaTeX.Table,+ Text.Pandoc.Writers.LaTeX.Types, Text.Pandoc.Writers.Roff, Text.Pandoc.Writers.Powerpoint.Presentation, Text.Pandoc.Writers.Powerpoint.Output,@@ -679,7 +686,7 @@ build-depends: base-compat >= 0.9 default-language: Haskell2010 other-extensions: NoImplicitPrelude- hs-source-dirs: .+ hs-source-dirs: app main-is: pandoc.hs buildable: True other-modules: Paths_pandoc@@ -692,7 +699,6 @@ if impl(ghc >= 8.4) ghc-options: -Wincomplete-uni-patterns -Widentities- -Werror=missing-home-modules -fhide-source-paths executable trypandoc@@ -719,7 +725,6 @@ if impl(ghc >= 8.4) ghc-options: -Wincomplete-uni-patterns -Widentities- -Werror=missing-home-modules -fhide-source-paths benchmark weigh-pandoc@@ -746,7 +751,6 @@ if impl(ghc >= 8.4) ghc-options: -Wincomplete-uni-patterns -Widentities- -Werror=missing-home-modules -fhide-source-paths @@ -763,7 +767,7 @@ bytestring >= 0.9 && < 0.12, containers >= 0.4.2.1 && < 0.7, directory >= 1.2.3 && < 1.4,- doctemplates >= 0.8.2 && < 0.9,+ doctemplates >= 0.9 && < 0.10, exceptions >= 0.8 && < 0.11, executable-path >= 0.0 && < 0.1, filepath >= 1.1 && < 1.5,@@ -853,7 +857,6 @@ if impl(ghc >= 8.4) ghc-options: -Wincomplete-uni-patterns -Widentities- -Werror=missing-home-modules -fhide-source-paths @@ -884,5 +887,4 @@ if impl(ghc >= 8.4) ghc-options: -Wincomplete-uni-patterns -Widentities- -Werror=missing-home-modules -fhide-source-paths
@@ -1,22 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{- |- Module : Main- Copyright : Copyright (C) 2006-2020 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 Prelude-import qualified Control.Exception as E-import Text.Pandoc.App (convertWithOpts, defaultOpts, options, parseOptions)-import Text.Pandoc.Error (handleError)--main :: IO ()-main = E.catch (parseOptions options defaultOpts >>= convertWithOpts)- (handleError . Left)
@@ -23,8 +23,8 @@ , applyFilters ) where import qualified Control.Exception as E-import Control.Monad-import Control.Monad.Trans+import Control.Monad ( (>=>), when )+import Control.Monad.Trans ( MonadIO(..) ) import Control.Monad.Except (throwError) import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as BL@@ -40,7 +40,7 @@ import Network.URI (URI (..), parseURI) import System.Directory (doesDirectoryExist) import System.Exit (exitSuccess)-import System.FilePath+import System.FilePath ( takeBaseName, takeExtension ) import System.IO (nativeNewline, stdout) import qualified System.IO as IO (Newline (..)) import Text.Pandoc
@@ -11,47 +11,46 @@ Tools for working with CSS. -}-module Text.Pandoc.CSS ( foldOrElse- , pickStyleAttrProps- , pickStylesToKVs- )+module Text.Pandoc.CSS+ ( cssAttributes+ , pickStyleAttrProps+ , pickStylesToKVs+ ) where -import qualified Data.Text as T+import Data.Maybe (mapMaybe, listToMaybe)+import Data.Text (Text, pack) import Text.Pandoc.Shared (trim) import Text.Parsec import Text.Parsec.Text -ruleParser :: Parser (T.Text, T.Text)+ruleParser :: Parser (Text, Text) ruleParser = do p <- many1 (noneOf ":") <* char ':' v <- many1 (noneOf ":;") <* optional (char ';') <* spaces- return (trim $ T.pack p, trim $ T.pack v)+ return (trim $ pack p, trim $ pack v) -styleAttrParser :: Parser [(T.Text, T.Text)]+styleAttrParser :: Parser [(Text, Text)] styleAttrParser = many1 ruleParser -orElse :: Eq a => a -> a -> a -> a-orElse v x y = if v == x then y else x--foldOrElse :: Eq a => a -> [a] -> a-foldOrElse v xs = foldr (orElse v) v xs--eitherToMaybe :: Either a b -> Maybe b-eitherToMaybe (Right x) = Just x-eitherToMaybe _ = Nothing+-- | Parses a style string, returning the CSS attributes.+-- Returns an empty list on failure.+cssAttributes :: Text -> [(Text, Text)]+cssAttributes styleString =+ -- Use Data.Either.fromRight once GHC 8.0 is no longer supported+ case parse styleAttrParser "" styleString of+ Left _ -> []+ Right x -> x -- | takes a list of keys/properties and a CSS string and -- returns the corresponding key-value-pairs.-pickStylesToKVs :: [T.Text] -> T.Text -> [(T.Text, T.Text)]+pickStylesToKVs :: [Text] -> Text -> [(Text, Text)] pickStylesToKVs props styleAttr =- case parse styleAttrParser "" styleAttr of- Left _ -> []- Right styles -> filter (\s -> fst s `elem` props) styles+ filter (\s -> fst s `elem` props) $ cssAttributes styleAttr -- | takes a list of key/property synonyms and a CSS string and maybe -- returns the value of the first match (in order of the supplied list)-pickStyleAttrProps :: [T.Text] -> T.Text -> Maybe T.Text+pickStyleAttrProps :: [Text] -> Text -> Maybe Text pickStyleAttrProps lookupProps styleAttr = do- styles <- eitherToMaybe $ parse styleAttrParser "" styleAttr- foldOrElse Nothing $ map (`lookup` styles) lookupProps+ styles <- either (const Nothing) Just $ parse styleAttrParser "" styleAttr+ listToMaybe $ mapMaybe (`lookup` styles) lookupProps
@@ -16,6 +16,7 @@ import Text.Pandoc.Citeproc.MetaValue (metaValueToReference, metaValueToText) import Text.Pandoc.Readers.Markdown (yamlToRefs) import Text.Pandoc.Class (setResourcePath, getResourcePath, getUserDataDir)+import qualified Text.Pandoc.BCP47 as BCP47 import Data.ByteString (ByteString) import qualified Data.ByteString.Lazy as L import Text.Pandoc.Definition as Pandoc@@ -91,8 +92,9 @@ case styleRes of Left err -> throwError $ PandocAppError $ prettyCiteprocError err Right style -> return style{ styleAbbreviations = mbAbbrevs }- let mblang = parseLang <$>- ((lookupMeta "lang" meta <|> lookupMeta "locale" meta) >>= metaValueToText)+ mblang <- maybe (return Nothing) bcp47LangToIETF+ ((lookupMeta "lang" meta <|> lookupMeta "locale" meta) >>=+ metaValueToText) let locale = Citeproc.mergeLocales mblang style let getCiteId (Cite cs _) = Set.fromList $ map B.citationId cs getCiteId _ = mempty@@ -103,20 +105,22 @@ let idpred = if "*" `Set.member` nocites then const True else (`Set.member` citeIds)- refs <- map (linkifyVariables . legacyDateRanges) <$>- case lookupMeta "references" meta of- Just (MetaList rs) -> return $ mapMaybe metaValueToReference rs- _ ->- case lookupMeta "bibliography" meta of- Just (MetaList xs) ->- mconcat <$>- mapM (getRefsFromBib locale idpred)- (mapMaybe metaValueToText xs)- Just x ->- case metaValueToText x of- Just fp -> getRefsFromBib locale idpred fp- Nothing -> return []- Nothing -> return []+ let inlineRefs = case lookupMeta "references" meta of+ Just (MetaList rs) -> mapMaybe metaValueToReference rs+ _ -> []+ externalRefs <- case lookupMeta "bibliography" meta of+ Just (MetaList xs) ->+ mconcat <$>+ mapM (getRefsFromBib locale idpred)+ (mapMaybe metaValueToText xs)+ Just x ->+ case metaValueToText x of+ Just fp -> getRefsFromBib locale idpred fp+ Nothing -> return []+ Nothing -> return []+ let refs = map (linkifyVariables . legacyDateRanges)+ (externalRefs ++ inlineRefs)+ -- note that inlineRefs can override externalRefs let otherIdsMap = foldr (\ref m -> case T.words . extractText <$> M.lookup "other-ids"@@ -187,24 +191,23 @@ getRefsFromBib :: PandocMonad m => Locale -> (Text -> Bool) -> Text -> m [Reference Inlines]-getRefsFromBib locale idpred t = do- let fp = T.unpack t- raw <- readFileStrict fp- case formatFromExtension fp of+getRefsFromBib locale idpred fp = do+ (raw, _) <- fetchItem fp+ case formatFromExtension (T.unpack fp) of Just f -> getRefs locale f idpred (Just fp) raw Nothing -> throwError $ PandocAppError $- "Could not determine bibliography format for " <> t+ "Could not determine bibliography format for " <> fp getRefs :: PandocMonad m => Locale -> BibFormat -> (Text -> Bool)- -> Maybe FilePath+ -> Maybe Text -> ByteString -> m [Reference Inlines] getRefs locale format idpred mbfp raw = do let err' = throwError .- PandocBibliographyError (maybe mempty T.pack mbfp)+ PandocBibliographyError (fromMaybe mempty mbfp) case format of Format_bibtex -> either (err' . tshow) return .@@ -219,7 +222,7 @@ Format_yaml -> do rs <- yamlToRefs idpred def{ readerExtensions = pandocExtensions }- mbfp+ (T.unpack <$> mbfp) (L.fromStrict raw) return $ mapMaybe metaValueToReference rs @@ -527,9 +530,9 @@ go [] = [] go (Cite (c:cs) ils : zs) | citationMode c == AuthorInText- = Cite cs (concatMap (noteAfterComma (needsPeriod zs)) ils) : go zs+ = Cite (c:cs) (concatMap (noteAfterComma (needsPeriod zs)) ils) : go zs | otherwise- = Cite cs (concatMap noteInParens ils) : go zs+ = Cite (c:cs) (concatMap noteInParens ils) : go zs go (x:xs) = x : go xs needsPeriod [] = True needsPeriod (Str t:_) = case T.uncons t of@@ -579,3 +582,16 @@ isRightQuote "\8217" = True isRightQuote "\187" = True isRightQuote _ = False++bcp47LangToIETF :: PandocMonad m => Text -> m (Maybe Lang)+bcp47LangToIETF bcplang =+ case BCP47.parseBCP47 bcplang of+ Left _ -> do+ report $ InvalidLang bcplang+ return Nothing+ Right lang ->+ return $ Just+ $ Lang (BCP47.langLanguage lang)+ (if T.null (BCP47.langRegion lang)+ then Nothing+ else Just (BCP47.langRegion lang))
@@ -601,7 +601,7 @@ inBraces = do char '{' res <- manyTill- ( (T.pack <$> many1 (noneOf "{}\\"))+ ( take1WhileP (\c -> c /= '{' && c /= '}' && c /= '\\') <|> (char '\\' >> ( (char '{' >> return "\\{") <|> (char '}' >> return "\\}") <|> return "\\"))@@ -616,7 +616,7 @@ inQuotes = do char '"' T.concat <$> manyTill- ( (T.pack <$> many1 (noneOf "\"\\{"))+ ( take1WhileP (\c -> c /= '{' && c /= '"' && c /= '\\') <|> (char '\\' >> T.cons '\\' . T.singleton <$> anyChar) <|> braced <$> inBraces ) (char '"')@@ -822,12 +822,11 @@ , dateLiteral = literal } getRawField :: Text -> Bib Text-getRawField f =- (stringify <$> getField f)- <|> do fs <- asks fields- case Map.lookup f fs of- Just x -> return x- Nothing -> notFound f+getRawField f = do+ fs <- asks fields+ case Map.lookup f fs of+ Just x -> return x+ Nothing -> notFound f getLiteralList :: Text -> Bib [Inlines] getLiteralList f = do
@@ -149,9 +149,12 @@ | Ext_tex_math_dollars -- ^ TeX math between $..$ or $$..$$ | Ext_tex_math_double_backslash -- ^ TeX math btw \\(..\\) \\[..\\] | Ext_tex_math_single_backslash -- ^ TeX math btw \(..\) \[..\]+ | Ext_xrefs_name -- ^ Use xrefs with names+ | Ext_xrefs_number -- ^ Use xrefs with numbers | Ext_yaml_metadata_block -- ^ YAML metadata block | Ext_gutenberg -- ^ Use Project Gutenberg conventions for plain | Ext_attributes -- ^ Generic attribute syntax+ | Ext_sourcepos -- ^ Include source position attributes deriving (Show, Read, Enum, Eq, Ord, Bounded, Data, Typeable, Generic) -- | Extensions to be used with pandoc-flavored markdown.@@ -355,7 +358,7 @@ getDefaultExtensions "commonmark_x" = extensionsFromList [ Ext_pipe_tables , Ext_raw_html- , Ext_auto_identifiers+ , Ext_gfm_auto_identifiers , Ext_strikeout , Ext_task_lists , Ext_emoji@@ -465,6 +468,8 @@ getAll "opendocument" = extensionsFromList [ Ext_empty_paragraphs , Ext_native_numbering+ , Ext_xrefs_name+ , Ext_xrefs_number ] getAll "odt" = getAll "opendocument" <> autoIdExtensions getAll "muse" = autoIdExtensions <>@@ -474,9 +479,10 @@ getAll "plain" = allMarkdownExtensions getAll "gfm" = getAll "commonmark" getAll "commonmark" =- autoIdExtensions <> extensionsFromList- [ Ext_pipe_tables+ [ Ext_gfm_auto_identifiers+ , Ext_ascii_identifiers+ , Ext_pipe_tables , Ext_autolink_bare_uris , Ext_strikeout , Ext_task_lists@@ -498,6 +504,7 @@ , Ext_implicit_header_references , Ext_attributes , Ext_fenced_code_attributes+ , Ext_sourcepos ] getAll "commonmark_x" = getAll "commonmark" getAll "org" = autoIdExtensions <>
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, CPP #-}+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-} {-# LANGUAGE ViewPatterns #-} {-# OPTIONS_GHC -fno-warn-type-defaults #-} {- |@@ -32,14 +32,12 @@ , showInPixel , showFl ) where-import Data.ByteString (ByteString, unpack)+import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Lazy as BL+import Data.Binary.Get import Data.Char (isDigit) import Control.Monad-import Data.Bits-import Data.Binary-import Data.Binary.Get import Text.Pandoc.Shared (safeRead) import Data.Default (Default) import Numeric (showFFloat)@@ -47,13 +45,13 @@ import Text.Pandoc.Options import qualified Text.Pandoc.UTF8 as UTF8 import qualified Text.XML.Light as Xml-import qualified Data.Map as M import qualified Data.Text as T import qualified Data.Text.Encoding as TE-import Control.Monad.Except import Control.Applicative-import Data.Maybe (fromMaybe) import qualified Data.Attoparsec.ByteString.Char8 as A+import qualified Codec.Picture.Metadata as Metadata+import qualified Codec.Picture.Metadata.Exif as Exif+import Codec.Picture (decodeImageWithMetadata) -- quick and dirty functions to get image sizes -- algorithms borrowed from wwwis.pl@@ -120,11 +118,11 @@ findSvgTag img = "<svg" `B.isInfixOf` img || "<SVG" `B.isInfixOf` img imageSize :: WriterOptions -> ByteString -> Either T.Text ImageSize-imageSize opts img =+imageSize opts img = checkDpi <$> case imageType img of- Just Png -> mbToEither "could not determine PNG size" $ pngSize img- Just Gif -> mbToEither "could not determine GIF size" $ gifSize img- Just Jpeg -> jpegSize img+ Just Png -> getSize img+ Just Gif -> getSize img+ Just Jpeg -> getSize img Just Svg -> mbToEither "could not determine SVG size" $ svgSize opts img Just Eps -> mbToEither "could not determine EPS size" $ epsSize img Just Pdf -> mbToEither "could not determine PDF size" $ pdfSize img@@ -132,9 +130,12 @@ Nothing -> Left "could not determine image type" where mbToEither msg Nothing = Left msg mbToEither _ (Just x) = Right x+ -- see #6880, some defective JPEGs may encode dpi 0, so default to 72+ -- if that value is 0+ checkDpi size =+ size{ dpiX = if dpiX size == 0 then 72 else dpiX size+ , dpiY = if dpiY size == 0 then 72 else dpiY size } -defaultSize :: (Integer, Integer)-defaultSize = (72, 72) sizeInPixels :: ImageSize -> (Integer, Integer) sizeInPixels s = (pxX s, pxY s)@@ -294,50 +295,36 @@ , dpiY = 72 } ) <|> pPdfSize -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)- _ -> Nothing -- "PNG parse error"- (dpix, dpiy) <- findpHYs rest''- return ImageSize { pxX = x, pxY = y, dpiX = dpix, dpiY = dpiy }+getSize :: ByteString -> Either T.Text ImageSize+getSize img =+ case decodeImageWithMetadata img of+ Left e -> Left (T.pack e)+ Right (_, meta) -> do+ pxx <- maybe (Left "Could not determine width") Right $+ -- first look for exif image width, then width+ (Metadata.lookup+ (Metadata.Exif (Exif.TagUnknown 0xA002)) meta >>=+ exifDataToWord) <|>+ Metadata.lookup Metadata.Width meta+ pxy <- maybe (Left "Could not determine height") Right $+ -- first look for exif image height, then height+ (Metadata.lookup+ (Metadata.Exif (Exif.TagUnknown 0xA003)) meta >>=+ exifDataToWord) <|>+ Metadata.lookup Metadata.Height meta+ dpix <- maybe (Right 72) Right $ Metadata.lookup Metadata.DpiX meta+ dpiy <- maybe (Right 72) Right $ Metadata.lookup Metadata.DpiY meta+ return $ ImageSize+ { pxX = fromIntegral pxx+ , pxY = fromIntegral pxy+ , dpiX = fromIntegral dpix+ , dpiY = fromIntegral dpiy }+ where+ exifDataToWord (Exif.ExifLong x) = Just $ fromIntegral x+ exifDataToWord (Exif.ExifShort x) = Just $ fromIntegral x+ exifDataToWord _ = Nothing -findpHYs :: ByteString -> Maybe (Integer, Integer)-findpHYs x- | B.null x || "IDAT" `B.isPrefixOf` x = return (72,72)- | "pHYs" `B.isPrefixOf` x =- case map fromIntegral $ unpack $ B.take 9 $ B.drop 4 x of- [x1,x2,x3,x4,y1,y2,y3,y4,u] -> do- let factor = if u == 1 -- dots per meter- then \z -> z * 254 `div` 10000- else const 72- return- ( factor $ shift x1 24 + shift x2 16 + shift x3 8 + x4,- factor $ shift y1 24 + shift y2 16 + shift y3 8 + y4 )- _ -> mzero- | otherwise = 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- }- _ -> Nothing -- "GIF parse error"- svgSize :: WriterOptions -> ByteString -> Maybe ImageSize svgSize opts img = do doc <- Xml.parseXMLDoc $ UTF8.toString img@@ -384,280 +371,3 @@ case parseheader . BL.fromStrict $ img of Left _ -> Nothing Right (_, _, size) -> Just size---jpegSize :: ByteString -> Either T.Text ImageSize-jpegSize img =- let (hdr, rest) = B.splitAt 4 img- in if B.length rest < 14- then Left "unable to determine JPEG size"- else case hdr of- "\xff\xd8\xff\xe0" -> jfifSize rest- "\xff\xd8\xff\xe1" -> exifSize rest- _ -> Left "unable to determine JPEG size"--jfifSize :: ByteString -> Either T.Text ImageSize-jfifSize rest =- case map fromIntegral $ unpack $ B.take 5 $ B.drop 9 rest of- [dpiDensity,dpix1,dpix2,dpiy1,dpiy2] ->- let factor = case dpiDensity of- 1 -> id- 2 -> \x -> x * 254 `div` 10- _ -> const 72- dpix = factor (shift dpix1 8 + dpix2)- dpiy = factor (shift dpiy1 8 + dpiy2)- in case findJfifSize rest of- Left msg -> Left msg- Right (w,h) -> Right ImageSize { pxX = w- , pxY = h- , dpiX = dpix- , dpiY = dpiy }- _ -> Left "unable to determine JFIF size"--findJfifSize :: ByteString -> Either T.Text (Integer,Integer)-findJfifSize bs =- let bs' = B.dropWhile (=='\xff') $ B.dropWhile (/='\xff') bs- in case B.uncons bs' of- Just (c,bs'') | c >= '\xc0' && c <= '\xc3' ->- case map fromIntegral $ unpack $ B.take 4 $ B.drop 3 bs'' of- [h1,h2,w1,w2] -> Right (shift w1 8 + w2, shift h1 8 + h2)- _ -> Left "JFIF parse error"- Just (_,bs'') ->- case map fromIntegral $ unpack $ B.take 2 bs'' of- [c1,c2] ->- let len = shift c1 8 + c2- -- skip variables- in findJfifSize $ B.drop len bs''- _ -> Left "JFIF parse error"- Nothing -> Left "Did not find JFIF length record"--runGet' :: Get (Either T.Text a) -> BL.ByteString -> Either T.Text a-runGet' p bl =-#if MIN_VERSION_binary(0,7,0)- case runGetOrFail p bl of- Left (_,_,msg) -> Left $ T.pack msg- Right (_,_,x) -> x-#else- runGet p bl-#endif--exifSize :: ByteString -> Either T.Text ImageSize-exifSize bs = runGet' header bl- where bl = BL.fromChunks [bs]- header = runExceptT $ exifHeader bl--- 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 -> ExceptT T.Text Get ImageSize-exifHeader hdr = do- _app1DataSize <- lift getWord16be- exifHdr <- lift getWord32be- unless (exifHdr == 0x45786966) $ throwError "Did not find exif header"- zeros <- lift getWord16be- unless (zeros == 0) $ throwError "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 <- lift 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 <- lift getWord16- unless (tagmark == 0x002a) $ throwError "Failed alignment sanity check"- ifdOffset <- lift getWord32- lift $ skip (fromIntegral ifdOffset - 8) -- skip to IDF- numentries <- lift getWord16- let ifdEntry :: ExceptT T.Text Get (TagType, DataFormat)- ifdEntry = do- tag <- fromMaybe UnknownTagType . flip M.lookup tagTypeTable- <$> lift getWord16- dataFormat <- lift getWord16- numComponents <- lift getWord32- (fmt, bytesPerComponent) <-- case dataFormat of- 1 -> return (UnsignedByte <$> getWord8, 1)- 2 -> return (AsciiString <$>- getLazyByteString- (fromIntegral numComponents), 1)- 3 -> return (UnsignedShort <$> getWord16, 2)- 4 -> return (UnsignedLong <$> getWord32, 4)- 5 -> return (UnsignedRational <$> getRational, 8)- 6 -> return (SignedByte <$> getWord8, 1)- 7 -> return (Undefined <$> getLazyByteString- (fromIntegral numComponents), 1)- 8 -> return (SignedShort <$> getWord16, 2)- 9 -> return (SignedLong <$> getWord32, 4)- 10 -> return (SignedRational <$> getRational, 8)- 11 -> return (SingleFloat <$> getWord32 {- TODO -}, 4)- 12 -> return (DoubleFloat <$> getWord64 {- TODO -}, 8)- _ -> throwError $ "Unknown data format " <> T.pack (show dataFormat)- let totalBytes = fromIntegral $ numComponents * bytesPerComponent- payload <- if totalBytes <= 4 -- data is right here- then lift $ fmt <* skip (4 - totalBytes)- else do -- get data from offset- offs <- lift getWord32- let bytesAtOffset =- BL.take (fromIntegral totalBytes)- $ BL.drop (fromIntegral offs) tiffHeader- case runGet' (Right <$> fmt) bytesAtOffset of- Left msg -> throwError msg- Right x -> return x- return (tag, payload)- entries <- replicateM (fromIntegral numentries) ifdEntry- subentries <- case lookup ExifOffset entries of- Just (UnsignedLong offset') -> do- pos <- lift bytesRead- lift $ skip (fromIntegral offset' - (fromIntegral pos - 8))- numsubentries <- lift getWord16- replicateM (fromIntegral numsubentries) ifdEntry- _ -> return []- let allentries = entries ++ subentries- (wdth, hght) <- 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 = case lookup XResolution allentries of- Just (UnsignedRational x) -> floor (x * resfactor)- _ -> 72- let yres = case lookup YResolution allentries of- Just (UnsignedRational y) -> floor (y * resfactor)- _ -> 72- return ImageSize{- pxX = wdth- , pxY = hght- , dpiX = xres- , dpiY = yres }--data DataFormat = UnsignedByte Word8- | AsciiString BL.ByteString- | UnsignedShort Word16- | UnsignedLong Word32- | UnsignedRational Rational- | SignedByte Word8- | Undefined BL.ByteString- | 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)- ]
@@ -22,6 +22,7 @@ instance (TemplateTarget a, Pushable a) => Pushable (Val a) where push NullVal = Lua.push ()+ push (BoolVal b) = Lua.push b push (MapVal ctx) = Lua.push ctx push (ListVal xs) = Lua.push xs push (SimpleVal d) = Lua.push $ render Nothing d
@@ -65,6 +65,7 @@ , readerDefaultImageExtension :: Text -- ^ Default extension for images , readerTrackChanges :: TrackChanges -- ^ Track changes setting for docx , readerStripComments :: Bool -- ^ Strip HTML comments instead of parsing as raw HTML+ -- (only implemented in commonmark) } deriving (Show, Read, Data, Typeable, Generic) instance HasSyntaxExtensions ReaderOptions where
@@ -190,7 +190,7 @@ import Control.Monad.Identity import Control.Monad.Reader-import Data.Char (chr, isAlphaNum, isAscii, isAsciiUpper,+import Data.Char (chr, isAlphaNum, isAscii, isAsciiUpper, isAsciiLower, isPunctuation, isSpace, ord, toLower, toUpper) import Data.Default import Data.Functor (($>))@@ -443,8 +443,15 @@ -- | Parses a nonspace, nonnewline character. nonspaceChar :: Stream s m Char => ParserT s st m Char-nonspaceChar = noneOf ['\t', '\n', ' ', '\r']+nonspaceChar = satisfy (not . isSpaceChar) +isSpaceChar :: Char -> Bool+isSpaceChar ' ' = True+isSpaceChar '\t' = True+isSpaceChar '\n' = True+isSpaceChar '\r' = True+isSpaceChar _ = False+ -- | Skips zero or more spaces or tabs. skipSpaces :: Stream s m Char => ParserT s st m () skipSpaces = skipMany spaceChar@@ -634,7 +641,7 @@ scheme <- uriScheme char ':' -- Avoid parsing e.g. "**Notes:**" as a raw URI:- notFollowedBy (oneOf "*_]")+ notFollowedBy $ satisfy (\c -> c == '*' || c == '_' || c == ']') -- We allow sentence 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)@@ -648,7 +655,20 @@ let uri' = scheme <> ":" <> fromEntities str' return (uri', escapeURI uri') where- wordChar = alphaNum <|> oneOf "#$%+/@\\_-&="+ isWordChar '#' = True+ isWordChar '$' = True+ isWordChar '%' = True+ isWordChar '+' = True+ isWordChar '/' = True+ isWordChar '@' = True+ isWordChar '\\' = True+ isWordChar '_' = True+ isWordChar '-' = True+ isWordChar '&' = True+ isWordChar '=' = True+ isWordChar c = isAlphaNum c++ wordChar = satisfy isWordChar percentEscaped = try $ (:) <$> char '%' <*> many1 hexDigit entity = try $ pure <$> characterReference punct = try $ many1 (char ',') <|> fmap pure (satisfy (\c -> not (isSpace c) && c /= '<' && c /= '>'))@@ -663,7 +683,9 @@ mathInlineWith op cl = try $ do textStr op when (op == "$") $ notFollowedBy space- words' <- many1Till (countChar 1 (noneOf " \t\n\\")+ words' <- many1Till (+ (T.singleton <$>+ satisfy (\c -> not (isSpaceChar c || c == '\\'))) <|> (char '\\' >> -- This next clause is needed because \text{..} can -- contain $, \(\), etc.@@ -671,7 +693,7 @@ (("\\text" <>) <$> inBalancedBraces 0 "")) <|> (\c -> T.pack ['\\',c]) <$> anyChar)) <|> do (blankline <* notFollowedBy' blankline) <|>- (oneOf " \t" <* skipMany (oneOf " \t"))+ (spaceChar <* skipMany spaceChar) notFollowedBy (char '$') return " " ) (try $ textStr cl)@@ -701,7 +723,8 @@ mathDisplayWith :: Stream s m Char => Text -> Text -> ParserT s st m Text mathDisplayWith op cl = try $ fmap T.pack $ do textStr op- many1Till (noneOf "\n" <|> (newline <* notFollowedBy' blankline)) (try $ textStr cl)+ many1Till (satisfy (/= '\n') <|> (newline <* notFollowedBy' blankline))+ (try $ textStr cl) mathDisplay :: (HasReaderOptions st, Stream s m Char) => ParserT s st m Text@@ -821,13 +844,13 @@ -- | 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']+ ch <- satisfy isAsciiLower 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']+ ch <- satisfy isAsciiUpper return (UpperAlpha, ord ch - ord 'A' + 1) -- | Parses a roman numeral i or I
@@ -2,7 +2,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {- |- Module : Text.Pandoc.Readers.RST+ Module : Text.Pandoc.Readers.CSV Copyright : Copyright (C) 2006-2020 John MacFarlane License : GNU GPL, version 2 or above
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {- | Module : Text.Pandoc.Readers.CommonMark@@ -27,15 +28,24 @@ import Text.Pandoc.Error import Control.Monad.Except import Data.Functor.Identity (runIdentity)+import Data.Typeable -- | Parse a CommonMark formatted string into a 'Pandoc' structure. readCommonMark :: PandocMonad m => ReaderOptions -> Text -> m Pandoc-readCommonMark opts s = do- let res = runIdentity $- commonmarkWith (foldr ($) defaultSyntaxSpec exts) "input" s- case res of- Left err -> throwError $ PandocParsecError s err- Right (Cm bls :: Cm () Blocks) -> return $ B.doc bls+readCommonMark opts s+ | isEnabled Ext_sourcepos opts =+ case runIdentity (commonmarkWith (specFor opts) "" s) of+ Left err -> throwError $ PandocParsecError s err+ Right (Cm bls :: Cm SourceRange Blocks) -> return $ B.doc bls+ | otherwise =+ case runIdentity (commonmarkWith (specFor opts) "" s) of+ Left err -> throwError $ PandocParsecError s err+ Right (Cm bls :: Cm () Blocks) -> return $ B.doc bls++specFor :: (Monad m, Typeable m, Typeable a,+ Rangeable (Cm a Inlines), Rangeable (Cm a Blocks))+ => ReaderOptions -> SyntaxSpec m (Cm a Inlines) (Cm a Blocks)+specFor opts = foldr ($) defaultSyntaxSpec exts where exts = [ (hardLineBreaksSpec <>) | isEnabled Ext_hard_line_breaks opts ] ++ [ (smartPunctuationSpec <>) | isEnabled Ext_smart opts ] ++
@@ -960,12 +960,22 @@ let aligns = case colspecs of [] -> replicate numrows AlignDefault cs -> map toAlignment cs+ let parseWidth s = safeRead (T.filter (\x -> (x >= '0' && x <= '9')+ || x == '.') s)+ let textWidth = case filterChild (named "?dbfo") e of+ Just d -> case attrValue "table-width" d of+ "" -> 1.0+ w -> fromMaybe 100.0 (parseWidth w) / 100.0+ Nothing -> 1.0 let widths = case colspecs of [] -> replicate numrows ColWidthDefault cs -> let ws = map toWidth cs in case sequence ws of- Just ws' -> let tot = sum ws'- in ColWidth . (/ tot) <$> ws'+ Just ws' -> let colTot = sum ws'+ scale+ | textWidth == 1.0 = (/ colTot)+ | otherwise = (* (textWidth / colTot) )+ in ColWidth . scale <$> ws' Nothing -> replicate numrows ColWidthDefault let toRow = Row nullAttr toHeaderRow l = [toRow l | not (null l)]
@@ -317,7 +317,7 @@ interwikiToUrl "wpfr" page = "https://fr.wikipedia.org/wiki/" <> page interwikiToUrl "wpjp" page = "https://jp.wikipedia.org/wiki/" <> page interwikiToUrl "wppl" page = "https://pl.wikipedia.org/wiki/" <> page-interwikiToUrl _ page = "https://www.google.com/search?q=" <> page <> "&btnI=lucky"+interwikiToUrl unknown page = unknown <> ">" <> page linkText :: PandocMonad m => DWParser m B.Inlines linkText = parseLink fromRaw "[[" "]]"
@@ -1,7 +1,6 @@-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} {- |@@ -26,10 +25,10 @@ ) where import Control.Applicative ((<|>))-import Control.Arrow (first)-import Control.Monad (guard, mplus, msum, mzero, unless, void)+import Control.Monad (guard, msum, mzero, unless, void) import Control.Monad.Except (throwError)-import Control.Monad.Reader (ReaderT, ask, asks, lift, local, runReaderT)+import Control.Monad.Reader (ask, asks, lift, local, runReaderT)+import Data.ByteString.Base64 (encode) import Data.Char (isAlphaNum, isLetter) import Data.Default (Default (..), def) import Data.Foldable (for_)@@ -40,18 +39,20 @@ import qualified Data.Set as Set import Data.Text (Text) import qualified Data.Text as T-import Network.URI (URI, nonStrictRelativeTo, parseURIReference)+import Network.URI (nonStrictRelativeTo, parseURIReference) import Text.HTML.TagSoup import Text.HTML.TagSoup.Match-import Text.Pandoc.Builder (Blocks, HasMeta (..), Inlines, trimInlines)+import Text.Pandoc.Builder (Blocks, Inlines, trimInlines) import qualified Text.Pandoc.Builder as B import Text.Pandoc.Class.PandocMonad (PandocMonad (..))-import Text.Pandoc.CSS (foldOrElse, pickStyleAttrProps)+import Text.Pandoc.CSS (pickStyleAttrProps) import qualified Text.Pandoc.UTF8 as UTF8 import Text.Pandoc.Definition+import Text.Pandoc.Readers.HTML.Parsing+import Text.Pandoc.Readers.HTML.Table (pTable)+import Text.Pandoc.Readers.HTML.TagCategories+import Text.Pandoc.Readers.HTML.Types import Text.Pandoc.Readers.LaTeX (rawLaTeXInline)-import Text.Pandoc.Readers.LaTeX.Types (Macro)-import Text.Pandoc.XML (html5Attributes, html4Attributes, rdfaAttributes) import Text.Pandoc.Error import Text.Pandoc.Logging import Text.Pandoc.Options (@@ -61,12 +62,10 @@ extensionEnabled) import Text.Pandoc.Parsing hiding ((<|>)) import Text.Pandoc.Shared (addMetaField, blocksToInlines', crFilter, escapeURI,- extractSpaces, htmlSpanLikeElements, elemText, splitTextBy,- onlySimpleTableCells, safeRead, tshow)+ extractSpaces, htmlSpanLikeElements, safeRead, tshow) import Text.Pandoc.Walk import Text.Parsec.Error import Text.TeXMath (readMathML, writeTeX)-import Data.ByteString.Base64 (encode) -- | Convert HTML-formatted string to 'Pandoc' document. readHtml :: PandocMonad m@@ -74,7 +73,7 @@ -> Text -- ^ String to parse (assumes @'\n'@ line endings) -> m Pandoc readHtml opts inp = do- let tags = stripPrefixes . canonicalizeTags $+ let tags = stripPrefixes $ canonicalizeTags $ parseTagsOptions parseOptions{ optTagPosition = True } (crFilter inp) parseDoc = do@@ -95,6 +94,15 @@ Right doc -> return doc Left err -> throwError $ PandocParseError $ T.pack $ getError err +-- Strip namespace prefixes on tags (not attributes)+stripPrefixes :: [Tag Text] -> [Tag Text]+stripPrefixes = map stripPrefix++stripPrefix :: Tag Text -> Tag Text+stripPrefix (TagOpen s as) = TagOpen (T.takeWhileEnd (/=':') s) as+stripPrefix (TagClose s) = TagClose (T.takeWhileEnd (/=':') s)+stripPrefix x = x+ replaceNotes :: PandocMonad m => [Block] -> TagParser m [Block] replaceNotes bs = do st <- getState@@ -105,41 +113,25 @@ maybe (Str "") (Note . B.toList) $ lookup ref noteTbl replaceNotes' _ x = x -data HTMLState =- HTMLState- { parserState :: ParserState,- noteTable :: [(Text, Blocks)],- baseHref :: Maybe URI,- identifiers :: Set.Set Text,- logMessages :: [LogMessage],- macros :: M.Map Text Macro,- readerOpts :: ReaderOptions- }--data HTMLLocal = HTMLLocal { quoteContext :: QuoteContext- , inChapter :: Bool -- ^ Set if in chapter section- , inPlain :: Bool -- ^ Set if in pPlain- }- setInChapter :: PandocMonad m => HTMLParser m s a -> HTMLParser m s a setInChapter = local (\s -> s {inChapter = True}) setInPlain :: PandocMonad m => HTMLParser m s a -> HTMLParser m s a setInPlain = local (\s -> s {inPlain = True}) -type HTMLParser m s = ParserT s HTMLState (ReaderT HTMLLocal m)--type TagParser m = HTMLParser m [Tag Text]- pHtml :: PandocMonad m => TagParser m Blocks-pHtml = try $ do+pHtml = do (TagOpen "html" attr) <- lookAhead pAny- for_ (lookup "lang" attr) $+ for_ (lookup "lang" attr <|> lookup "xml:lang" attr) $ updateState . B.setMeta "lang" . B.text pInTags "html" block pBody :: PandocMonad m => TagParser m Blocks-pBody = pInTags "body" block+pBody = do+ (TagOpen "body" attr) <- lookAhead pAny+ for_ (lookup "lang" attr <|> lookup "xml:lang" attr) $+ updateState . B.setMeta "lang" . B.text+ pInTags "body" block pHead :: PandocMonad m => TagParser m Blocks pHead = pInTags "head" $ pTitle <|> pMetaTag <|> pBaseTag <|> (mempty <$ pAny)@@ -178,7 +170,7 @@ , pCodeBlock , pList , pHrule- , pTable+ , pTable block , pHtml , pHead , pBody@@ -309,23 +301,14 @@ pOrderedList = try $ do TagOpen _ attribs' <- pSatisfy (matchTagOpen "ol" []) let attribs = toStringAttr attribs'- let (start, style) = (sta', sty')- where sta = fromMaybe "1" $- lookup "start" attribs- sta' = fromMaybe 1 $ safeRead sta-- pickListStyle = pickStyleAttrProps ["list-style-type", "list-style"]-- typeAttr = fromMaybe "" $ lookup "type" attribs- classAttr = fromMaybe "" $ lookup "class" attribs- styleAttr = fromMaybe "" $ lookup "style" attribs- listStyle = fromMaybe "" $ pickListStyle styleAttr+ let start = fromMaybe 1 $ lookup "start" attribs >>= safeRead+ let style = fromMaybe DefaultStyle+ $ (parseTypeAttr <$> lookup "type" attribs)+ <|> (parseListStyleType <$> lookup "class" attribs)+ <|> (parseListStyleType <$> (lookup "style" attribs >>= pickListStyle))+ where+ pickListStyle = pickStyleAttrProps ["list-style-type", "list-style"] - sty' = foldOrElse DefaultStyle- [ parseTypeAttr typeAttr- , parseListStyleType classAttr- , parseListStyleType listStyle- ] let nonItem = pSatisfy (\t -> not (tagOpen (`elem` ["li","ol","ul","dl"]) (const True) t) && not (matchTagClose "ol" t))@@ -492,107 +475,6 @@ pSelfClosing (=="hr") (const True) return B.horizontalRule -pTable :: PandocMonad m => TagParser m Blocks-pTable = try $ do- TagOpen _ attribs' <- pSatisfy (matchTagOpen "table" [])- let attribs = toAttr attribs'- skipMany pBlank- caption <- option mempty $ pInTags "caption" inline <* skipMany pBlank- widths' <- (mconcat <$> many1 pColgroup) <|> many pCol- let pTh = option [] $ pInTags "tr" (pCell "th")- pTr = try $ skipMany pBlank >>- pInTags "tr" (pCell "td" <|> pCell "th")- pTBody = pInTag True "tbody" $ many1 pTr- head'' <- pInTag False "thead" (option [] pTr) <|> pInTag True "thead" pTh- head' <- map snd <$>- pInTag True "tbody"- (if null head'' then pTh else return head'')- topfoot <- option [] $ pInTag False "tfoot" $ many pTr- rowsLs <- many pTBody- bottomfoot <- option [] $ pInTag False "tfoot" $ many pTr- TagClose _ <- pSatisfy (matchTagClose "table")- let rows'' = concat rowsLs <> topfoot <> bottomfoot- let rows''' = map (map snd) rows''- -- fail on empty table- guard $ not $ null head' && null rows'''- let isSimple = onlySimpleTableCells $ fmap B.toList <$> head':rows'''- let cols = if null head'- then maximum (map length rows''')- else length head'- -- add empty cells to short rows- let addEmpties r = case cols - length r of- n | n > 0 -> r <> replicate n mempty- | otherwise -> r- let rows = map addEmpties rows'''- let aligns = case rows'' of- (cs:_) -> take cols $ map fst cs ++ repeat AlignDefault- _ -> replicate cols AlignDefault- let widths = if null widths'- then if isSimple- then replicate cols ColWidthDefault- else replicate cols (ColWidth (1.0 / fromIntegral cols))- else widths'- let toRow = Row nullAttr . map B.simpleCell- toHeaderRow l = [toRow l | not (null l)]- return $ B.tableWith attribs- (B.simpleCaption $ B.plain caption)- (zip aligns widths)- (TableHead nullAttr $ toHeaderRow head')- [TableBody nullAttr 0 [] $ map toRow rows]- (TableFoot nullAttr [])--pCol :: PandocMonad m => TagParser m ColWidth-pCol = try $ do- TagOpen _ attribs' <- pSatisfy (matchTagOpen "col" [])- let attribs = toStringAttr attribs'- skipMany pBlank- optional $ pSatisfy (matchTagClose "col")- skipMany pBlank- let width = case lookup "width" attribs of- Nothing -> case lookup "style" attribs of- Just (T.stripPrefix "width:" -> Just xs) | T.any (== '%') xs ->- fromMaybe 0.0 $ safeRead (T.filter- (`notElem` (" \t\r\n%'\";" :: [Char])) xs)- _ -> 0.0- Just (T.unsnoc -> Just (xs, '%')) ->- fromMaybe 0.0 $ safeRead xs- _ -> 0.0- if width > 0.0- then return $ ColWidth $ width / 100.0- else return ColWidthDefault--pColgroup :: PandocMonad m => TagParser m [ColWidth]-pColgroup = try $ do- pSatisfy (matchTagOpen "colgroup" [])- skipMany pBlank- manyTill pCol (pCloses "colgroup" <|> eof) <* skipMany pBlank--noColOrRowSpans :: Tag Text -> Bool-noColOrRowSpans t = isNullOrOne "colspan" && isNullOrOne "rowspan"- where isNullOrOne x = case fromAttrib x t of- "" -> True- "1" -> True- _ -> False--pCell :: PandocMonad m => Text -> TagParser m [(Alignment, Blocks)]-pCell celltype = try $ do- skipMany pBlank- tag <- lookAhead $- pSatisfy (\t -> t ~== TagOpen celltype [] && noColOrRowSpans t)- let extractAlign' [] = ""- extractAlign' ("text-align":x:_) = x- extractAlign' (_:xs) = extractAlign' xs- let extractAlign = extractAlign' . splitTextBy (`elemText` " \t;:")- let align = case maybeFromAttrib "align" tag `mplus`- (extractAlign <$> maybeFromAttrib "style" tag) of- Just "left" -> AlignLeft- Just "right" -> AlignRight- Just "center" -> AlignCenter- _ -> AlignDefault- res <- pInTags' celltype noColOrRowSpans block- skipMany pBlank- return [(align, res)]- pBlockQuote :: PandocMonad m => TagParser m Blocks pBlockQuote = do contents <- pInTags "blockquote" block@@ -618,7 +500,7 @@ TagOpen _ _ <- pSatisfy (matchTagOpen "figure" []) skipMany pBlank let pImg = (\x -> (Just x, Nothing)) <$>- (pInTag True "p" pImage <* skipMany pBlank)+ (pInTag TagsOmittable "p" pImage <* skipMany pBlank) pCapt = (\x -> (Nothing, Just x)) <$> do bs <- pInTags "figcaption" block return $ blocksToInlines' $ B.toList bs@@ -681,22 +563,6 @@ , pRawHtmlInline ] -pLocation :: PandocMonad m => TagParser m ()-pLocation = do- (TagPosition r c) <- pSat isTagPosition- setPosition $ newPos "input" r c--pSat :: PandocMonad m => (Tag Text -> Bool) -> TagParser m (Tag Text)-pSat f = do- pos <- getPosition- token tshow (const pos) (\x -> if f x then Just x else Nothing)--pSatisfy :: PandocMonad m => (Tag Text -> Bool) -> TagParser m (Tag Text)-pSatisfy f = try $ optional pLocation >> pSat f--pAny :: PandocMonad m => TagParser m (Tag Text)-pAny = pSatisfy (const True)- pSelfClosing :: PandocMonad m => (Text -> Bool) -> ([Attribute Text] -> Bool) -> TagParser m (Tag Text)@@ -773,12 +639,6 @@ pSelfClosing (=="br") (const True) return B.linebreak --- Unlike fromAttrib from tagsoup, this distinguishes--- between a missing attribute and an attribute with empty content.-maybeFromAttrib :: Text -> Tag Text -> Maybe Text-maybeFromAttrib name (TagOpen _ attrs) = lookup name attrs-maybeFromAttrib _ _ = Nothing- pLink :: PandocMonad m => TagParser m Inlines pLink = try $ do tag <- pSatisfy $ tagOpenLit "a" (const True)@@ -882,16 +742,6 @@ mathMLToTeXMath :: Text -> Either Text Text mathMLToTeXMath s = writeTeX <$> readMathML s -toStringAttr :: [(Text, Text)] -> [(Text, Text)]-toStringAttr = map go- where- go (x,y) =- case T.stripPrefix "data-" x of- Just x' | x' `Set.notMember` (html5Attributes <>- html4Attributes <> rdfaAttributes)- -> (x',y)- _ -> (x,y)- pScriptMath :: PandocMonad m => TagParser m Inlines pScriptMath = try $ do TagOpen _ attr' <- pSatisfy $ tagOpen (=="script") (const True)@@ -924,49 +774,6 @@ -> TagParser m Inlines pInlinesInTags tagtype f = extractSpaces f <$> pInTags tagtype inline -pInTags :: (PandocMonad m, Monoid a) => Text -> TagParser m a -> TagParser m a-pInTags tagtype parser = pInTags' tagtype (const True) parser--pInTags' :: (PandocMonad m, Monoid a)- => Text- -> (Tag Text -> Bool)- -> TagParser m a- -> TagParser m a-pInTags' tagtype tagtest parser = try $ do- pSatisfy (\t -> t ~== TagOpen tagtype [] && tagtest t)- mconcat <$> manyTill parser (pCloses tagtype <|> eof)---- parses p, preceded by an opening tag (optional if tagsOptional)--- and followed by a closing tag (optional if tagsOptional)-pInTag :: PandocMonad m => Bool -> Text -> TagParser m a -> TagParser m a-pInTag tagsOptional tagtype p = try $ do- skipMany pBlank- (if tagsOptional then optional else void) $ pSatisfy (matchTagOpen tagtype [])- skipMany pBlank- x <- p- skipMany pBlank- (if tagsOptional then optional else void) $ pSatisfy (matchTagClose tagtype)- skipMany pBlank- return x--pCloses :: PandocMonad m => Text -> TagParser m ()-pCloses tagtype = try $ do- t <- lookAhead $ pSatisfy $ \tag -> isTagClose tag || isTagOpen tag- case t of- (TagClose t') | t' == tagtype -> void pAny- (TagOpen t' _) | t' `closes` tagtype -> return ()- (TagClose "ul") | tagtype == "li" -> return ()- (TagClose "ol") | tagtype == "li" -> return ()- (TagClose "dl") | tagtype == "dd" -> return ()- (TagClose "table") | tagtype == "td" -> return ()- (TagClose "table") | tagtype == "th" -> return ()- (TagClose "table") | tagtype == "tr" -> return ()- (TagClose "td") | tagtype `Set.member` blockHtmlTags -> return ()- (TagClose "th") | tagtype `Set.member` blockHtmlTags -> return ()- (TagClose t') | tagtype == "p" && t' `Set.member` blockHtmlTags- -> return () -- see #3794- _ -> mzero- pTagText :: PandocMonad m => TagParser m Inlines pTagText = try $ do (TagText str) <- pSatisfy isTagText@@ -975,14 +782,10 @@ parsed <- lift $ lift $ flip runReaderT qu $ runParserT (many pTagContents) st "text" str case parsed of- Left _ -> throwError $ PandocParseError $ "Could not parse `" <> str <> "'"+ Left _ -> throwError $ PandocParseError $+ "Could not parse `" <> str <> "'" Right result -> return $ mconcat result -pBlank :: PandocMonad m => TagParser m ()-pBlank = try $ do- (TagText str) <- pSatisfy isTagText- guard $ T.all isSpace str- type InlinesParser m = HTMLParser m Text pTagContents :: PandocMonad m => InlinesParser m Inlines@@ -1077,54 +880,6 @@ then return B.softbreak else return B.space ------ Constants-----eitherBlockOrInline :: Set.Set Text-eitherBlockOrInline = Set.fromList- ["audio", "applet", "button", "iframe", "embed",- "del", "ins", "progress", "map", "area", "noscript", "script",- "object", "svg", "video", "source"]--blockHtmlTags :: Set.Set Text-blockHtmlTags = Set.fromList- ["?xml", "!DOCTYPE", "address", "article", "aside",- "blockquote", "body", "canvas",- "caption", "center", "col", "colgroup", "dd", "details",- "dir", "div", "dl", "dt", "fieldset", "figcaption", "figure",- "footer", "form", "h1", "h2", "h3", "h4",- "h5", "h6", "head", "header", "hgroup", "hr", "html",- "isindex", "main", "menu", "meta", "noframes", "nav",- "ol", "output", "p", "pre",- "section", "summary", "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 :: Set.Set Text-blockDocBookTags = Set.fromList- ["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 :: Set.Set Text-epubTags = Set.fromList ["case", "switch", "default"]--blockTags :: Set.Set Text-blockTags = Set.unions [blockHtmlTags, blockDocBookTags, epubTags]- class NamedTag a where getTagName :: a -> Maybe Text @@ -1162,47 +917,6 @@ isCommentTag :: Tag a -> 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 :: Text -> Text -> Bool-_ `closes` "body" = False-_ `closes` "html" = False-"body" `closes` "head" = True-"a" `closes` "a" = True-"li" `closes` "li" = True-"th" `closes` t | t `elem` ["th","td"] = True-"td" `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--- https://html.spec.whatwg.org/multipage/syntax.html#optional-tags-x `closes` "p" | x `elem` ["address", "article", "aside", "blockquote",- "dir", "div", "dl", "fieldset", "footer", "form", "h1", "h2", "h3", "h4",- "h5", "h6", "header", "hr", "main", "menu", "nav", "ol", "p", "pre", "section",- "table", "ul"] = True-_ `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` "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","main","p"] &&- t2 `elem` ["h1","h2","h3","h4","h5","h6","p" ] = True -- not "div" or "main"-t1 `closes` t2 |- t1 `Set.member` blockTags &&- t2 `Set.notMember` blockTags &&- t2 `Set.notMember` eitherBlockOrInline = True-_ `closes` _ = False- --- parsers for use in markdown, textile readers -- | Matches a stretch of HTML in balanced tags.@@ -1322,38 +1036,6 @@ handleTag tagname _ -> mzero -mkAttr :: [(Text, Text)] -> Attr-mkAttr attr = (attribsId, attribsClasses, attribsKV)- where attribsId = fromMaybe "" $ lookup "id" attr- attribsClasses = T.words (fromMaybe "" $ lookup "class" attr) <> epubTypes- attribsKV = filter (\(k,_) -> k /= "class" && k /= "id") attr- epubTypes = T.words $ fromMaybe "" $ lookup "epub:type" attr--toAttr :: [(Text, Text)] -> Attr-toAttr = mkAttr . toStringAttr---- Strip namespace prefixes-stripPrefixes :: [Tag Text] -> [Tag Text]-stripPrefixes = map stripPrefix--stripPrefix :: Tag Text -> Tag Text-stripPrefix (TagOpen s as) =- TagOpen (stripPrefix' s) (map (first stripPrefix') as)-stripPrefix (TagClose s) = TagClose (stripPrefix' s)-stripPrefix x = x--stripPrefix' :: Text -> Text-stripPrefix' s =- if T.null t then s else T.drop 1 t- where (_, t) = T.span (/= ':') s--isSpace :: Char -> Bool-isSpace ' ' = True-isSpace '\t' = True-isSpace '\n' = True-isSpace '\r' = True-isSpace _ = False- -- Utilities -- | Adjusts a url according to the document's base URL.@@ -1364,41 +1046,6 @@ (Just rel, Just bs) -> tshow (rel `nonStrictRelativeTo` bs) _ -> url ---- Instances--instance HasMacros HTMLState where- extractMacros = macros- updateMacros f st = st{ macros = f $ macros st }--instance HasIdentifierList HTMLState where- extractIdentifierList = identifiers- updateIdentifierList f s = s{ identifiers = f (identifiers s) }--instance HasLogMessages HTMLState where- addLogMessage m s = s{ logMessages = m : logMessages s }- getLogMessages = reverse . logMessages---- This signature should be more general--- MonadReader HTMLLocal m => HasQuoteContext st m-instance PandocMonad m => HasQuoteContext HTMLState (ReaderT HTMLLocal m) where- getQuoteContext = asks quoteContext- withQuoteContext q = local (\s -> s{quoteContext = q})--instance HasReaderOptions HTMLState where- extractReaderOptions = extractReaderOptions . parserState--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- -- For now we need a special version here; the one in Shared has String type renderTags' :: [Tag Text] -> Text renderTags' = renderTagsOptions@@ -1411,21 +1058,6 @@ -- EPUB Specific -- ---sectioningContent :: [Text]-sectioningContent = ["article", "aside", "nav", "section"]---groupingContent :: [Text]-groupingContent = ["p", "hr", "pre", "blockquote", "ol"- , "ul", "li", "dl", "dt", "dt", "dd"- , "figure", "figcaption", "div", "main"]--matchTagClose :: Text -> (Tag Text -> Bool)-matchTagClose t = (~== TagClose t)--matchTagOpen :: Text -> [(Text, Text)] -> (Tag Text -> Bool)-matchTagOpen t as = (~== TagOpen t as)- {- types :: [(String, ([String], Int))]
@@ -0,0 +1,225 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{- |+ Module : Text.Pandoc.Readers.HTML.Parsing+ Copyright : Copyright (C) 2006-2020 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Parsing functions and utilities.+-}+module Text.Pandoc.Readers.HTML.Parsing+ ( TagOmission (..)+ , pInTags+ , pInTags'+ , pInTag+ , pInTagWithAttribs+ , pAny+ , pCloses+ , pSatisfy+ , pBlank+ , matchTagClose+ , matchTagOpen+ , isSpace+ , maybeFromAttrib+ , toAttr+ , toStringAttr+ )+where++import Control.Monad (guard, void, mzero)+import Data.Maybe (fromMaybe)+import Data.Text (Text)+import Text.HTML.TagSoup+ ( Attribute, Tag (..), isTagText, isTagPosition, isTagOpen, isTagClose, (~==) )+import Text.Pandoc.Class.PandocMonad (PandocMonad (..))+import Text.Pandoc.Definition (Attr)+import Text.Pandoc.Parsing+ ( (<|>), eof, getPosition, lookAhead, manyTill, newPos, option, optional+ , skipMany, setPosition, token, try)+import Text.Pandoc.Readers.HTML.TagCategories+import Text.Pandoc.Readers.HTML.Types+import Text.Pandoc.Shared (tshow)+import Text.Pandoc.XML (html5Attributes, html4Attributes, rdfaAttributes)+import qualified Data.Set as Set+import qualified Data.Text as T++-- | Whether no tag, the closing tag, or both tags can be omitted.+data TagOmission+ = TagsRequired -- ^ Opening and closing tags are both required+ | ClosingTagOptional -- ^ The closing tag can be omitted+ | TagsOmittable -- ^ Both tags, opening and closing, can be omitted.+ deriving (Eq)++pInTags :: (PandocMonad m, Monoid a) => Text -> TagParser m a -> TagParser m a+pInTags tagtype parser = pInTags' tagtype (const True) parser++pInTags' :: (PandocMonad m, Monoid a)+ => Text+ -> (Tag Text -> Bool)+ -> TagParser m a+ -> TagParser m a+pInTags' tagtype tagtest parser = try $ do+ pSatisfy $ \t -> matchTagOpen tagtype [] t && tagtest t+ mconcat <$> manyTill parser (pCloses tagtype <|> eof)++pInTag :: PandocMonad m+ => TagOmission -- ^ Whether some tags can be omitted+ -> Text -- ^ @tagtype@ Tag name+ -> TagParser m a -- ^ @p@ Content parser+ -> TagParser m a+pInTag tagOmission tagtype = fmap snd . pInTagWithAttribs tagOmission tagtype++-- | Returns the contents of a tag together with its attributes; parses+-- @p@, preceded by an opening tag (optional if TagsOmittable) and+-- followed by a closing tag (optional unless TagsRequired).+pInTagWithAttribs :: PandocMonad m+ => TagOmission -- ^ Whether some tags can be omitted+ -> Text -- ^ @tagtype@ Tag name+ -> TagParser m a -- ^ @p@ Content parser+ -> TagParser m ([Attribute Text], a)+pInTagWithAttribs tagOmission tagtype p = try $ do+ let openingOptional = tagOmission == TagsOmittable+ let closingOptional = tagOmission /= TagsRequired+ skipMany pBlank+ attribs <- (if openingOptional then option [] else id)+ (getAttribs <$> pSatisfy (matchTagOpen tagtype []))+ skipMany pBlank+ x <- p+ skipMany pBlank+ (if closingOptional then optional else void) $+ pSatisfy (matchTagClose tagtype)+ skipMany pBlank+ return (attribs, x)+ where+ getAttribs = \case+ TagOpen _ attribs -> attribs+ _ -> []++pCloses :: PandocMonad m => Text -> TagParser m ()+pCloses tagtype = try $ do+ t <- lookAhead $ pSatisfy $ \tag -> isTagClose tag || isTagOpen tag+ case t of+ (TagClose t') | t' == tagtype -> void pAny+ (TagOpen t' _) | t' `closes` tagtype -> return ()+ (TagClose "ul") | tagtype == "li" -> return ()+ (TagClose "ol") | tagtype == "li" -> return ()+ (TagClose "dl") | tagtype == "dd" -> return ()+ (TagClose "table") | tagtype == "td" -> return ()+ (TagClose "table") | tagtype == "th" -> return ()+ (TagClose "table") | tagtype == "tr" -> return ()+ (TagClose "td") | tagtype `Set.member` blockHtmlTags -> return ()+ (TagClose "th") | tagtype `Set.member` blockHtmlTags -> return ()+ (TagClose t') | tagtype == "p" && t' `Set.member` blockHtmlTags+ -> return () -- see #3794+ _ -> mzero++pBlank :: PandocMonad m => TagParser m ()+pBlank = try $ do+ (TagText str) <- pSatisfy isTagText+ guard $ T.all isSpace str++pLocation :: PandocMonad m => TagParser m ()+pLocation = do+ (TagPosition r c) <- pSat isTagPosition+ setPosition $ newPos "input" r c++pSat :: PandocMonad m => (Tag Text -> Bool) -> TagParser m (Tag Text)+pSat f = do+ pos <- getPosition+ token tshow (const pos) (\x -> if f x then Just x else Nothing)++pSatisfy :: PandocMonad m => (Tag Text -> Bool) -> TagParser m (Tag Text)+pSatisfy f = try $ optional pLocation >> pSat f++matchTagClose :: Text -> (Tag Text -> Bool)+matchTagClose t = (~== TagClose t)++matchTagOpen :: Text -> [(Text, Text)] -> (Tag Text -> Bool)+matchTagOpen t as = (~== TagOpen t as)++pAny :: PandocMonad m => TagParser m (Tag Text)+pAny = pSatisfy (const True)++isSpace :: Char -> Bool+isSpace ' ' = True+isSpace '\t' = True+isSpace '\n' = True+isSpace '\r' = True+isSpace _ = False++-- taken from HXT and extended+-- See http://www.w3.org/TR/html5/syntax.html sec 8.1.2.4 optional tags+closes :: Text -> Text -> Bool+_ `closes` "body" = False+_ `closes` "html" = False+"body" `closes` "head" = True+"a" `closes` "a" = True+"li" `closes` "li" = True+"th" `closes` t | t `elem` ["th","td"] = True+"td" `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+-- https://html.spec.whatwg.org/multipage/syntax.html#optional-tags+x `closes` "p" | x `elem` ["address", "article", "aside", "blockquote",+ "dir", "div", "dl", "fieldset", "footer", "form", "h1", "h2", "h3", "h4",+ "h5", "h6", "header", "hr", "main", "menu", "nav", "ol", "p", "pre", "section",+ "table", "ul"] = True+_ `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` "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","main","p"] &&+ t2 `elem` ["h1","h2","h3","h4","h5","h6","p" ] = True -- not "div" or "main"+t1 `closes` t2 |+ t1 `Set.member` blockTags &&+ t2 `Set.notMember` blockTags &&+ t2 `Set.notMember` eitherBlockOrInline = True+_ `closes` _ = False++toStringAttr :: [(Text, Text)] -> [(Text, Text)]+toStringAttr = foldr go []+ where+ go :: (Text, Text) -> [(Text, Text)] -> [(Text, Text)]+ -- treat xml:lang as lang+ go ("xml:lang",y) ats = go ("lang",y) ats+ -- prevent duplicate attributes+ go (x,y) ats+ | any (\(x',_) -> x == x') ats = ats+ | otherwise =+ case T.stripPrefix "data-" x of+ Just x' | x' `Set.notMember` (html5Attributes <>+ html4Attributes <> rdfaAttributes)+ -> go (x',y) ats+ _ -> (x,y):ats++-- Unlike fromAttrib from tagsoup, this distinguishes+-- between a missing attribute and an attribute with empty content.+maybeFromAttrib :: Text -> Tag Text -> Maybe Text+maybeFromAttrib name (TagOpen _ attrs) = lookup name attrs+maybeFromAttrib _ _ = Nothing++mkAttr :: [(Text, Text)] -> Attr+mkAttr attr = (attribsId, attribsClasses, attribsKV)+ where attribsId = fromMaybe "" $ lookup "id" attr+ attribsClasses = T.words (fromMaybe "" $ lookup "class" attr) <> epubTypes+ attribsKV = filter (\(k,_) -> k /= "class" && k /= "id") attr+ epubTypes = T.words $ fromMaybe "" $ lookup "epub:type" attr++toAttr :: [(Text, Text)] -> Attr+toAttr = mkAttr . toStringAttr
@@ -0,0 +1,263 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns #-}+{- |+ Module : Text.Pandoc.Readers.HTML.Table+ Copyright : © 2006-2020 John MacFarlane,+ 2020 Albert Krewinkel+ License : GNU GPL, version 2 or above++ Maintainer : Albert Krewinkel <albert@zeitkraut.de>+ Stability : alpha+ Portability : portable++HTML table parser.+-}+module Text.Pandoc.Readers.HTML.Table (pTable) where++import Control.Applicative ((<|>))+import Data.Maybe (fromMaybe)+import Data.Text (Text)+import Text.HTML.TagSoup+import Text.Pandoc.Builder (Blocks)+import Text.Pandoc.CSS (cssAttributes)+import Text.Pandoc.Definition+import Text.Pandoc.Class.PandocMonad (PandocMonad (..))+import Text.Pandoc.Parsing+ ( eof, lookAhead, many, many1, manyTill, option, optional+ , optionMaybe, skipMany, try)+import Text.Pandoc.Readers.HTML.Parsing+import Text.Pandoc.Readers.HTML.Types (TagParser)+import Text.Pandoc.Shared (onlySimpleTableCells, safeRead)+import qualified Data.Text as T+import qualified Text.Pandoc.Builder as B++-- | Parses a @<col>@ element, returning the column's width. Defaults to+-- @'ColWidthDefault'@ if the width is not set or cannot be determined.+pCol :: PandocMonad m => TagParser m ColWidth+pCol = try $ do+ TagOpen _ attribs' <- pSatisfy (matchTagOpen "col" [])+ let attribs = toStringAttr attribs'+ skipMany pBlank+ optional $ pSatisfy (matchTagClose "col")+ skipMany pBlank+ let width = case lookup "width" attribs of+ Nothing -> case lookup "style" attribs of+ Just (T.stripPrefix "width:" -> Just xs) | T.any (== '%') xs ->+ fromMaybe 0.0 $ safeRead (T.filter+ (`notElem` (" \t\r\n%'\";" :: [Char])) xs)+ _ -> 0.0+ Just (T.unsnoc -> Just (xs, '%')) ->+ fromMaybe 0.0 $ safeRead xs+ _ -> 0.0+ if width > 0.0+ then return $ ColWidth $ width / 100.0+ else return ColWidthDefault++pColgroup :: PandocMonad m => TagParser m [ColWidth]+pColgroup = try $ do+ pSatisfy (matchTagOpen "colgroup" [])+ skipMany pBlank+ manyTill pCol (pCloses "colgroup" <|> eof) <* skipMany pBlank++data CellType+ = HeaderCell+ | BodyCell+ deriving Eq++pCell :: PandocMonad m+ => TagParser m Blocks+ -> CellType+ -> TagParser m (CellType, Cell)+pCell block celltype = try $ do+ let celltype' = case celltype of+ HeaderCell -> "th"+ BodyCell -> "td"+ skipMany pBlank+ TagOpen _ attribs <- lookAhead $ pSatisfy (matchTagOpen celltype' [])+ let cssAttribs = maybe [] cssAttributes $ lookup "style" attribs+ let align = case lookup "align" attribs <|>+ lookup "text-align" cssAttribs of+ Just "left" -> AlignLeft+ Just "right" -> AlignRight+ Just "center" -> AlignCenter+ _ -> AlignDefault+ let rowspan = RowSpan . fromMaybe 1 $+ safeRead =<< lookup "rowspan" attribs+ let colspan = ColSpan . fromMaybe 1 $+ safeRead =<< lookup "colspan" attribs+ res <- pInTags celltype' block+ skipMany pBlank+ let handledAttribs = ["align", "colspan", "rowspan", "text-align"]+ attribs' = foldr go [] attribs+ go kv@(k, _) acc = case k of+ "style" -> case filter ((/= "text-align") . fst) cssAttribs of+ [] -> acc+ cs -> ("style", toStyleString cs) : acc+ -- drop attrib if it's already handled+ _ | k `elem` handledAttribs -> acc+ _ -> kv : acc+ return (celltype, B.cellWith (toAttr attribs') align rowspan colspan res)++-- | Create a style attribute string from a list of CSS attributes+toStyleString :: [(Text, Text)] -> Text+toStyleString = T.intercalate "; " . map (\(k, v) -> k <> ": " <> v)++-- | Parses a normal table row; returns the row together with the number+-- of header cells at the beginning of the row.+pRow :: PandocMonad m+ => TagParser m Blocks+ -> TagParser m (RowHeadColumns, B.Row)+pRow block = try $ do+ skipMany pBlank+ TagOpen _ attribs <- pSatisfy (matchTagOpen "tr" []) <* skipMany pBlank+ cells <- many (pCell block BodyCell <|> pCell block HeaderCell)+ TagClose _ <- pSatisfy (matchTagClose "tr")+ return ( RowHeadColumns $ length (takeWhile ((== HeaderCell) . fst) cells)+ , Row (toAttr attribs) $ map snd cells+ )++-- | Parses a header row, i.e., a row which containing nothing but+-- @<th>@ elements.+pHeaderRow :: PandocMonad m+ => TagParser m Blocks+ -> TagParser m B.Row+pHeaderRow block = try $ do+ skipMany pBlank+ let pThs = map snd <$> many (pCell block HeaderCell)+ let mkRow (attribs, cells) = Row (toAttr attribs) cells+ mkRow <$> pInTagWithAttribs TagsRequired "tr" pThs++-- | Parses a table head. If there is no @thead@ element, this looks for+-- a row of @<th>@-only elements as the first line of the table.+pTableHead :: PandocMonad m+ => TagParser m Blocks+ -> TagParser m TableHead+pTableHead block = try $ do+ skipMany pBlank+ let pRows = many (pRow block)+ let pThead = pInTagWithAttribs ClosingTagOptional "thead" pRows+ optionMaybe pThead >>= \case+ Just (attribs, rows) ->+ return $ TableHead (toAttr attribs) $ map snd rows+ Nothing -> mkTableHead <$> optionMaybe (pHeaderRow block)+ where+ mkTableHead = TableHead nullAttr . \case+ -- Use row as header only if it's non-empty+ Just row@(Row _ (_:_)) -> [row]+ _ -> []++-- | Parses a table foot+pTableFoot :: PandocMonad m+ => TagParser m Blocks+ -> TagParser m TableFoot+pTableFoot block = try $ do+ skipMany pBlank+ TagOpen _ attribs <- pSatisfy (matchTagOpen "tfoot" []) <* skipMany pBlank+ rows <- many (fmap snd $ pRow block <* skipMany pBlank)+ optional $ pSatisfy (matchTagClose "tfoot")+ return $ TableFoot (toAttr attribs) rows++-- | Parses a table body+pTableBody :: PandocMonad m+ => TagParser m Blocks+ -> TagParser m TableBody+pTableBody block = try $ do+ skipMany pBlank+ attribs <- option [] $ getAttribs <$> pSatisfy (matchTagOpen "tbody" [])+ <* skipMany pBlank+ bodyheads <- many (pHeaderRow block)+ (rowheads, rows) <- unzip <$> many1 (pRow block <* skipMany pBlank)+ optional $ pSatisfy (matchTagClose "tbody")+ return $ TableBody (toAttr attribs) (foldr max 0 rowheads) bodyheads rows+ where+ getAttribs (TagOpen _ attribs) = attribs+ getAttribs _ = []++-- | Parses a simple HTML table+pTable :: PandocMonad m+ => TagParser m Blocks -- ^ Caption and cell contents parser+ -> TagParser m Blocks+pTable block = try $ do+ TagOpen _ attribs <- pSatisfy (matchTagOpen "table" []) <* skipMany pBlank+ caption <- option mempty $ pInTags "caption" block <* skipMany pBlank+ widths <- ((mconcat <$> many1 pColgroup) <|> many pCol) <* skipMany pBlank+ thead <- pTableHead block <* skipMany pBlank+ topfoot <- optionMaybe (pTableFoot block) <* skipMany pBlank+ tbodies <- many (pTableBody block) <* skipMany pBlank+ botfoot <- optionMaybe (pTableFoot block) <* skipMany pBlank+ TagClose _ <- pSatisfy (matchTagClose "table")+ let tfoot = fromMaybe (TableFoot nullAttr []) $ topfoot <|> botfoot+ case normalize widths thead tbodies tfoot of+ Left err -> fail err+ Right (colspecs, thead', tbodies', tfoot') -> return $+ B.tableWith (toAttr attribs)+ (B.simpleCaption caption)+ colspecs+ thead'+ tbodies'+ tfoot'+data TableType+ = SimpleTable+ | NormalTable++tableType :: [[Cell]] -> TableType+tableType cells =+ if onlySimpleTableCells $ map (map cellContents) cells+ then SimpleTable+ else NormalTable+ where+ cellContents :: Cell -> [Block]+ cellContents (Cell _ _ _ _ bs) = bs++normalize :: [ColWidth] -> TableHead -> [TableBody] -> TableFoot+ -> Either String ([ColSpec], TableHead, [TableBody], TableFoot)+normalize widths head' bodies foot = do+ let rows = headRows head' <> concatMap bodyRows bodies <> footRows foot+ let cellWidth (Cell _ _ _ (ColSpan cs) _) = cs+ let rowLength = foldr (\cell acc -> cellWidth cell + acc) 0 . rowCells+ let ncols = maximum (map rowLength rows)+ let tblType = tableType (map rowCells rows)+ -- fail on empty table+ if null rows+ then Left "empty table"+ else Right+ ( zip (calculateAlignments ncols bodies)+ (normalizeColWidths ncols tblType widths)+ , head'+ , bodies+ , foot+ )++normalizeColWidths :: Int -> TableType -> [ColWidth] -> [ColWidth]+normalizeColWidths ncols tblType = \case+ [] -> case tblType of+ SimpleTable -> replicate ncols ColWidthDefault+ NormalTable -> replicate ncols (ColWidth $ 1 / fromIntegral ncols)+ widths -> widths++calculateAlignments :: Int -> [TableBody] -> [Alignment]+calculateAlignments cols tbodies =+ case cells of+ cs:_ -> take cols $ concatMap cellAligns cs ++ repeat AlignDefault+ _ -> replicate cols AlignDefault+ where+ cells :: [[Cell]]+ cells = concatMap bodyRowCells tbodies+ cellAligns :: Cell -> [Alignment]+ cellAligns (Cell _ align _ (ColSpan cs) _) = replicate cs align++bodyRowCells :: TableBody -> [[Cell]]+bodyRowCells = map rowCells . bodyRows++headRows :: TableHead -> [B.Row]+headRows (TableHead _ rows) = rows++bodyRows :: TableBody -> [B.Row]+bodyRows (TableBody _ _ headerRows bodyRows') = headerRows <> bodyRows'++footRows :: TableFoot -> [B.Row]+footRows (TableFoot _ rows) = rows++rowCells :: B.Row -> [Cell]+rowCells (Row _ cells) = cells
@@ -0,0 +1,78 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+ Module : Text.Pandoc.Readers.HTML.TagCategories+ Copyright : Copyright (C) 2006-2020 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Categories of tags.+-}+module Text.Pandoc.Readers.HTML.TagCategories+ ( blockHtmlTags+ , blockDocBookTags+ , eitherBlockOrInline+ , epubTags+ , blockTags+ , sectioningContent+ , groupingContent+ )+where++import Data.Set (Set, fromList, unions)+import Data.Text (Text)++eitherBlockOrInline :: Set Text+eitherBlockOrInline = fromList+ ["audio", "applet", "button", "iframe", "embed",+ "del", "ins", "progress", "map", "area", "noscript", "script",+ "object", "svg", "video", "source"]++blockHtmlTags :: Set Text+blockHtmlTags = fromList+ ["?xml", "!DOCTYPE", "address", "article", "aside",+ "blockquote", "body", "canvas",+ "caption", "center", "col", "colgroup", "dd", "details",+ "dir", "div", "dl", "dt", "fieldset", "figcaption", "figure",+ "footer", "form", "h1", "h2", "h3", "h4",+ "h5", "h6", "head", "header", "hgroup", "hr", "html",+ "isindex", "main", "menu", "meta", "noframes", "nav",+ "ol", "output", "p", "pre",+ "section", "summary", "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 :: Set Text+blockDocBookTags = fromList+ ["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 :: Set Text+epubTags = fromList ["case", "switch", "default"]++blockTags :: Set Text+blockTags = unions [blockHtmlTags, blockDocBookTags, epubTags]++sectioningContent :: [Text]+sectioningContent = ["article", "aside", "nav", "section"]+++groupingContent :: [Text]+groupingContent = ["p", "hr", "pre", "blockquote", "ol"+ , "ul", "li", "dl", "dt", "dt", "dd"+ , "figure", "figcaption", "div", "main"]
@@ -0,0 +1,97 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{- |+ Module : Text.Pandoc.Readers.HTML.Types+ Copyright : Copyright (C) 2006-2020 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Types for pandoc's HTML reader.+-}+module Text.Pandoc.Readers.HTML.Types+ ( TagParser+ , HTMLParser+ , HTMLState (..)+ , HTMLLocal (..)+ )+where++import Control.Monad.Reader (ReaderT, asks, local)+import Data.Default (Default (def))+import Data.Map (Map)+import Data.Set (Set)+import Data.Text (Text)+import Network.URI (URI)+import Text.HTML.TagSoup+import Text.Pandoc.Builder (Blocks, HasMeta (..))+import Text.Pandoc.Class.PandocMonad (PandocMonad (..))+import Text.Pandoc.Logging (LogMessage)+import Text.Pandoc.Options (ReaderOptions)+import Text.Pandoc.Parsing+ ( HasIdentifierList (..), HasLastStrPosition (..), HasLogMessages (..)+ , HasMacros (..), HasQuoteContext (..), HasReaderOptions (..)+ , ParserT, ParserState, QuoteContext (NoQuote)+ )+import Text.Pandoc.Readers.LaTeX.Types (Macro)++-- | HTML parser type+type HTMLParser m s = ParserT s HTMLState (ReaderT HTMLLocal m)++-- | HTML parser, expecting @Tag Text@ as tokens.+type TagParser m = HTMLParser m [Tag Text]++-- | Global HTML parser state+data HTMLState = HTMLState+ { parserState :: ParserState+ , noteTable :: [(Text, Blocks)]+ , baseHref :: Maybe URI+ , identifiers :: Set Text+ , logMessages :: [LogMessage]+ , macros :: Map Text Macro+ , readerOpts :: ReaderOptions+ }++-- | Local HTML parser state+data HTMLLocal = HTMLLocal+ { quoteContext :: QuoteContext+ , inChapter :: Bool -- ^ Set if in chapter section+ , inPlain :: Bool -- ^ Set if in pPlain+ }+++-- Instances++instance HasMacros HTMLState where+ extractMacros = macros+ updateMacros f st = st{ macros = f $ macros st }++instance HasIdentifierList HTMLState where+ extractIdentifierList = identifiers+ updateIdentifierList f s = s{ identifiers = f (identifiers s) }++instance HasLogMessages HTMLState where+ addLogMessage m s = s{ logMessages = m : logMessages s }+ getLogMessages = reverse . logMessages++-- This signature should be more general+-- MonadReader HTMLLocal m => HasQuoteContext st m+instance PandocMonad m => HasQuoteContext HTMLState (ReaderT HTMLLocal m) where+ getQuoteContext = asks quoteContext+ withQuoteContext q = local (\s -> s{quoteContext = q})++instance HasReaderOptions HTMLState where+ extractReaderOptions = extractReaderOptions . parserState++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
@@ -559,7 +559,14 @@ return $ str t opt :: PandocMonad m => LP m Inlines-opt = bracketed inline <|> (str <$> rawopt)+opt = do+ toks <- try (sp *> bracketedToks <* sp)+ -- now parse the toks as inlines+ st <- getState+ parsed <- runParserT (mconcat <$> many inline) st "bracketed option" toks+ case parsed of+ Right result -> return result+ Left e -> throwError $ PandocParsecError (untokenize toks) e paropt :: PandocMonad m => LP m Inlines paropt = parenWrapped inline@@ -1218,6 +1225,16 @@ anyTok return mempty) +rule :: PandocMonad m => LP m Blocks+rule = do+ skipopts+ width <- T.takeWhile (\c -> isDigit c || c == '.') . stringify <$> tok+ _thickness <- tok+ -- 0-width rules are used to fix spacing issues:+ case safeRead width of+ Just (0 :: Double) -> return mempty+ _ -> return horizontalRule+ paragraph :: PandocMonad m => LP m Blocks paragraph = do x <- trimInlines . mconcat <$> many1 inline@@ -1588,7 +1605,7 @@ -- , ("hrule", pure horizontalRule) , ("strut", pure mempty)- , ("rule", skipopts *> tok *> tok $> horizontalRule)+ , ("rule", rule) , ("item", looseItem) , ("documentclass", skipopts *> braced *> preamble) , ("centerline", para . trimInlines <$> (skipopts *> tok))@@ -1639,7 +1656,7 @@ skipopts *> spaces *> optional braced *> spaces *> blocks) , ("figure", env "figure" $ skipopts *> figure) , ("subfigure", env "subfigure" $ skipopts *> tok *> figure)- , ("center", env "center" blocks)+ , ("center", divWith ("", ["center"], []) <$> env "center" blocks) , ("longtable", env "longtable" $ resetCaption *> simpTable "longtable" False >>= addTableCaption) , ("table", env "table" $@@ -1795,6 +1812,7 @@ _ -> bs italicize :: Block -> Block+italicize x@(Para [Image{}]) = x -- see #6925 italicize (Para ils) = Para [Emph ils] italicize (Plain ils) = Plain [Emph ils] italicize x = x
@@ -477,17 +477,17 @@ internalLink :: Text -> Inlines -> F Inlines internalLink link title = do- anchorB <- (link `elem`) <$> asksF orgStateAnchorIds- if anchorB+ ids <- asksF orgStateAnchorIds+ if link `elem` ids then return $ B.link ("#" <> link) "" title- else return $ B.emph title+ else let attr' = ("", ["spurious-link"] , [("target", link)])+ in return $ B.spanWith attr' (B.emph title) -- | Parse an anchor like @<<anchor-id>>@ and return an empty span with -- @anchor-id@ set as id. Legal anchors in org-mode are defined through -- @org-target-regexp@, which is fairly liberal. Since no link is created if -- @anchor-id@ contains spaces, we are more restrictive in what is accepted as -- an anchor.- anchor :: PandocMonad m => OrgParser m (F Inlines) anchor = try $ do anchorId <- parseAnchor@@ -501,7 +501,6 @@ -- | Replace every char but [a-zA-Z0-9_.-:] with a hyphen '-'. This mirrors -- the org function @org-export-solidify-link-text@.- solidify :: Text -> Text solidify = T.map replaceSpecialChar where replaceSpecialChar c
@@ -93,6 +93,8 @@ , "institute" ~~> lineOfInlines `parseThen` collectLines "institute" -- topic keywords , "keywords" ~~> lineOfInlines `parseThen` collectLines "keywords"+ -- document language+ , "language" ~~> fmap pure anyLine `parseThen` B.setMeta "lang" -- LaTeX-specific export settings , "latex_class" ~~> fmap pure anyLine `parseThen` B.setMeta "documentclass" , "latex_class_options" ~~>
@@ -15,6 +15,7 @@ module Text.Pandoc.Writers.Docbook ( writeDocbook4, writeDocbook5 ) where import Control.Monad.Reader import Data.Generics (everywhere, mkT)+import Data.Maybe (isNothing) import Data.Monoid (Any (..)) import Data.Text (Text) import qualified Data.Text as T@@ -40,6 +41,25 @@ type DB = ReaderT DocBookVersion +-- | Get level of the top-level headers based on the configured top-level division.+-- The header level can then be used to determine appropriate DocBook element+-- for each subdivision associated with a header.+-- The numbering here follows LaTeX's internal numbering+getStartLvl :: WriterOptions -> Int+getStartLvl opts =+ case writerTopLevelDivision opts of+ TopLevelPart -> -1+ TopLevelChapter -> 0+ TopLevelSection -> 1+ TopLevelDefault -> 1++-- | Get correct name for the id attribute based on DocBook version.+-- DocBook 4 used custom id attribute but DocBook 5 adopted the xml:id specification.+-- https://www.w3.org/TR/xml-id/+idName :: DocBookVersion -> Text+idName DocBook5 = "xml:id"+idName DocBook4 = "id"+ -- | Convert list of authors to a docbook <author> section authorToDocbook :: PandocMonad m => WriterOptions -> [Inline] -> DB m B.Inlines authorToDocbook opts name' = do@@ -79,12 +99,7 @@ let colwidth = if writerWrapText opts == WrapAuto then Just $ writerColumns opts else Nothing- -- The numbering here follows LaTeX's internal numbering- let startLvl = case writerTopLevelDivision opts of- TopLevelPart -> -1- TopLevelChapter -> 0- TopLevelSection -> 1- TopLevelDefault -> 1+ let startLvl = getStartLvl opts let fromBlocks = blocksToDocbook opts . makeSections False (Just startLvl) auths' <- mapM (authorToDocbook opts) $ docAuthors meta@@ -166,28 +181,50 @@ then "section" else "sect" <> tshow n _ -> "simplesect"- idName = if version == DocBook5- then "xml:id"- else "id"- idAttr = [(idName, writerIdentifierPrefix opts <> id') | not (T.null id')]- nsAttr = if version == DocBook5 && lvl == 0 then [("xmlns", "http://docbook.org/ns/docbook"),("xmlns:xlink", "http://www.w3.org/1999/xlink")]- else []+ idAttr = [(idName version, writerIdentifierPrefix opts <> id') | not (T.null id')]+ -- We want to add namespaces to the root (top-level) element.+ nsAttr = if version == DocBook5 && lvl == getStartLvl opts && isNothing (writerTemplate opts)+ -- Though, DocBook 4 does not support namespaces and+ -- standalone documents will include them in the template.+ then [("xmlns", "http://docbook.org/ns/docbook"),("xmlns:xlink", "http://www.w3.org/1999/xlink")]+ else [] attribs = nsAttr <> idAttr title' <- inlinesToDocbook opts ils contents <- blocksToDocbook opts bs return $ inTags True tag attribs $ inTagsSimple "title" title' $$ contents-blockToDocbook opts (Div (ident,_,_) [Para lst]) =- let attribs = [("id", ident) | not (T.null ident)] in- if hasLineBreaks lst- then flush . nowrap . inTags False "literallayout" attribs- <$> inlinesToDocbook opts lst- else inTags True "para" attribs <$> inlinesToDocbook opts lst-blockToDocbook opts (Div (ident,_,_) bs) = do- contents <- blocksToDocbook opts (map plainToPara bs)- return $- (if T.null ident- then mempty- else selfClosingTag "anchor" [("id", ident)]) $$ contents+blockToDocbook opts (Div (ident,classes,_) bs) = do+ version <- ask+ let identAttribs = [(idName version, ident) | not (T.null ident)]+ admonitions = ["attention","caution","danger","error","hint",+ "important","note","tip","warning"]+ case classes of+ (l:_) | l `elem` admonitions -> do+ let (mTitleBs, bodyBs) =+ case bs of+ -- Matches AST produced by the DocBook reader → Markdown writer → Markdown reader chain.+ (Div (_,["title"],_) [Para ts] : rest) -> (Just (inlinesToDocbook opts ts), rest)+ -- Matches AST produced by the Docbook reader.+ (Div (_,["title"],_) ts : rest) -> (Just (blocksToDocbook opts ts), rest)+ _ -> (Nothing, bs)+ admonitionTitle <- case mTitleBs of+ Nothing -> return mempty+ -- id will be attached to the admonition so let’s pass empty identAttrs.+ Just titleBs -> inTags False "title" [] <$> titleBs+ admonitionBody <- handleDivBody [] bodyBs+ return (inTags True l identAttribs (admonitionTitle $$ admonitionBody))+ _ -> handleDivBody identAttribs bs+ where+ handleDivBody identAttribs [Para lst] =+ if hasLineBreaks lst+ then flush . nowrap . inTags False "literallayout" identAttribs+ <$> inlinesToDocbook opts lst+ else inTags True "para" identAttribs <$> inlinesToDocbook opts lst+ handleDivBody identAttribs bodyBs = do+ contents <- blocksToDocbook opts (map plainToPara bodyBs)+ return $+ (if null identAttribs+ then mempty+ else selfClosingTag "anchor" identAttribs) $$ contents blockToDocbook _ h@Header{} = do -- should be handled by Div section above, except inside lists/blockquotes report $ BlockNotRendered h@@ -341,11 +378,12 @@ inTagsSimple "quote" <$> inlinesToDocbook opts lst inlineToDocbook opts (Cite _ lst) = inlinesToDocbook opts lst-inlineToDocbook opts (Span (ident,_,_) ils) =+inlineToDocbook opts (Span (ident,_,_) ils) = do+ version <- ask ((if T.null ident then mempty- else selfClosingTag "anchor" [("id", ident)]) <>) <$>- inlinesToDocbook opts ils+ else selfClosingTag "anchor" [(idName version, ident)]) <>) <$>+ inlinesToDocbook opts ils inlineToDocbook _ (Code _ str) = return $ inTagsSimple "literal" $ literal (escapeStringForXML str) inlineToDocbook opts (Math t str)
@@ -441,7 +441,7 @@ Nothing -> mknode "w:sectPr" [] () -- let sectpr = fromMaybe (mknode "w:sectPr" [] ()) mbsectpr'- let contents' = contents ++ [sectpr]+ let contents' = contents ++ [Elem sectpr] let docContents = mknode "w:document" stdAttributes $ mknode "w:body" [] contents' @@ -538,7 +538,8 @@ -- docProps/custom.xml let customProperties :: [(String, String)]- customProperties = [(T.unpack k, T.unpack $ lookupMetaString k meta) | k <- M.keys (unMeta meta)+ customProperties = [ (T.unpack k, T.unpack $ lookupMetaString k meta)+ | k <- M.keys (unMeta meta) , k `notElem` (["title", "author", "keywords"] ++ extraCoreProps)] let mkCustomProp (k, v) pid = mknode "property"@@ -732,9 +733,9 @@ , 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)] ()+ [ mknode "w:ind" [ ("w:left",show $ lvl * step + step)+ , ("w:hanging",show (hang :: Int))+ ] () ] ] where (fmt, lvltxt, start) =@@ -788,7 +789,7 @@ mknode "w:docPartUnique" [] ()] -- w:docPartObj ), -- w:sdtPr- mknode "w:sdtContent" [] (title++[+ mknode "w:sdtContent" [] (title ++ [ Elem $ mknode "w:p" [] ( mknode "w:r" [] [ mknode "w:fldChar" [("w:fldCharType","begin"),("w:dirty","true")] (),@@ -802,7 +803,9 @@ -- | Convert Pandoc document to two lists of -- OpenXML elements (the main document and footnotes).-writeOpenXML :: (PandocMonad m) => WriterOptions -> Pandoc -> WS m ([Element], [Element],[Element])+writeOpenXML :: (PandocMonad m)+ => WriterOptions -> Pandoc+ -> WS m ([Content], [Element], [Element]) writeOpenXML opts (Pandoc meta blocks) = do let tit = docTitle meta let auths = docAuthors meta@@ -830,6 +833,7 @@ return $ mknode "w:comment" [('w':':':T.unpack k,T.unpack v) | (k,v) <- kvs] [ mknode "w:p" [] $+ map Elem [ mknode "w:pPr" [] [ mknode "w:pStyle" [("w:val", "CommentText")] () ] , mknode "w:r" []@@ -844,11 +848,11 @@ toc <- if includeTOC then makeTOC opts else return []- let meta' = title ++ subtitle ++ authors ++ date ++ abstract ++ toc+ let meta' = title ++ subtitle ++ authors ++ date ++ abstract ++ map Elem toc return (meta' ++ doc', notes', comments') -- | Convert a list of Pandoc blocks to OpenXML.-blocksToOpenXML :: (PandocMonad m) => WriterOptions -> [Block] -> WS m [Element]+blocksToOpenXML :: (PandocMonad m) => WriterOptions -> [Block] -> WS m [Content] blocksToOpenXML opts = fmap concat . mapM (blockToOpenXML opts) . separateTables -- Word combines adjacent tables unless you put an empty paragraph between@@ -884,10 +888,10 @@ dynamicStyleKey = "custom-style" -- | Convert a Pandoc block element to OpenXML.-blockToOpenXML :: (PandocMonad m) => WriterOptions -> Block -> WS m [Element]+blockToOpenXML :: (PandocMonad m) => WriterOptions -> Block -> WS m [Content] blockToOpenXML opts blk = withDirection $ blockToOpenXML' opts blk -blockToOpenXML' :: (PandocMonad m) => WriterOptions -> Block -> WS m [Element]+blockToOpenXML' :: (PandocMonad m) => WriterOptions -> Block -> WS m [Content] blockToOpenXML' _ Null = return [] blockToOpenXML' opts (Div (ident,_classes,kvs) bs) = do stylemod <- case lookup dynamicStyleKey kvs of@@ -921,18 +925,18 @@ Just n -> do num <- withTextPropM (rStyleM "SectionNumber") (inlineToOpenXML opts (Str n))- return $ num ++ [mknode "w:r" [] [mknode "w:tab" [] ()]]+ return $ num ++ [Elem $ mknode "w:r" [] [mknode "w:tab" [] ()]] Nothing -> return [] else return [] contents <- (number ++) <$> inlinesToOpenXML opts lst if T.null ident- then return [mknode "w:p" [] (paraProps ++ contents)]+ then return [Elem $ mknode "w:p" [] (map Elem paraProps ++ contents)] else do let bookmarkName = ident modify $ \s -> s{ stSectionIds = Set.insert bookmarkName $ stSectionIds s } bookmarkedContents <- wrapBookmark bookmarkName contents- return [mknode "w:p" [] (paraProps ++ bookmarkedContents)]+ return [Elem $ mknode "w:p" [] (map Elem paraProps ++ bookmarkedContents)] blockToOpenXML' opts (Plain lst) = do isInTable <- gets stInTable isInList <- gets stInList@@ -952,7 +956,9 @@ contents <- inlinesToOpenXML opts [Image attr alt (src,tit)] captionNode <- withParaPropM (pStyleM "Image Caption") $ blockToOpenXML opts (Para alt)- return $ mknode "w:p" [] (paraProps ++ contents) : captionNode+ return $+ Elem (mknode "w:p" [] (map Elem paraProps ++ contents))+ : captionNode blockToOpenXML' opts (Para lst) | null lst && not (isEnabled Ext_empty_paragraphs opts) = return [] | otherwise = do@@ -969,10 +975,12 @@ ps -> ps modify $ \s -> s { stFirstPara = False } contents <- inlinesToOpenXML opts lst- return [mknode "w:p" [] (paraProps' ++ contents)]+ return [Elem $ mknode "w:p" [] (map Elem paraProps' ++ contents)] blockToOpenXML' opts (LineBlock lns) = blockToOpenXML opts $ linesToPara lns blockToOpenXML' _ b@(RawBlock format str)- | format == Format "openxml" = return [ x | Elem x <- parseXML str ]+ | format == Format "openxml" = return [+ Text (CData CDataRaw (T.unpack str) Nothing)+ ] | otherwise = do report $ BlockNotRendered b return []@@ -987,7 +995,7 @@ wrapBookmark ident p blockToOpenXML' _ HorizontalRule = do setFirstPara- return [+ return [ Elem $ mknode "w:p" [] $ mknode "w:r" [] $ mknode "w:pict" [] $ mknode "v:rect" [("style","width:0;height:1.5pt"), ("o:hralign","center"),@@ -1006,26 +1014,28 @@ -- Not in the spec but in Word 2007, 2010. See #4953. let cellToOpenXML (al, cell) = do es <- withParaProp (alignmentFor al) $ blocksToOpenXML opts cell- return $ if any (\e -> qName (elName e) == "p") es+ return $ if any (\e -> qName (elName e) == "p") (onlyElems es) then es- else es ++ [mknode "w:p" [] ()]+ else es ++ [Elem $ mknode "w:p" [] ()] headers' <- mapM cellToOpenXML $ zip aligns headers rows' <- mapM (mapM cellToOpenXML . zip aligns) rows- let borderProps = mknode "w:tcPr" []+ let borderProps = Elem $ mknode "w:tcPr" [] [ mknode "w:tcBorders" [] $ mknode "w:bottom" [("w:val","single")] () , mknode "w:vAlign" [("w:val","bottom")] () ] compactStyle <- pStyleM "Compact"- let emptyCell' = [mknode "w:p" [] [mknode "w:pPr" [] [compactStyle]]]+ let emptyCell' = [Elem $ mknode "w:p" [] [mknode "w:pPr" [] [compactStyle]]] let mkcell border contents = mknode "w:tc" [] $ [ borderProps | border ] ++ if null contents then emptyCell' else contents- let mkrow border cells = mknode "w:tr" [] $- [mknode "w:trPr" [] [- mknode "w:cnfStyle" [("w:firstRow","1")] ()] | border]- ++ map (mkcell border) cells+ let mkrow border cells =+ mknode "w:tr" [] $+ [ mknode "w:trPr" []+ [ mknode "w:cnfStyle" [("w:firstRow","1")] ()]+ | border]+ ++ 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@@ -1035,7 +1045,8 @@ modify $ \s -> s { stInTable = False } return $ caption' ++- [mknode "w:tbl" []+ [Elem $+ mknode "w:tbl" [] ( mknode "w:tblPr" [] ( mknode "w:tblStyle" [("w:val","Table")] () : mknode "w:tblW" [("w:type", "pct"), ("w:w", show rowwidth)] () :@@ -1070,7 +1081,9 @@ setFirstPara return l -definitionListItemToOpenXML :: (PandocMonad m) => WriterOptions -> ([Inline],[[Block]]) -> WS m [Element]+definitionListItemToOpenXML :: (PandocMonad m)+ => WriterOptions -> ([Inline],[[Block]])+ -> WS m [Content] definitionListItemToOpenXML opts (term,defs) = do term' <- withParaPropM (pStyleM "Definition Term") $ blockToOpenXML opts (Para term)@@ -1083,8 +1096,11 @@ lists <- gets stLists modify $ \st -> st{ stLists = lists ++ [marker] } -listItemToOpenXML :: (PandocMonad m) => WriterOptions -> Int -> [Block] -> WS m [Element]-listItemToOpenXML _ _ [] = return []+listItemToOpenXML :: (PandocMonad m)+ => WriterOptions+ -> Int -> [Block]+ -> WS m [Content]+listItemToOpenXML _ _ [] = return [] listItemToOpenXML opts numid (first:rest) = do oldInList <- gets stInList modify $ \st -> st{ stInList = True }@@ -1111,7 +1127,7 @@ AlignDefault -> "left" -- | Convert a list of inline elements to OpenXML.-inlinesToOpenXML :: (PandocMonad m) => WriterOptions -> [Inline] -> WS m [Element]+inlinesToOpenXML :: PandocMonad m => WriterOptions -> [Inline] -> WS m [Content] inlinesToOpenXML opts lst = concat `fmap` mapM (inlineToOpenXML opts) lst withNumId :: (PandocMonad m) => Int -> WS m a -> WS m a@@ -1186,12 +1202,12 @@ setFirstPara = modify $ \s -> s { stFirstPara = True } -- | Convert an inline element to OpenXML.-inlineToOpenXML :: PandocMonad m => WriterOptions -> Inline -> WS m [Element]+inlineToOpenXML :: PandocMonad m => WriterOptions -> Inline -> WS m [Content] inlineToOpenXML opts il = withDirection $ inlineToOpenXML' opts il -inlineToOpenXML' :: PandocMonad m => WriterOptions -> Inline -> WS m [Element]+inlineToOpenXML' :: PandocMonad m => WriterOptions -> Inline -> WS m [Content] inlineToOpenXML' _ (Str str) =- formattedString str+ map Elem <$> formattedString str inlineToOpenXML' opts Space = inlineToOpenXML opts (Str " ") inlineToOpenXML' opts SoftBreak = inlineToOpenXML opts (Str " ") inlineToOpenXML' opts (Span ("",["csl-block"],[]) ils) =@@ -1199,10 +1215,11 @@ inlineToOpenXML' opts (Span ("",["csl-left-margin"],[]) ils) = inlinesToOpenXML opts ils inlineToOpenXML' opts (Span ("",["csl-right-inline"],[]) ils) =- ([mknode "w:r" []- (mknode "w:t"- [("xml:space","preserve")]- ("\t" :: String))] ++)+ ([Elem $+ mknode "w:r" []+ (mknode "w:t"+ [("xml:space","preserve")]+ ("\t" :: String))] ++) <$> inlinesToOpenXML opts ils inlineToOpenXML' opts (Span ("",["csl-indent"],[]) ils) = inlinesToOpenXML opts ils@@ -1212,18 +1229,18 @@ let ident' = fromMaybe ident (lookup "id" kvs) kvs' = filter (("id" /=) . fst) kvs modify $ \st -> st{ stComments = (("id",ident'):kvs', ils) : stComments st }- return [ mknode "w:commentRangeStart" [("w:id", T.unpack ident')] () ]+ return [ Elem $ mknode "w:commentRangeStart" [("w:id", T.unpack ident')] () ] inlineToOpenXML' _ (Span (ident,["comment-end"],kvs) _) = -- prefer the "id" in kvs, since that is the one produced by the docx -- reader. let ident' = fromMaybe ident (lookup "id" kvs)- in- return [ mknode "w:commentRangeEnd" [("w:id", T.unpack ident')] ()- , mknode "w:r" []- [ mknode "w:rPr" []- [ mknode "w:rStyle" [("w:val", "CommentReference")] () ]- , mknode "w:commentReference" [("w:id", T.unpack ident')] () ]- ]+ in return . map Elem $+ [ mknode "w:commentRangeEnd" [("w:id", T.unpack ident')] ()+ , mknode "w:r" []+ [ mknode "w:rPr" []+ [ mknode "w:rStyle" [("w:val", "CommentReference")] () ]+ , mknode "w:commentReference" [("w:id", T.unpack ident')] () ]+ ] inlineToOpenXML' opts (Span (ident,classes,kvs) ils) = do stylemod <- case lookup dynamicStyleKey kvs of Just (fromString . T.unpack -> sty) -> do@@ -1255,8 +1272,9 @@ modify $ \s -> s{stInsId = insId + 1} return $ \f -> do x <- f- return [ mknode "w:ins"- (("w:id", show insId) : changeAuthorDate) x]+ return [Elem $+ mknode "w:ins"+ (("w:id", show insId) : changeAuthorDate) x] else return id delmod <- if "deletion" `elem` classes then do@@ -1265,16 +1283,20 @@ modify $ \s -> s{stDelId = delId + 1} return $ \f -> local (\env->env{envInDel=True}) $ do x <- f- return [mknode "w:del"- (("w:id", show delId) : changeAuthorDate) x]+ return [Elem $ mknode "w:del"+ (("w:id", show delId) : changeAuthorDate) x] else return id contents <- insmod $ delmod $ dirmod $ stylemod $ pmod $ inlinesToOpenXML opts ils wrapBookmark ident contents inlineToOpenXML' opts (Strong lst) =- withTextProp (mknode "w:b" [] ()) $ inlinesToOpenXML opts lst+ withTextProp (mknode "w:b" [] ()) $+ withTextProp (mknode "w:bCs" [] ()) $ -- needed for LTR, #6911+ inlinesToOpenXML opts lst inlineToOpenXML' opts (Emph lst) =- withTextProp (mknode "w:i" [] ()) $ inlinesToOpenXML opts lst+ withTextProp (mknode "w:i" [] ()) $+ withTextProp (mknode "w:iCs" [] ()) $ -- needed for LTR, #6911+ inlinesToOpenXML opts lst inlineToOpenXML' opts (Underline lst) = withTextProp (mknode "w:u" [("w:val","single")] ()) $ inlinesToOpenXML opts lst@@ -1290,9 +1312,10 @@ inlineToOpenXML' opts (Strikeout lst) = withTextProp (mknode "w:strike" [] ()) $ inlinesToOpenXML opts lst-inlineToOpenXML' _ LineBreak = return [br]+inlineToOpenXML' _ LineBreak = return [Elem br] inlineToOpenXML' _ il@(RawInline f str)- | f == Format "openxml" = return [ x | Elem x <- parseXML str ]+ | f == Format "openxml" = return+ [Text (CData CDataRaw (T.unpack str) Nothing)] | otherwise = do report $ InlineNotRendered il return []@@ -1305,13 +1328,13 @@ when (mathType == DisplayMath) setFirstPara res <- (lift . lift) (convertMath writeOMML mathType str) case res of- Right r -> return [r]+ Right r -> return [Elem r] Left il -> inlineToOpenXML' opts il inlineToOpenXML' opts (Cite _ lst) = inlinesToOpenXML opts lst inlineToOpenXML' opts (Code attrs str) = do let alltoktypes = [KeywordTok ..] tokTypesMap <- mapM (\tt -> (,) tt <$> rStyleM (fromString $ show tt)) alltoktypes- let unhighlighted = intercalate [br] `fmap`+ let unhighlighted = (map Elem . intercalate [br]) `fmap` mapM formattedString (T.lines str) formatOpenXML _fmtOpts = intercalate [br] . map (map toHlTok) toHlTok (toktype,tok) =@@ -1324,7 +1347,7 @@ then unhighlighted else case highlight (writerSyntaxMap opts) formatOpenXML attrs str of- Right h -> return h+ Right h -> return (map Elem h) Left msg -> do unless (T.null msg) $ report $ CouldNotHighlight msg unhighlighted@@ -1347,14 +1370,14 @@ $ insertNoteRef bs) let newnote = mknode "w:footnote" [("w:id", notenum)] contents modify $ \s -> s{ stFootnotes = newnote : notes }- return [ mknode "w:r" []+ return [ Elem $ mknode "w:r" [] [ mknode "w:rPr" [] footnoteStyle , mknode "w:footnoteReference" [("w:id", notenum)] () ] ] -- internal link: inlineToOpenXML' opts (Link _ txt (T.uncons -> Just ('#', xs),_)) = do contents <- withTextPropM (rStyleM "Hyperlink") $ inlinesToOpenXML opts txt return- [ mknode "w:hyperlink" [("w:anchor", T.unpack $ toBookmarkName xs)] contents ]+ [ Elem $ mknode "w:hyperlink" [("w:anchor", T.unpack $ toBookmarkName xs)] contents ] -- external link: inlineToOpenXML' opts (Link _ txt (src,_)) = do contents <- withTextPropM (rStyleM "Hyperlink") $ inlinesToOpenXML opts txt@@ -1366,7 +1389,7 @@ modify $ \st -> st{ stExternalLinks = M.insert (T.unpack src) i extlinks } return i- return [ mknode "w:hyperlink" [("r:id",id')] contents ]+ return [ Elem $ mknode "w:hyperlink" [("r:id",id')] contents ] inlineToOpenXML' opts (Image attr@(imgident, _, _) alt (src, title)) = do pageWidth <- asks envPrintWidth imgs <- gets stImages@@ -1430,7 +1453,7 @@ imgElt wrapBookmark imgident =<< case stImage of- Just imgData -> return [generateImgElt imgData]+ Just imgData -> return [Elem $ generateImgElt imgData] Nothing -> ( do --try (img, mt) <- P.fetchItem src ident <- ("rId"++) `fmap` getUniqueId@@ -1458,7 +1481,7 @@ else do -- insert mime type to use in constructing [Content_Types].xml modify $ \st -> st { stImages = M.insert (T.unpack src) imgData $ stImages st }- return [generateImgElt imgData]+ return [Elem $ generateImgElt imgData] ) `catchError` ( \e -> do report $ CouldNotFetchResource src $ T.pack (show e)@@ -1508,7 +1531,7 @@ , envTextProperties = EnvProps textStyle textProps' } -wrapBookmark :: (PandocMonad m) => T.Text -> [Element] -> WS m [Element]+wrapBookmark :: (PandocMonad m) => T.Text -> [Content] -> WS m [Content] wrapBookmark "" contents = return contents wrapBookmark ident contents = do id' <- getUniqueId@@ -1516,7 +1539,7 @@ [("w:id", id') ,("w:name", T.unpack $ toBookmarkName ident)] () bookmarkEnd = mknode "w:bookmarkEnd" [("w:id", id')] ()- return $ bookmarkStart : contents ++ [bookmarkEnd]+ return $ Elem bookmarkStart : contents ++ [Elem bookmarkEnd] -- Word imposes a 40 character limit on bookmark names and requires -- that they begin with a letter. So we just use a hash of the
@@ -825,7 +825,12 @@ [ unode "h1" ! [("id","toc-title")] $ tocTitle , unode "ol" ! [("class","toc")] $ tocBlocks ]] let landmarkItems = if epub3- then [ unode "li"+ then unode "li"+ [ unode "a" ! [("href",+ "text/title_page.xhtml")+ ,("epub:type", "titlepage")] $+ ("Title Page" :: String) ] :+ [ unode "li" [ unode "a" ! [("href", "text/cover.xhtml") ,("epub:type", "cover")] $ ("Cover" :: String)] |@@ -834,7 +839,7 @@ [ unode "li" [ unode "a" ! [("href", "#toc") ,("epub:type", "toc")] $- ("Table of contents" :: String)+ ("Table of Contents" :: String) ] | writerTableOfContents opts ] else []@@ -845,7 +850,9 @@ [ unode "ol" landmarkItems ] | not (null landmarkItems)] navData <- lift $ writeHtml opts'{ writerVariables =- Context (M.fromList [("navpage", toVal' "true")])+ Context (M.fromList [("navpage", toVal' "true")+ ,("body-type", toVal' "frontmatter")+ ]) <> cssvars False <> vars } (Pandoc (setMeta "title" (walk removeNote $ fromList $ docTitle' meta) nullMeta)
@@ -695,12 +695,12 @@ let fragmentClass = case slideVariant of RevealJsSlides -> "fragment" _ -> "incremental"- let inDiv zs = RawBlock (Format "html") ("<div class=\""+ let inDiv' zs = RawBlock (Format "html") ("<div class=\"" <> fragmentClass <> "\">") : (zs ++ [RawBlock (Format "html") "</div>"]) let breakOnPauses zs = case splitBy isPause zs of [] -> []- y:ys -> y ++ concatMap inDiv ys+ y:ys -> y ++ concatMap inDiv' ys let (titleBlocks, innerSecs) = if titleSlide -- title slides have no content of their own@@ -783,9 +783,7 @@ -- a newline between the column divs, which throws -- off widths! see #4028 mconcat <$> mapM (blockToHtml opts) bs- else if isCslBibEntry- then mconcat <$> mapM (cslEntryToHtml opts') bs- else blockListToHtml opts' bs+ else blockListToHtml opts' bs let contents' = nl opts >> contents >> nl opts let (divtag, classes'') = if html5 && "section" `elem` classes' then (H5.section, filter (/= "section") classes')@@ -1213,6 +1211,10 @@ LineBreak -> return $ do if html5 then H5.br else H.br strToHtml "\n"+ (Span ("",[cls],[]) ils)+ | cls == "csl-block" || cls == "csl-left-margin" ||+ cls == "csl-right-inline" || cls == "csl-indent"+ -> inlineListToHtml opts ils >>= inDiv cls (Span (id',classes,kvs) ils) -> let spanLikeTag = case classes of@@ -1462,22 +1464,12 @@ _ -> noteItem return $ nl opts >> noteItem' -cslEntryToHtml :: PandocMonad m- => WriterOptions- -> Block- -> StateT WriterState m Html-cslEntryToHtml opts (Para xs) = do+inDiv :: PandocMonad m=> Text -> Html -> StateT WriterState m Html+inDiv cls x = do html5 <- gets stHtml5- let inDiv :: Text -> Html -> Html- inDiv cls x = (if html5 then H5.div else H.div)- x ! A.class_ (toValue cls)- let go (Span ("",[cls],[]) ils)- | cls == "csl-block" || cls == "csl-left-margin" ||- cls == "csl-right-inline" || cls == "csl-indent"- = inDiv cls <$> inlineListToHtml opts ils- go il = inlineToHtml opts il- mconcat <$> mapM go xs-cslEntryToHtml opts x = blockToHtml opts x+ return $+ (if html5 then H5.div else H.div)+ x ! A.class_ (toValue cls) isMathEnvironment :: Text -> Bool isMathEnvironment s = "\\begin{" `T.isPrefixOf` s &&
@@ -621,7 +621,12 @@ image = inTags True "Image" [("Self","ue6"), ("ItemTransform", scale<>" -"<>hw<>" -"<>hh)] $ vcat [- inTags True "Properties" [] $ inTags True "Profile" [("type","string")] $ text "$ID/Embedded"+ inTags True "Properties" [] $ vcat [+ inTags True "Profile" [("type","string")] $ text "$ID/Embedded"+ , selfClosingTag "GraphicBounds" [("Left","0"), ("Top","0")+ , ("Right", showFl $ ow*ow / imgWidth)+ , ("Bottom", showFl $ oh*oh / imgHeight)]+ ] , selfClosingTag "Link" [("Self", "ueb"), ("LinkResourceURI", src')] ] doc = inTags True "CharacterStyleRange" attrs
@@ -46,6 +46,7 @@ import Text.Pandoc.Writers.Shared import Text.Pandoc.XML import Text.TeXMath+import qualified Text.Pandoc.Writers.AnnotatedTable as Ann import qualified Text.XML.Light as Xml -- | Convert a @'Pandoc'@ document to JATS (Archiving and Interchange@@ -349,8 +350,8 @@ report $ BlockNotRendered b return empty blockToJATS _ HorizontalRule = return empty -- not semantic-blockToJATS opts (Table attr blkCapt specs th tb tf) =- tableToJATS opts attr blkCapt specs th tb tf+blockToJATS opts (Table attr caption colspecs thead tbody tfoot) =+ tableToJATS opts (Ann.toTable attr caption colspecs thead tbody tfoot) -- | Convert a list of inline elements to JATS. inlinesToJATS :: PandocMonad m => WriterOptions -> [Inline] -> JATS m (Doc Text)
@@ -1,4 +1,6 @@+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TupleSections #-} {- | Module : Text.Pandoc.Writers.JATS.Table Copyright : © 2020 Albert Krewinkel@@ -14,69 +16,233 @@ ( tableToJATS ) where import Control.Monad.Reader (asks)+import Data.List.NonEmpty (NonEmpty ((:|))) import Data.Text (Text)+import Text.DocLayout (Doc, empty, vcat, ($$)) import Text.Pandoc.Class.PandocMonad (PandocMonad) import Text.Pandoc.Definition import Text.Pandoc.Options (WriterOptions)-import Text.DocLayout (Doc, empty, vcat, ($$)) import Text.Pandoc.Shared (tshow) import Text.Pandoc.Writers.JATS.Types-import Text.Pandoc.Writers.Shared (toLegacyTable) import Text.Pandoc.XML (inTags, inTagsIndented, selfClosingTag)-+import qualified Data.Text as T+import qualified Text.Pandoc.Writers.AnnotatedTable as Ann tableToJATS :: PandocMonad m => WriterOptions- -> Attr -> Caption -> [ColSpec] -> TableHead- -> [TableBody] -> TableFoot+ -> Ann.Table -> JATS m (Doc Text)-tableToJATS opts _attr blkCapt specs th tb tf = do- blockToJATS <- asks jatsBlockWriter- let (caption, aligns, widths, headers, rows) =- toLegacyTable blkCapt specs th tb tf- captionDoc <- if null caption- then return mempty- else inTagsIndented "caption" <$> blockToJATS opts (Para caption)- tbl <- captionlessTable aligns widths headers rows+tableToJATS opts (Ann.Table attr caption colspecs thead tbodies tfoot) = do+ let (Caption _maybeShortCaption captionBlocks) = caption+ tbl <- captionlessTable opts attr colspecs thead tbodies tfoot+ captionDoc <- if null captionBlocks+ then return empty+ else do+ blockToJATS <- asks jatsBlockWriter+ inTagsIndented "caption" . vcat <$>+ mapM (blockToJATS opts) captionBlocks return $ inTags True "table-wrap" [] $ captionDoc $$ tbl++captionlessTable :: PandocMonad m+ => WriterOptions+ -> Attr+ -> [ColSpec]+ -> Ann.TableHead+ -> [Ann.TableBody]+ -> Ann.TableFoot+ -> JATS m (Doc Text)+captionlessTable opts attr colspecs thead tbodies tfoot = do+ head' <- tableHeadToJats opts thead+ bodies <- mapM (tableBodyToJats opts) tbodies+ foot' <- tableFootToJats opts tfoot+ let validAttribs = [ "border", "cellpadding", "cellspacing", "content-type"+ , "frame", "rules", "specific-use", "style", "summary"+ , "width"+ ]+ let attribs = toAttribs attr validAttribs+ return $ inTags True "table" attribs $ vcat+ [ colSpecListToJATS colspecs+ , head'+ , foot'+ , vcat bodies+ ]++validTablePartAttribs :: [Text]+validTablePartAttribs =+ [ "align", "char", "charoff", "content-type", "style", "valign" ]++tableBodyToJats :: PandocMonad m+ => WriterOptions+ -> Ann.TableBody+ -> JATS m (Doc Text)+tableBodyToJats opts (Ann.TableBody attr _rowHeadCols inthead rows) = do+ let attribs = toAttribs attr validTablePartAttribs+ intermediateHead <- if null inthead+ then return mempty+ else headerRowsToJats opts Thead inthead+ bodyRows <- bodyRowsToJats opts rows+ return $ inTags True "tbody" attribs $ intermediateHead $$ bodyRows++tableHeadToJats :: PandocMonad m+ => WriterOptions+ -> Ann.TableHead+ -> JATS m (Doc Text)+tableHeadToJats opts (Ann.TableHead attr rows) =+ tablePartToJats opts Thead attr rows++tableFootToJats :: PandocMonad m+ => WriterOptions+ -> Ann.TableFoot+ -> JATS m (Doc Text)+tableFootToJats opts (Ann.TableFoot attr rows) =+ tablePartToJats opts Tfoot attr rows++tablePartToJats :: PandocMonad m+ => WriterOptions+ -> TablePart+ -> Attr+ -> [Ann.HeaderRow]+ -> JATS m (Doc Text)+tablePartToJats opts tblpart attr rows =+ if null rows || all isEmptyRow rows+ then return mempty+ else do+ let tag' = case tblpart of+ Thead -> "thead"+ Tfoot -> "tfoot"+ Tbody -> "tbody" -- this would be unexpected+ let attribs = toAttribs attr validTablePartAttribs+ inTags True tag' attribs <$> headerRowsToJats opts tblpart rows where- captionlessTable aligns widths headers rows = do- let percent w = tshow (truncate (100*w) :: Integer) <> "*"- let coltags = vcat $ zipWith (\w al -> selfClosingTag "col"- ([("width", percent w) | w > 0] ++- [("align", alignmentToText al)])) widths aligns- thead <- if all null headers- then return empty- else inTagsIndented "thead" <$> tableRowToJATS opts True headers- tbody <- inTagsIndented "tbody" . vcat <$>- mapM (tableRowToJATS opts False) rows- return $ inTags True "table" [] $ coltags $$ thead $$ tbody+ isEmptyRow (Ann.HeaderRow _attr _rownum cells) = all isEmptyCell cells+ isEmptyCell (Ann.Cell _colspecs _colnum cell) =+ cell == Cell nullAttr AlignDefault (RowSpan 1) (ColSpan 1) [] -alignmentToText :: Alignment -> Text-alignmentToText alignment = case alignment of- AlignLeft -> "left"- AlignRight -> "right"- AlignCenter -> "center"- AlignDefault -> "left"+-- | The part of a table; header, footer, or body.+data TablePart = Thead | Tfoot | Tbody+ deriving (Eq) -tableRowToJATS :: PandocMonad m+data CellType = HeaderCell | BodyCell++data TableRow = TableRow TablePart Attr Ann.RowNumber Ann.RowHead Ann.RowBody++headerRowsToJats :: PandocMonad m+ => WriterOptions+ -> TablePart+ -> [Ann.HeaderRow]+ -> JATS m (Doc Text)+headerRowsToJats opts tablepart =+ rowListToJats opts . map toTableRow+ where+ toTableRow (Ann.HeaderRow attr rownum rowbody) =+ TableRow tablepart attr rownum [] rowbody++bodyRowsToJats :: PandocMonad m => WriterOptions- -> Bool- -> [[Block]]+ -> [Ann.BodyRow] -> JATS m (Doc Text)-tableRowToJATS opts isHeader cols =- inTagsIndented "tr" . vcat <$> mapM (tableItemToJATS opts isHeader) cols+bodyRowsToJats opts =+ rowListToJats opts . zipWith toTableRow [1..]+ where+ toTableRow rownum (Ann.BodyRow attr _rownum rowhead rowbody) =+ TableRow Tbody attr rownum rowhead rowbody -tableItemToJATS :: PandocMonad m+rowListToJats :: PandocMonad m+ => WriterOptions+ -> [TableRow]+ -> JATS m (Doc Text)+rowListToJats opts = fmap vcat . mapM (tableRowToJats opts)++colSpecListToJATS :: [ColSpec] -> Doc Text+colSpecListToJATS colspecs =+ let hasDefaultWidth (_, ColWidthDefault) = True+ hasDefaultWidth _ = False++ percent w = tshow (round (100*w) :: Integer) <> "%"++ col :: ColWidth -> Doc Text+ col = selfClosingTag "col" . \case+ ColWidthDefault -> mempty+ ColWidth w -> [("width", percent w)]++ in if all hasDefaultWidth colspecs+ then mempty+ else inTags True "colgroup" [] $ vcat $ map (col . snd) colspecs++tableRowToJats :: PandocMonad m+ => WriterOptions+ -> TableRow+ -> JATS m (Doc Text)+tableRowToJats opts (TableRow tblpart attr _rownum rowhead rowbody) = do+ let validAttribs = [ "align", "char", "charoff", "content-type"+ , "style", "valign"+ ]+ let attr' = toAttribs attr validAttribs+ let celltype = case tblpart of+ Thead -> HeaderCell+ _ -> BodyCell+ headcells <- mapM (cellToJats opts HeaderCell) rowhead+ bodycells <- mapM (cellToJats opts celltype) rowbody+ return $ inTags True "tr" attr' $ mconcat+ [ vcat headcells+ , vcat bodycells+ ]++alignmentAttrib :: Alignment -> Maybe (Text, Text)+alignmentAttrib = fmap ("align",) . \case+ AlignLeft -> Just "left"+ AlignRight -> Just "right"+ AlignCenter -> Just "center"+ AlignDefault -> Nothing++colspanAttrib :: ColSpan -> Maybe (Text, Text)+colspanAttrib = \case+ ColSpan 1 -> Nothing+ ColSpan n -> Just ("colspan", tshow n)++rowspanAttrib :: RowSpan -> Maybe (Text, Text)+rowspanAttrib = \case+ RowSpan 1 -> Nothing+ RowSpan n -> Just ("rowspan", tshow n)++cellToJats :: PandocMonad m+ => WriterOptions+ -> CellType+ -> Ann.Cell+ -> JATS m (Doc Text)+cellToJats opts celltype (Ann.Cell (colspec :| _) _colNum cell) =+ let align = fst colspec+ in tableCellToJats opts celltype align cell++toAttribs :: Attr -> [Text] -> [(Text, Text)]+toAttribs (ident, _classes, kvs) knownAttribs =+ (if T.null ident then id else (("id", ident) :)) $+ filter ((`elem` knownAttribs) . fst) kvs++tableCellToJats :: PandocMonad m => WriterOptions- -> Bool- -> [Block]+ -> CellType+ -> Alignment+ -> Cell -> JATS m (Doc Text)-tableItemToJATS opts isHeader [Plain item] = do- inlinesToJATS <- asks jatsInlinesWriter- inTags False (if isHeader then "th" else "td") [] <$>- inlinesToJATS opts item-tableItemToJATS opts isHeader item = do- blockToJATS <- asks jatsBlockWriter- inTags False (if isHeader then "th" else "td") [] . vcat <$>- mapM (blockToJATS opts) item+tableCellToJats opts ctype colAlign (Cell attr align rowspan colspan item) = do+ blockToJats <- asks jatsBlockWriter+ inlinesToJats <- asks jatsInlinesWriter+ let cellContents = \case+ [Plain inlines] -> inlinesToJats opts inlines+ blocks -> vcat <$> mapM (blockToJats opts) blocks+ let tag' = case ctype of+ BodyCell -> "td"+ HeaderCell -> "th"+ let align' = case align of+ AlignDefault -> colAlign+ _ -> align+ let maybeCons = maybe id (:)+ let validAttribs = [ "abbr", "align", "axis", "char", "charoff"+ , "content-type", "headers", "scope", "style", "valign"+ ]+ let attribs = maybeCons (alignmentAttrib align')+ . maybeCons (rowspanAttrib rowspan)+ . maybeCons (colspanAttrib colspan)+ $ toAttribs attr validAttribs+ inTags False tag' attribs <$> cellContents item
@@ -20,7 +20,6 @@ ) where import Control.Applicative ((<|>)) import Control.Monad.State.Strict-import Data.Monoid (Any(..)) import Data.Char (isAlphaNum, isAscii, isDigit, isLetter, isSpace, isPunctuation, ord) import Data.List (foldl', intersperse, nubBy, (\\), uncons)@@ -42,69 +41,14 @@ import Text.DocLayout import Text.Pandoc.Shared import Text.Pandoc.Slides-import Text.Pandoc.Walk+import Text.Pandoc.Walk (query, walk, walkM)+import Text.Pandoc.Writers.LaTeX.Caption (getCaption)+import Text.Pandoc.Writers.LaTeX.Table (tableToLaTeX)+import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState (..), startingState) import Text.Pandoc.Writers.Shared import Text.Printf (printf) import qualified Data.Text.Normalize as Normalize -data WriterState =- WriterState { stInNote :: Bool -- true if we're in a note- , stInQuote :: Bool -- true if in a blockquote- , stExternalNotes :: Bool -- true if in context where- -- we need to store footnotes- , stInMinipage :: Bool -- true if in minipage- , stInHeading :: Bool -- true if in a section heading- , stInItem :: Bool -- true if in \item[..]- , stNotes :: [Doc Text] -- 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- , stLHS :: Bool -- true if document has literate haskell code- , stHasChapters :: Bool -- true if document has chapters- , 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 :: [Text] -- list of internal link targets- , stBeamer :: Bool -- produce beamer- , stEmptyLine :: Bool -- true if no content on line- , stHasCslRefs :: Bool -- has a Div with class refs- , stIsFirstInDefinition :: Bool -- first block in a defn list- }--startingState :: WriterOptions -> WriterState-startingState options = WriterState {- stInNote = False- , stInQuote = False- , stExternalNotes = False- , stInHeading = False- , stInMinipage = False- , stInItem = False- , stNotes = []- , stOLLevel = 1- , stOptions = options- , stVerbInNote = False- , stTable = False- , stStrikeout = False- , stUrl = False- , stGraphics = False- , stLHS = False- , stHasChapters = case writerTopLevelDivision options of- TopLevelPart -> True- TopLevelChapter -> True- _ -> False- , stCsquotes = False- , stHighlighting = False- , stIncremental = writerIncremental options- , stInternalLinks = []- , stBeamer = False- , stEmptyLine = True- , stHasCslRefs = False- , stIsFirstInDefinition = False }- -- | Convert Pandoc to LaTeX. writeLaTeX :: PandocMonad m => WriterOptions -> Pandoc -> m Text writeLaTeX options document =@@ -117,8 +61,6 @@ evalStateT (pandocToLaTeX options document) $ (startingState options){ stBeamer = True } -type LW m = StateT WriterState m- pandocToLaTeX :: PandocMonad m => WriterOptions -> Pandoc -> LW m Text pandocToLaTeX options (Pandoc meta blocks) = do@@ -553,9 +495,7 @@ Just s -> braces (literal s)) $$ inner $+$ "\\end{CSLReferences}"- else if "csl-entry" `elem` classes- then vcat <$> mapM cslEntryToLaTeX bs- else blockListToLaTeX bs+ else blockListToLaTeX bs modify $ \st -> st{ stIncremental = oldIncremental } linkAnchor' <- hypertarget True identifier empty -- see #2704 for the motivation for adding \leavevmode:@@ -575,7 +515,7 @@ blockToLaTeX (Para [Image attr@(ident, _, _) txt (src,tgt)]) | Just tit <- T.stripPrefix "fig:" tgt = do- (capt, captForLof, footnotes) <- getCaption True txt+ (capt, captForLof, footnotes) <- getCaption inlineListToLaTeX True txt lab <- labelFor ident let caption = "\\caption" <> captForLof <> braces capt <> lab img <- inlineToLaTeX (Image attr txt (src,tit))@@ -776,161 +716,14 @@ hdr <- sectionHeader classes id' level lst modify $ \s -> s{stInHeading = False} return hdr-blockToLaTeX (Table _ blkCapt specs thead tbody tfoot) = do- let (caption, aligns, widths, heads, rows) = toLegacyTable blkCapt specs thead tbody tfoot- (captionText, captForLof, captNotes) <- getCaption False caption- let toHeaders hs = do contents <- tableRowToLaTeX True aligns widths hs- return ("\\toprule" $$ contents $$ "\\midrule")- let removeNote (Note _) = Span ("", [], []) []- removeNote x = x- firsthead <- if isEmpty captionText || all null heads- then return empty- else ($$ text "\\endfirsthead") <$> toHeaders heads- head' <- if all null heads- then return "\\toprule"- -- avoid duplicate notes in head and firsthead:- else toHeaders (if isEmpty firsthead- then heads- else walk removeNote heads)- let capt = if isEmpty captionText- then empty- else "\\caption" <> captForLof <> braces captionText- <> "\\tabularnewline"- rows' <- mapM (tableRowToLaTeX False aligns widths) rows- let colDescriptors = literal $ T.concat $ map toColDescriptor aligns- modify $ \s -> s{ stTable = True }- notes <- notesToLaTeX <$> gets stNotes- return $ "\\begin{longtable}[]" <>- braces ("@{}" <> colDescriptors <> "@{}")- -- the @{} removes extra space at beginning and end- $$ capt- $$ firsthead- $$ head'- $$ "\\endhead"- $$ vcat rows'- $$ "\\bottomrule"- $$ "\\end{longtable}"- $$ captNotes- $$ notes--getCaption :: PandocMonad m- => Bool -> [Inline] -> LW m (Doc Text, Doc Text, Doc Text)-getCaption externalNotes txt = do- oldExternalNotes <- gets stExternalNotes- modify $ \st -> st{ stExternalNotes = externalNotes, stNotes = [] }- capt <- inlineListToLaTeX txt- footnotes <- if externalNotes- then notesToLaTeX <$> gets stNotes- else return empty- modify $ \st -> st{ stExternalNotes = oldExternalNotes, stNotes = [] }- -- We can't have footnotes in the list of figures/tables, so remove them:- let getNote (Note _) = Any True- getNote _ = Any False- let hasNotes = getAny . query getNote- captForLof <- if hasNotes txt- then brackets <$> inlineListToLaTeX (walk deNote txt)- else return empty- return (capt, captForLof, footnotes)--toColDescriptor :: Alignment -> Text-toColDescriptor align =- case align of- AlignLeft -> "l"- AlignRight -> "r"- AlignCenter -> "c"- AlignDefault -> "l"+blockToLaTeX (Table _ blkCapt specs thead tbodies tfoot) =+ tableToLaTeX inlineListToLaTeX blockListToLaTeX+ blkCapt specs thead tbodies tfoot blockListToLaTeX :: PandocMonad m => [Block] -> LW m (Doc Text) blockListToLaTeX lst = vsep `fmap` mapM (\b -> setEmptyLine True >> blockToLaTeX b) lst -tableRowToLaTeX :: PandocMonad m- => Bool- -> [Alignment]- -> [Double]- -> [[Block]]- -> LW m (Doc Text)-tableRowToLaTeX header aligns widths cols = do- let isSimple [Plain _] = True- isSimple [Para _] = True- isSimple [] = True- isSimple _ = False- -- simple tables have to have simple cells:- let widths' = if all (== 0) widths && not (all isSimple cols)- then replicate (length aligns)- (1 / fromIntegral (length aligns))- else widths- let numcols = length widths'- cells <- mapM (tableCellToLaTeX header numcols) $ 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" "}"]---- We also change display math to inline math, since display--- math breaks in simple tables.-displayMathToInline :: Inline -> Inline-displayMathToInline (Math DisplayMath x) = Math InlineMath x-displayMathToInline x = x--tableCellToLaTeX :: PandocMonad m- => Bool -> Int -> (Double, Alignment, [Block])- -> LW m (Doc Text)-tableCellToLaTeX _ _ (0, _, blocks) =- blockListToLaTeX $ walk fixLineBreaks $ walk displayMathToInline blocks-tableCellToLaTeX header numcols (width, align, blocks) = do- beamer <- gets stBeamer- externalNotes <- gets stExternalNotes- inMinipage <- gets stInMinipage- -- See #5367 -- footnotehyper/footnote don't work in beamer,- -- so we need to produce the notes outside the table...- modify $ \st -> st{ stExternalNotes = beamer,- stInMinipage = True }- cellContents <- blockListToLaTeX blocks- modify $ \st -> st{ stExternalNotes = externalNotes,- stInMinipage = inMinipage }- 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- "(\\columnwidth - %d\\tabcolsep) * \\real{%.2f}"- (numcols - 1) width)) <>- halign <> cr <> cellContents <> "\\strut" <> cr <>- "\\end{minipage}"--- (\columnwidth - 8\tabcolsep) * \real{0.15}--notesToLaTeX :: [Doc Text] -> Doc Text-notesToLaTeX [] = empty-notesToLaTeX 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 :: PandocMonad m => [Block] -> LW m (Doc Text) listItemToLaTeX lst -- we need to put some text before a header if it's the first@@ -1063,7 +856,7 @@ "top-baseline" -> "t" "bottom" -> "b" "center" -> "c"- _ -> a + _ -> a wrapDiv :: PandocMonad m => Attr -> Doc Text -> LW m (Doc Text) wrapDiv (_,classes,kvs) t = do@@ -1077,7 +870,7 @@ (lookup "totalwidth" kvs) onlytextwidth = filter ("onlytextwidth" ==) classes options = text $ T.unpack $ T.intercalate "," $- valign : totalwidth ++ onlytextwidth + valign : totalwidth ++ onlytextwidth in inCmd "begin" "columns" <> brackets options $$ contents $$ inCmd "end" "columns"@@ -1088,8 +881,8 @@ maybe "" (brackets . text . T.unpack . mapAlignment) (lookup "align" kvs)- w = maybe "0.48" fromPct (lookup "width" kvs) - in inCmd "begin" "column" <> + w = maybe "0.48" fromPct (lookup "width" kvs)+ in inCmd "begin" "column" <> valign <> braces (literal w <> "\\textwidth") $$ contents@@ -1160,23 +953,6 @@ isQuoted (Quoted _ _) = True isQuoted _ = False -cslEntryToLaTeX :: PandocMonad m- => Block- -> LW m (Doc Text)-cslEntryToLaTeX (Para xs) =- mconcat <$> mapM go xs- where- go (Span ("",["csl-block"],[]) ils) =- (cr <>) . inCmd "CSLBlock" <$> inlineListToLaTeX ils- go (Span ("",["csl-left-margin"],[]) ils) =- inCmd "CSLLeftMargin" <$> inlineListToLaTeX ils- go (Span ("",["csl-right-inline"],[]) ils) =- (cr <>) . inCmd "CSLRightInline" <$> inlineListToLaTeX ils- go (Span ("",["csl-indent"],[]) ils) =- (cr <>) . inCmd "CSLIndent" <$> inlineListToLaTeX ils- go il = inlineToLaTeX il-cslEntryToLaTeX x = blockToLaTeX x- -- | Convert inline element to LaTeX inlineToLaTeX :: PandocMonad m => Inline -- ^ Inline to convert@@ -1184,23 +960,38 @@ inlineToLaTeX (Span (id',classes,kvs) ils) = do linkAnchor <- hypertarget False id' empty lang <- toLang $ lookup "lang" kvs- let cmds = ["textup" | "csl-no-emph" `elem` classes] ++- ["textnormal" | "csl-no-strong" `elem` classes ||- "csl-no-smallcaps" `elem` classes] ++- ["RL" | ("dir", "rtl") `elem` kvs] ++- ["LR" | ("dir", "ltr") `elem` kvs] ++- (case lang of- Just lng -> let (l, o) = toPolyglossia lng- ops = if T.null o then "" else "[" <> o <> "]"- in ["text" <> l <> ops]- Nothing -> [])+ let classToCmd "csl-no-emph" = Just "textup"+ classToCmd "csl-no-strong" = Just "textnormal"+ classToCmd "csl-no-smallcaps" = Just "textnormal"+ classToCmd "csl-block" = Just "CSLBlock"+ classToCmd "csl-left-margin" = Just "CSLLeftMargin"+ classToCmd "csl-right-inline" = Just "CSLRightInline"+ classToCmd "csl-indent" = Just "CSLIndent"+ classToCmd _ = Nothing+ kvToCmd ("dir","rtl") = Just "RL"+ kvToCmd ("dir","ltr") = Just "LR"+ kvToCmd _ = Nothing+ langCmds =+ case lang of+ Just lng -> let (l, o) = toPolyglossia lng+ ops = if T.null o then "" else "[" <> o <> "]"+ in ["text" <> l <> ops]+ Nothing -> []+ let cmds = mapMaybe classToCmd classes ++ mapMaybe kvToCmd kvs ++ langCmds contents <- inlineListToLaTeX ils- return $ (if T.null id'- then empty- else "\\protect" <> linkAnchor) <>- (if null cmds- then braces contents- else foldr inCmd contents cmds)+ return $+ (case classes of+ ["csl-block"] -> (cr <>)+ ["csl-left-margin"] -> (cr <>)+ ["csl-right-inline"] -> (cr <>)+ ["csl-indent"] -> (cr <>)+ _ -> id) $+ (if T.null id'+ then empty+ else "\\protect" <> linkAnchor) <>+ (if null cmds+ then braces contents+ else foldr inCmd contents cmds) inlineToLaTeX (Emph lst) = inCmd "emph" <$> inlineListToLaTeX lst inlineToLaTeX (Underline lst) = inCmd "underline" <$> inlineListToLaTeX lst inlineToLaTeX (Strong lst) = inCmd "textbf" <$> inlineListToLaTeX lst
@@ -0,0 +1,48 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+ Module : Text.Pandoc.Writers.LaTeX.Caption+ Copyright : Copyright (C) 2006-2020 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Write figure or table captions as LaTeX.+-}+module Text.Pandoc.Writers.LaTeX.Caption+ ( getCaption+ ) where++import Control.Monad.State.Strict+import Data.Monoid (Any(..))+import Data.Text (Text)+import Text.Pandoc.Class.PandocMonad (PandocMonad)+import Text.Pandoc.Definition+import Text.DocLayout (Doc, brackets, empty)+import Text.Pandoc.Shared+import Text.Pandoc.Walk+import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX)+import Text.Pandoc.Writers.LaTeX.Types+ ( LW, WriterState (stExternalNotes, stNotes) )++getCaption :: PandocMonad m+ => ([Inline] -> LW m (Doc Text))+ -> Bool -> [Inline]+ -> LW m (Doc Text, Doc Text, Doc Text)+getCaption inlineListToLaTeX externalNotes txt = do+ oldExternalNotes <- gets stExternalNotes+ modify $ \st -> st{ stExternalNotes = externalNotes, stNotes = [] }+ capt <- inlineListToLaTeX txt+ footnotes <- if externalNotes+ then notesToLaTeX <$> gets stNotes+ else return empty+ modify $ \st -> st{ stExternalNotes = oldExternalNotes, stNotes = [] }+ -- We can't have footnotes in the list of figures/tables, so remove them:+ let getNote (Note _) = Any True+ getNote _ = Any False+ let hasNotes = getAny . query getNote+ captForLof <- if hasNotes txt+ then brackets <$> inlineListToLaTeX (walk deNote txt)+ else return empty+ return (capt, captForLof, footnotes)
@@ -0,0 +1,34 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{- |+ Module : Text.Pandoc.Writers.LaTeX.Notes+ Copyright : Copyright (C) 2006-2020 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Output tables as LaTeX.+-}+module Text.Pandoc.Writers.LaTeX.Notes+ ( notesToLaTeX+ ) where++import Data.List (intersperse)+import Text.DocLayout ( Doc, braces, empty, text, vcat, ($$))+import Data.Text (Text)++notesToLaTeX :: [Doc Text] -> Doc Text+notesToLaTeX = \case+ [] -> 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)
@@ -0,0 +1,181 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{- |+ Module : Text.Pandoc.Writers.LaTeX.Table+ Copyright : Copyright (C) 2006-2020 John MacFarlane+ License : GNU GPL, version 2 or above++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Output LaTeX formatted tables.+-}+module Text.Pandoc.Writers.LaTeX.Table+ ( tableToLaTeX+ ) where+import Control.Monad.State.Strict+import Data.List (intersperse)+import Data.Text (Text)+import qualified Data.Text as T+import Text.Pandoc.Class.PandocMonad (PandocMonad)+import Text.Pandoc.Definition+import Text.DocLayout+ ( Doc, braces, cr, empty, hcat, hsep, isEmpty, literal, nest+ , text, vcat, ($$) )+import Text.Pandoc.Shared (splitBy)+import Text.Pandoc.Walk (walk)+import Text.Pandoc.Writers.Shared (toLegacyTable)+import Text.Pandoc.Writers.LaTeX.Caption (getCaption)+import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX)+import Text.Pandoc.Writers.LaTeX.Types+ ( LW, WriterState (stBeamer, stExternalNotes, stInMinipage, stNotes, stTable) )+import Text.Printf (printf)++tableToLaTeX :: PandocMonad m+ => ([Inline] -> LW m (Doc Text))+ -> ([Block] -> LW m (Doc Text))+ -> Caption -> [ColSpec] -> TableHead -> [TableBody] -> TableFoot+ -> LW m (Doc Text)+tableToLaTeX inlnsToLaTeX blksToLaTeX blkCapt specs thead tbody tfoot = do+ let (caption, aligns, widths, heads, rows) =+ toLegacyTable blkCapt specs thead tbody tfoot+ -- simple tables have to have simple cells:+ let isSimple = \case+ [Plain _] -> True+ [Para _] -> True+ [] -> True+ _ -> False+ let widths' = if all (== 0) widths && not (all (all isSimple) rows)+ then replicate (length aligns)+ (1 / fromIntegral (length aligns))+ else widths+ (captionText, captForLof, captNotes) <- getCaption inlnsToLaTeX False caption+ let toHeaders hs = do contents <- tableRowToLaTeX blksToLaTeX True aligns hs+ return ("\\toprule" $$ contents $$ "\\midrule")+ let removeNote (Note _) = Span ("", [], []) []+ removeNote x = x+ firsthead <- if isEmpty captionText || all null heads+ then return empty+ else ($$ text "\\endfirsthead") <$> toHeaders heads+ head' <- if all null heads+ then return "\\toprule"+ -- avoid duplicate notes in head and firsthead:+ else toHeaders (if isEmpty firsthead+ then heads+ else walk removeNote heads)+ let capt = if isEmpty captionText+ then empty+ else "\\caption" <> captForLof <> braces captionText+ <> "\\tabularnewline"+ rows' <- mapM (tableRowToLaTeX blksToLaTeX False aligns) rows+ let colDescriptors =+ (if all (== 0) widths'+ then hcat . map literal+ else (\xs -> cr <> nest 2 (vcat $ map literal xs))) $+ zipWith (toColDescriptor (length widths')) aligns widths'+ modify $ \s -> s{ stTable = True }+ notes <- notesToLaTeX <$> gets stNotes+ return $ "\\begin{longtable}[]" <>+ braces ("@{}" <> colDescriptors <> "@{}")+ -- the @{} removes extra space at beginning and end+ $$ capt+ $$ firsthead+ $$ head'+ $$ "\\endhead"+ $$ vcat rows'+ $$ "\\bottomrule"+ $$ "\\end{longtable}"+ $$ captNotes+ $$ notes++toColDescriptor :: Int -> Alignment -> Double -> Text+toColDescriptor _numcols align 0 =+ case align of+ AlignLeft -> "l"+ AlignRight -> "r"+ AlignCenter -> "c"+ AlignDefault -> "l"+toColDescriptor numcols align width =+ T.pack $ printf+ ">{%s\\arraybackslash}p{(\\columnwidth - %d\\tabcolsep) * \\real{%0.2f}}"+ align'+ ((numcols - 1) * 2)+ width+ where+ align' :: String+ align' = case align of+ AlignLeft -> "\\raggedright"+ AlignRight -> "\\raggedleft"+ AlignCenter -> "\\centering"+ AlignDefault -> "\\raggedright"++tableRowToLaTeX :: PandocMonad m+ => ([Block] -> LW m (Doc Text))+ -> Bool+ -> [Alignment]+ -> [[Block]]+ -> LW m (Doc Text)+tableRowToLaTeX blockListToLaTeX header aligns cols = do+ cells <- mapM (tableCellToLaTeX blockListToLaTeX header) $ zip aligns cols+ return $ hsep (intersperse "&" cells) <> " \\\\ \\addlinespace"++-- 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" "}"]++-- We also change display math to inline math, since display+-- math breaks in simple tables.+displayMathToInline :: Inline -> Inline+displayMathToInline (Math DisplayMath x) = Math InlineMath x+displayMathToInline x = x++tableCellToLaTeX :: PandocMonad m+ => ([Block] -> LW m (Doc Text))+ -> Bool -> (Alignment, [Block])+ -> LW m (Doc Text)+tableCellToLaTeX blockListToLaTeX header (align, blocks) = do+ beamer <- gets stBeamer+ externalNotes <- gets stExternalNotes+ inMinipage <- gets stInMinipage+ -- See #5367 -- footnotehyper/footnote don't work in beamer,+ -- so we need to produce the notes outside the table...+ modify $ \st -> st{ stExternalNotes = beamer }+ let isPlainOrPara = \case+ Para{} -> True+ Plain{} -> True+ _ -> False+ result <-+ if all isPlainOrPara blocks+ then+ blockListToLaTeX $ walk fixLineBreaks $ walk displayMathToInline blocks+ else do+ modify $ \st -> st{ stInMinipage = True }+ cellContents <- blockListToLaTeX blocks+ modify $ \st -> st{ stInMinipage = inMinipage }+ 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 "\\linewidth" <> halign <> cr <>+ cellContents <> cr <>+ "\\end{minipage}"+ modify $ \st -> st{ stExternalNotes = externalNotes }+ return result
@@ -0,0 +1,80 @@+module Text.Pandoc.Writers.LaTeX.Types+ ( LW+ , WriterState (..)+ , startingState+ ) where++import Control.Monad.State.Strict (StateT)+import Data.Text (Text)+import Text.DocLayout (Doc)+import Text.Pandoc.Options+ ( WriterOptions (writerIncremental, writerTopLevelDivision)+ , TopLevelDivision (..)+ )++-- | LaTeX writer type. The type constructor @m@ will typically be an+-- instance of PandocMonad.+type LW m = StateT WriterState m++data WriterState =+ WriterState+ { stInNote :: Bool -- ^ true if we're in a note+ , stInQuote :: Bool -- ^ true if in a blockquote+ , stExternalNotes :: Bool -- ^ true if in context where+ -- we need to store footnotes+ , stInMinipage :: Bool -- ^ true if in minipage+ , stInHeading :: Bool -- ^ true if in a section heading+ , stInItem :: Bool -- ^ true if in \item[..]+ , stNotes :: [Doc Text] -- ^ 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+ , stLHS :: Bool -- ^ true if document has literate haskell code+ , stHasChapters :: Bool -- ^ true if document has chapters+ , 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 :: [Text] -- ^ list of internal link targets+ , stBeamer :: Bool -- ^ produce beamer+ , stEmptyLine :: Bool -- ^ true if no content on line+ , stHasCslRefs :: Bool -- ^ has a Div with class refs+ , stIsFirstInDefinition :: Bool -- ^ first block in a defn list+ }++startingState :: WriterOptions -> WriterState+startingState options =+ WriterState+ { stInNote = False+ , stInQuote = False+ , stExternalNotes = False+ , stInHeading = False+ , stInMinipage = False+ , stInItem = False+ , stNotes = []+ , stOLLevel = 1+ , stOptions = options+ , stVerbInNote = False+ , stTable = False+ , stStrikeout = False+ , stUrl = False+ , stGraphics = False+ , stLHS = False+ , stHasChapters = case writerTopLevelDivision options of+ TopLevelPart -> True+ TopLevelChapter -> True+ _ -> False+ , stCsquotes = False+ , stHighlighting = False+ , stIncremental = writerIncremental options+ , stInternalLinks = []+ , stBeamer = False+ , stEmptyLine = True+ , stHasCslRefs = False+ , stIsFirstInDefinition = False+ }
@@ -174,6 +174,8 @@ valToYaml (ListVal xs) = vcat $ map (\v -> hang 2 "- " (valToYaml v)) xs valToYaml (MapVal c) = contextToYaml c+valToYaml (BoolVal True) = "true"+valToYaml (BoolVal False) = "false" valToYaml (SimpleVal x) | isEmpty x = empty | otherwise =@@ -1058,7 +1060,12 @@ inlineToMarkdown opts (Span attrs ils) = do variant <- asks envVariant contents <- inlineListToMarkdown opts ils- return $ case variant of+ return $ case attrs of+ (_,["csl-block"],_) -> (cr <>)+ (_,["csl-left-margin"],_) -> (cr <>)+ (_,["csl-indent"],_) -> (cr <>)+ _ -> id+ $ case variant of PlainText -> contents _ | attrs == nullAttr -> contents | isEnabled Ext_bracketed_spans opts ->
@@ -17,6 +17,7 @@ import Control.Arrow ((***), (>>>)) import Control.Monad.State.Strict hiding (when) import Data.Char (chr)+import Data.Foldable (find) import Data.List (sortOn, sortBy, foldl') import qualified Data.Map as Map import Data.Maybe (fromMaybe, isNothing)@@ -35,6 +36,7 @@ import Text.Pandoc.Shared (linesToPara, tshow, blocksToInlines) import Text.Pandoc.Templates (renderTemplate) import qualified Text.Pandoc.Translations as Term (Term(Figure, Table))+import Text.Pandoc.Walk import Text.Pandoc.Writers.Math import Text.Pandoc.Writers.Shared import qualified Text.Pandoc.Writers.AnnotatedTable as Ann@@ -54,6 +56,11 @@ type OD m = StateT WriterState m +data ReferenceType+ = HeaderRef+ | TableRef+ | ImageRef+ data WriterState = WriterState { stNotes :: [Doc Text] , stTableStyles :: [Doc Text]@@ -69,6 +76,7 @@ , stImageId :: Int , stTableCaptionId :: Int , stImageCaptionId :: Int+ , stIdentTypes :: [(Text,ReferenceType)] } defaultWriterState :: WriterState@@ -86,6 +94,7 @@ , stImageId = 1 , stTableCaptionId = 1 , stImageCaptionId = 1+ , stIdentTypes = [] } when :: Bool -> Doc Text -> Doc Text@@ -188,15 +197,23 @@ ,("style:horizontal-rel", "paragraph-content") ,("style:wrap", "none")] +inBookmarkTags :: Text -> Doc Text -> Doc Text+inBookmarkTags ident d =+ selfClosingTag "text:bookmark-start" [ ("text:name", ident) ]+ <> d <>+ selfClosingTag "text:bookmark-end" [ ("text:name", ident) ]++selfClosingBookmark :: Text -> Doc Text+selfClosingBookmark ident =+ selfClosingTag "text:bookmark" [("text:name", ident)]+ inHeaderTags :: PandocMonad m => Int -> Text -> Doc Text -> OD m (Doc Text) inHeaderTags i ident d = return $ inTags False "text:h" [ ("text:style-name", "Heading_20_" <> tshow i) , ("text:outline-level", tshow i)] $ if T.null ident then d- else selfClosingTag "text:bookmark-start" [ ("text:name", ident) ]- <> d <>- selfClosingTag "text:bookmark-end" [ ("text:name", ident) ]+ else inBookmarkTags ident d inQuotes :: QuoteType -> Doc Text -> Doc Text inQuotes SingleQuote s = char '\8216' <> s <> char '\8217'@@ -235,6 +252,12 @@ meta ((body, metadata),s) <- flip runStateT defaultWriterState $ do+ let collectInlineIdent (Image (ident,_,_) _ _) = [(ident,ImageRef)]+ collectInlineIdent _ = []+ let collectBlockIdent (Header _ (ident,_,_) _) = [(ident,HeaderRef)]+ collectBlockIdent (Table (ident,_,_) _ _ _ _ _) = [(ident,TableRef)]+ collectBlockIdent _ = []+ modify $ \s -> s{ stIdentTypes = query collectBlockIdent blocks ++ query collectInlineIdent blocks } m <- metaToContext opts (blocksToOpenDocument opts) (fmap chomp . inlinesToOpenDocument opts)@@ -360,12 +383,7 @@ then return empty else inParagraphTags =<< inlinesToOpenDocument o b | LineBlock b <- bs = blockToOpenDocument o $ linesToPara b- | Div attr xs <- bs = do- let (_,_,kvs) = attr- withLangFromAttr attr $- case lookup "custom-style" kvs of- Just sty -> withParagraphStyle o sty xs- _ -> blocksToOpenDocument o xs+ | Div attr xs <- bs = mkDiv attr xs | Header i (ident,_,_) b <- bs = setFirstPara >> (inHeaderTags i ident =<< inlinesToOpenDocument o b)@@ -390,6 +408,16 @@ setInDefinitionList False return r preformatted s = flush . vcat <$> mapM (inPreformattedTags . escapeStringForXML) (T.lines s)+ mkDiv attr s = do+ let (ident,_,kvs) = attr+ i = withLangFromAttr attr $+ case lookup "custom-style" kvs of+ Just sty -> withParagraphStyle o sty s+ _ -> blocksToOpenDocument o s+ mkBookmarkedDiv = inTags False "text:section" [("text:name", ident)]+ if T.null ident+ then i+ else fmap mkBookmarkedDiv i mkBlockQuote b = do increaseIndent i <- paraStyle [("style:parent-style-name","Quotations")]@@ -398,7 +426,7 @@ inTags True "text:list" [ ("text:style-name", "L" <> tshow ln)] <$> orderedListToOpenDocument o pn b table :: PandocMonad m => Ann.Table -> OD m (Doc Text)- table (Ann.Table _ (Caption _ c) colspecs thead tbodies _) = do+ table (Ann.Table (ident, _, _) (Caption _ c) colspecs thead tbodies _) = do tn <- length <$> gets stTableStyles pn <- length <$> gets stParaStyles let genIds = map chr [65..]@@ -407,19 +435,20 @@ fromWidth (ColWidth w) | w > 0 = w fromWidth _ = 0 widths = map fromWidth mwidths+ textWidth = sum widths columnIds = zip genIds widths mkColumn n = selfClosingTag "table:table-column" [("table:style-name", name <> "." <> T.singleton (fst n))] columns = map mkColumn columnIds paraHStyles = paraTableStyles "Heading" pn aligns paraStyles = paraTableStyles "Contents" (pn + length (newPara paraHStyles)) aligns newPara = map snd . filter (not . isEmpty . snd)- addTableStyle $ tableStyle tn columnIds+ addTableStyle $ tableStyle tn textWidth columnIds mapM_ addParaStyle . newPara $ paraHStyles ++ paraStyles captionDoc <- if null c then return empty else inlinesToOpenDocument o (blocksToInlines c) >>= if isEnabled Ext_native_numbering o- then numberedTableCaption+ then numberedTableCaption ident else unNumberedCaption "TableCaption" th <- colHeadsToOpenDocument o (map fst paraHStyles) thead tr <- mapM (tableBodyToOpenDocument o (map fst paraStyles)) tbodies@@ -428,36 +457,39 @@ , ("table:style-name", name) ] (vcat columns $$ th $$ vcat tr) return $ captionDoc $$ tableDoc- figure attr caption source title | null caption =+ figure attr@(ident, _, _) caption source title | null caption = withParagraphStyle o "Figure" [Para [Image attr caption (source,title)]] | otherwise = do imageDoc <- withParagraphStyle o "FigureWithCaption" [Para [Image attr caption (source,title)]] captionDoc <- inlinesToOpenDocument o caption >>= if isEnabled Ext_native_numbering o- then numberedFigureCaption+ then numberedFigureCaption ident else unNumberedCaption "FigureCaption" return $ imageDoc $$ captionDoc -numberedTableCaption :: PandocMonad m => Doc Text -> OD m (Doc Text)-numberedTableCaption caption = do+numberedTableCaption :: PandocMonad m => Text -> Doc Text -> OD m (Doc Text)+numberedTableCaption ident caption = do id' <- gets stTableCaptionId modify (\st -> st{ stTableCaptionId = id' + 1 }) capterm <- translateTerm Term.Table- return $ numberedCaption "TableCaption" capterm "Table" id' caption+ return $ numberedCaption "TableCaption" capterm "Table" id' ident caption -numberedFigureCaption :: PandocMonad m => Doc Text -> OD m (Doc Text)-numberedFigureCaption caption = do+numberedFigureCaption :: PandocMonad m => Text -> Doc Text -> OD m (Doc Text)+numberedFigureCaption ident caption = do id' <- gets stImageCaptionId modify (\st -> st{ stImageCaptionId = id' + 1 }) capterm <- translateTerm Term.Figure- return $ numberedCaption "FigureCaption" capterm "Illustration" id' caption+ return $ numberedCaption "FigureCaption" capterm "Illustration" id' ident caption -numberedCaption :: Text -> Text -> Text -> Int -> Doc Text -> Doc Text-numberedCaption style term name num caption =+numberedCaption :: Text -> Text -> Text -> Int -> Text -> Doc Text -> Doc Text+numberedCaption style term name num ident caption = let t = text $ T.unpack term r = num - 1- s = inTags False "text:sequence" [ ("text:ref-name", "ref" <> name <> tshow r),+ ident' = case ident of+ "" -> "ref" <> name <> tshow r+ _ -> ident+ s = inTags False "text:sequence" [ ("text:ref-name", ident'), ("text:name", name), ("text:formula", "ooow:" <> name <> "+1"), ("style:num-format", "1") ] $ text $ show num@@ -566,7 +598,7 @@ | writerWrapText o == WrapPreserve -> return $ preformatted "\n" | otherwise -> return space- Span attr xs -> withLangFromAttr attr (inlinesToOpenDocument o xs)+ Span attr xs -> mkSpan attr xs LineBreak -> return $ selfClosingTag "text:line-break" [] Str s -> return $ handleSpaces $ escapeStringForXML s Emph l -> withTextStyle Italic $ inlinesToOpenDocument o l@@ -593,7 +625,9 @@ else do report $ InlineNotRendered ils return empty- Link _ l (s,t) -> mkLink s t <$> inlinesToOpenDocument o l+ Link _ l (s,t) -> do+ identTypes <- gets stIdentTypes+ mkLink o identTypes s t <$> inlinesToOpenDocument o l Image attr _ (s,t) -> mkImg attr s t Note l -> mkNote l where@@ -605,10 +639,6 @@ unhighlighted s = inlinedCode $ preformatted s preformatted s = handleSpaces $ escapeStringForXML s inlinedCode s = return $ inTags False "text:span" [("text:style-name", "Source_Text")] s- mkLink s t = inTags False "text:a" [ ("xlink:type" , "simple")- , ("xlink:href" , s )- , ("office:name", t )- ] . inSpanTags "Definition" mkImg (_, _, kvs) s _ = do id' <- gets stImageId modify (\st -> st{ stImageId = id' + 1 })@@ -624,6 +654,16 @@ , ("xlink:type" , "simple") , ("xlink:show" , "embed" ) , ("xlink:actuate", "onLoad")]+ mkSpan attr xs = do+ let (ident,_,_) = attr+ i = withLangFromAttr attr (inlinesToOpenDocument o xs)+ mkBookmarkedSpan b =+ if isEmpty b+ then selfClosingBookmark ident+ else inBookmarkTags ident b+ if T.null ident+ then i+ else fmap mkBookmarkedSpan i mkNote l = do n <- length <$> gets stNotes let footNote t = inTags False "text:note"@@ -635,6 +675,45 @@ addNote nn return nn +mkLink :: WriterOptions -> [(Text,ReferenceType)] -> Text -> Text -> Doc Text -> Doc Text+mkLink o identTypes s t d =+ let maybeIdentAndType = case T.uncons s of+ Just ('#', ident) -> find ((ident ==) . fst) identTypes+ _ -> Nothing+ d' = inSpanTags "Definition" d+ ref refType format ident = inTags False refType+ [ ("text:reference-format", format ),+ ("text:ref-name", ident) ]+ inlineSpace = selfClosingTag "text:s" []+ bookmarkRef = ref "text:bookmark-ref"+ bookmarkRefNumber ident = bookmarkRef "number" ident mempty+ bookmarkRefName ident = bookmarkRef "text" ident d+ bookmarkRefNameNumber ident = bookmarkRefNumber ident <> inlineSpace <> bookmarkRefName ident+ bookmarkRef'+ | isEnabled Ext_xrefs_number o && isEnabled Ext_xrefs_name o = bookmarkRefNameNumber+ | isEnabled Ext_xrefs_name o = bookmarkRefName+ | otherwise = bookmarkRefNumber+ sequenceRef = ref "text:sequence-ref"+ sequenceRefNumber ident = sequenceRef "value" ident mempty+ sequenceRefName ident = sequenceRef "caption" ident d+ sequenceRefNameNumber ident = sequenceRefNumber ident <> inlineSpace <> sequenceRefName ident+ sequenceRef'+ | isEnabled Ext_xrefs_number o && isEnabled Ext_xrefs_name o = sequenceRefNameNumber+ | isEnabled Ext_xrefs_name o = sequenceRefName+ | otherwise = sequenceRefNumber+ link = inTags False "text:a" [ ("xlink:type" , "simple")+ , ("xlink:href" , s )+ , ("office:name", t )+ ] d'+ linkOrReference = case maybeIdentAndType of+ Just (ident, HeaderRef) -> bookmarkRef' ident+ Just (ident, TableRef) -> sequenceRef' ident+ Just (ident, ImageRef) -> sequenceRef' ident+ _ -> link+ in if isEnabled Ext_xrefs_name o || isEnabled Ext_xrefs_number o+ then linkOrReference+ else link+ bulletListStyle :: PandocMonad m => Int -> OD m (Int,(Int,[Doc Text])) bulletListStyle l = do let doStyles i = inTags True "text:list-level-style-bullet"@@ -684,14 +763,19 @@ , ("fo:margin-left", indent <> "in") ] -tableStyle :: Int -> [(Char,Double)] -> Doc Text-tableStyle num wcs =+tableStyle :: Int -> Double -> [(Char,Double)] -> Doc Text+tableStyle num textWidth wcs = let tableId = "Table" <> tshow (num + 1)+ tableWidthAttr :: [(Text,Text)]+ tableWidthAttr+ | textWidth <= 1 && textWidth > 0 = [("style:rel-width",+ T.pack (show (round (textWidth * 100) :: Int) <> "%"))]+ | otherwise = [] table = inTags True "style:style" [("style:name", tableId) ,("style:family", "table")] $ selfClosingTag "style:table-properties"- [("table:align" , "center")]+ (("table:align", "center") : tableWidthAttr) colStyle (c,0) = selfClosingTag "style:style" [ ("style:name" , tableId <> "." <> T.singleton c) , ("style:family", "table-column" )]
@@ -143,9 +143,12 @@ let (_, cls, _) = attr classes = case cls of [] -> empty- ["align-right"] -> ":align: right"- ["align-left"] -> ":align: left"- ["align-center"] -> ":align: center"+ ["align-top"] -> ":align: top"+ ["align-middle"] -> ":align: middle"+ ["align-bottom"] -> ":align: bottom"+ ["align-center"] -> empty+ ["align-right"] -> empty+ ["align-left"] -> empty _ -> ":class: " <> literal (T.unwords cls) return $ nowrap $ ".. |" <> label' <> "| image:: " <> literal src $$ hang 3 empty (classes $$ dims)@@ -215,19 +218,28 @@ nest 3 contents $$ blankline blockToRST (Plain inlines) = inlineListToRST inlines--- title beginning with fig: indicates that the image is a figure-blockToRST (Para [Image attr txt (src,T.stripPrefix "fig:" -> Just tit)]) = do- capt <- inlineListToRST txt+blockToRST (Para [Image attr txt (src, rawtit)]) = do+ description <- inlineListToRST txt dims <- imageDimsToRST attr- let fig = "figure:: " <> literal src- alt = ":alt: " <> if T.null tit then capt else literal tit+ -- title beginning with fig: indicates that the image is a figure+ let (isfig, tit) = case T.stripPrefix "fig:" rawtit of+ Nothing -> (False, rawtit)+ Just tit' -> (True, tit')+ let fig | isfig = "figure:: " <> literal src+ | otherwise = "image:: " <> literal src+ alt | isfig = ":alt: " <> if T.null tit then description else literal tit+ | null txt = empty+ | otherwise = ":alt: " <> description+ capt | isfig = description+ | otherwise = empty (_,cls,_) = attr classes = case cls of [] -> empty ["align-right"] -> ":align: right" ["align-left"] -> ":align: left" ["align-center"] -> ":align: center"- _ -> ":figclass: " <> literal (T.unwords cls)+ _ | isfig -> ":figclass: " <> literal (T.unwords cls)+ | otherwise -> ":class: " <> literal (T.unwords cls) return $ hang 3 ".. " (fig $$ alt $$ classes $$ dims $+$ capt) $$ blankline blockToRST (Para inlines) | LineBreak `elem` inlines =
@@ -109,8 +109,7 @@ MapVal . Context <$> mapM (metaValueToVal blockWriter inlineWriter) metamap metaValueToVal blockWriter inlineWriter (MetaList xs) = ListVal <$> mapM (metaValueToVal blockWriter inlineWriter) xs-metaValueToVal _ _ (MetaBool True) = return $ SimpleVal "true"-metaValueToVal _ _ (MetaBool False) = return NullVal+metaValueToVal _ _ (MetaBool b) = return $ BoolVal b metaValueToVal _ inlineWriter (MetaString s) = SimpleVal <$> inlineWriter (Builder.toList (Builder.text s)) metaValueToVal blockWriter _ (MetaBlocks bs) = SimpleVal <$> blockWriter bs
@@ -6,25 +6,23 @@ - '.' extra-deps: - pandoc-types-1.22-- texmath-0.12.0.3 - rfc5051-0.2 - haddock-library-1.9.0-- skylighting-0.10.0.3-- skylighting-core-0.10.0.3-- doclayout-0.3-- emojis-0.1+- skylighting-0.10.2+- skylighting-core-0.10.2 - hslua-1.1.2 - jira-wiki-markup-1.3.2-- HsYAML-0.2.1.0 - HsYAML-aeson-0.2.0.0-- doctemplates-0.8.2 - commonmark-0.1.1.2 - commonmark-extensions-0.2.0.4 - commonmark-pandoc-0.2.0.1-- citeproc-0.2+- doctemplates-0.9+- citeproc-0.3+# - citeproc:+# git: https://github.com/jgm/citeproc.git+# commit: a8193fe375fa2354049bf9a967ba3bad4b1ba053 ghc-options: "$locals": -fhide-source-paths -Wno-missing-home-modules-resolver: lts-14.6+resolver: lts-16.23 nix: packages: [zlib]-
@@ -101,7 +101,7 @@ , testGroup "jats" [ testGroup "writer" [ testGroup "jats_archiving" $- writerTests' "jats_archiving"+ extWriterTests' "jats_archiving" , testGroup "jats_articleauthoring" $ writerTests' "jats_articleauthoring" , testGroup "jats_publishing" $
@@ -21,8 +21,7 @@ import Test.Tasty.Options (IsOption(defaultValue)) import Tests.Helpers import Text.Pandoc-import Text.Pandoc.Writers.Shared (toLegacyTable)-import Text.Pandoc.Shared (isHeaderBlock, onlySimpleTableCells)+import Text.Pandoc.Shared (isHeaderBlock) import Text.Pandoc.Arbitrary () import Text.Pandoc.Builder import Text.Pandoc.Walk (walk)@@ -40,14 +39,7 @@ makeRoundTrip (Div attr bs) = Div attr $ filter (not . isHeaderBlock) bs -- avoids round-trip failures related to makeSections -- e.g. with [Div ("loc",[],[("a","11"),("b_2","a b c")]) [Header 3 ("",[],[]) []]]-makeRoundTrip b@(Table _attr blkCapt specs thead tbody tfoot) =- let (_capt, _aligns, widths, headers, rows') =- toLegacyTable blkCapt specs thead tbody tfoot- isSimple = onlySimpleTableCells (headers:rows')- in- if all (== 0.0) widths && not isSimple- then Para [Str "weird table omitted"]- else b+makeRoundTrip Table{} = Para [Str "table block was here"] makeRoundTrip x = x removeRawInlines :: Inline -> Inline@@ -61,7 +53,7 @@ d' = rewrite d d'' = rewrite d' d''' = rewrite d''- rewrite = html . T.pack . (++ "\n") . T.unpack .+ rewrite = html . (`T.snoc` '\n') . purely (writeHtml5String def { writerWrapText = WrapPreserve })
@@ -112,6 +112,10 @@ "#+institute: ACME Inc." =?> Pandoc (setMeta "institute" ("ACME Inc." :: Inlines) nullMeta) mempty + , "Document language" =:+ "#+LANGUAGE: de-DE" =?>+ Pandoc (setMeta "lang" (MetaString "de-DE") nullMeta) mempty+ , testGroup "LaTeX" [ "LATEX_HEADER" =: "#+latex_header: \\usepackage{tikz}" =?>@@ -266,7 +270,8 @@ , "Search links are read as emph" =: "[[Wally][Where's Wally?]]" =?>- para (emph $ "Where's" <> space <> "Wally?")+ para (spanWith ("", ["spurious-link"], [("target", "Wally")])+ (emph $ "Where's" <> space <> "Wally?")) , "Link to nonexistent anchor" =: T.unlines [ "<<link-here>> Target."@@ -274,5 +279,6 @@ , "[[link$here][See here!]]" ] =?> (para (spanWith ("link-here", [], []) mempty <> "Target.") <>- para (emph ("See" <> space <> "here!")))+ para (spanWith ("", ["spurious-link"], [("target", "link$here")])+ (emph ("See" <> space <> "here!")))) ]
@@ -70,6 +70,72 @@ , "</para>" ] ) ]+ , testGroup "divs"+ [ "admonition" =: divWith ("foo", ["warning"], []) (para "This is a test")+ =?> unlines+ [ "<warning id=\"foo\">"+ , " <para>"+ , " This is a test"+ , " </para>"+ , "</warning>"+ ]+ , "admonition-with-title" =:+ divWith ("foo", ["attention"], []) (+ divWith ("foo", ["title"], [])+ (plain (text "This is title")) <>+ para "This is a test"+ )+ =?> unlines+ [ "<attention id=\"foo\">"+ , " <title>This is title</title>"+ , " <para>"+ , " This is a test"+ , " </para>"+ , "</attention>"+ ]+ , "admonition-with-title-in-para" =:+ divWith ("foo", ["attention"], []) (+ divWith ("foo", ["title"], [])+ (para "This is title") <>+ para "This is a test"+ )+ =?> unlines+ [ "<attention id=\"foo\">"+ , " <title>This is title</title>"+ , " <para>"+ , " This is a test"+ , " </para>"+ , "</attention>"+ ]+ , "single-child" =:+ divWith ("foo", [], []) (para "This is a test")+ =?> unlines+ [ "<para id=\"foo\">"+ , " This is a test"+ , "</para>"+ ]+ , "single-literal-child" =:+ divWith ("foo", [], []) lineblock+ =?> unlines+ [ "<literallayout id=\"foo\">some text"+ , "and more lines"+ , "and again</literallayout>"+ ]+ , "multiple-children" =:+ divWith ("foo", [], []) (+ para "This is a test" <>+ para "This is an another test"+ )+ =?> unlines+ [ "<anchor id=\"foo\" />"+ , "<para>"+ , " This is a test"+ , "</para>"+ , "<para>"+ , " This is an another test"+ , "</para>"+ ]+ ] , testGroup "compact lists" [ testGroup "bullet" [ "compact" =: bulletList [plain "a", plain "b", plain "c"]
@@ -128,6 +128,16 @@ def "docx/codeblock.native" "docx/golden/codeblock.docx"+ , docxTest+ "raw OOXML blocks"+ def+ "docx/raw-blocks.native"+ "docx/golden/raw-blocks.docx"+ , docxTest+ "raw bookmark markers"+ def+ "docx/raw-bookmarks.native"+ "docx/golden/raw-bookmarks.docx" ] , testGroup "track changes" [ docxTest
@@ -27,23 +27,23 @@ ,(AlignCenter,ColWidthDefault) ,(AlignDefault,ColWidthDefault)] (TableHead ("",[],[])- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Row ("",["header"],[])+ [Cell ("",[],[]) AlignRight (RowSpan 1) (ColSpan 1) [Plain [Str "Right"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ ,Cell ("",[],[]) AlignLeft (RowSpan 1) (ColSpan 1) [Plain [Str "Left"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1) [Plain [Str "Center"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Default"]]]]) [(TableBody ("",[],[]) (RowHeadColumns 0) []- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Row ("",["odd"],[])+ [Cell ("",[],[]) AlignRight (RowSpan 1) (ColSpan 1) [Plain [Str "12"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ ,Cell ("",[],[]) AlignLeft (RowSpan 1) (ColSpan 1) [Plain [Str "12"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1) [Plain [Str "12"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "12"]]]])]@@ -72,14 +72,14 @@ []) [(TableBody ("",[],[]) (RowHeadColumns 0) []- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Row ("",["odd"],[])+ [Cell ("",[],[]) AlignRight (RowSpan 1) (ColSpan 1) [Plain [Str "12"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ ,Cell ("",[],[]) AlignLeft (RowSpan 1) (ColSpan 1) [Plain [Str "12"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1) [Plain [Str "12"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ ,Cell ("",[],[]) AlignRight (RowSpan 1) (ColSpan 1) [Plain [Str "12"]]]])] (TableFoot ("",[],[]) [])]
@@ -14,14 +14,14 @@ \begin{longtable}[]{@{}ll@{}} \caption{a table}\tabularnewline \toprule-x & y\footnote{a footnote}\tabularnewline+x & y\footnote{a footnote} \\ \addlinespace \midrule \endfirsthead \toprule-x & y{}\tabularnewline+x & y{} \\ \addlinespace \midrule \endhead-1 & 2\tabularnewline+1 & 2 \\ \addlinespace \bottomrule \end{longtable} ```
@@ -1,16 +1,5 @@ ``` % pandoc -f native -t rst-[Image ("",["align-right"],[("width","100px")]) [Str "image"] ("foo.png","")]-^D-|image|--.. |image| image:: foo.png- :align: right- :width: 100px-```--```-% pandoc -f native -t rst [Para [Image ("",["align-right"],[("width","100px")]) [Str "image"] ("foo.png","fig:test")]] ^D .. figure:: foo.png
@@ -2,7 +2,7 @@ extension properly. ```-% pandoc -f commonmark+auto_identifiers+gfm_auto_identifiers+ascii_identifiers -t native+% pandoc -f commonmark+gfm_auto_identifiers+ascii_identifiers -t native # non ascii ⚠️ räksmörgås ^D [Header 1 ("non-ascii--raksmorgas",[],[]) [Str "non",Space,Str "ascii",Space,Str "\9888\65039",Space,Str "r\228ksm\246rg\229s"]]@@ -13,7 +13,7 @@ so it survives... ```-% pandoc -f commonmark+auto_identifiers+gfm_auto_identifiers-ascii_identifiers -t native+% pandoc -f commonmark+gfm_auto_identifiers-ascii_identifiers -t native # non ascii ⚠️ räksmörgås ^D [Header 1 ("non-ascii-\65039-r\228ksm\246rg\229s",[],[]) [Str "non",Space,Str "ascii",Space,Str "\9888\65039",Space,Str "r\228ksm\246rg\229s"]]
@@ -20,23 +20,18 @@ ^D hello\footnote{doc footnote} -\begin{longtable}[]{@{}c@{}}+\begin{longtable}[]{@{}+ >{\centering\arraybackslash}p{(\columnwidth - 0\tabcolsep) * \real{0.17}}@{}} \caption[Sample table.]{Sample table.\footnote{caption footnote}}\tabularnewline \toprule-\begin{minipage}[b]{(\columnwidth - 0\tabcolsep) * \real{0.17}}\centering-Fruit\footnote{header footnote}\strut-\end{minipage}\tabularnewline+Fruit\footnote{header footnote} \\ \addlinespace \midrule \endfirsthead \toprule-\begin{minipage}[b]{(\columnwidth - 0\tabcolsep) * \real{0.17}}\centering-Fruit{}\strut-\end{minipage}\tabularnewline+Fruit{} \\ \addlinespace \midrule \endhead-\begin{minipage}[t]{(\columnwidth - 0\tabcolsep) * \real{0.17}}\centering-Bans\footnote{table cell footnote}\strut-\end{minipage}\tabularnewline+Bans\footnote{table cell footnote} \\ \addlinespace \bottomrule \end{longtable}
@@ -80,6 +80,7 @@ <Profile type="string"> $ID/Embedded </Profile>+ <GraphicBounds Left="0" Top="0" Right="150" Bottom="150" /> </Properties> <Link Self="ueb" LinkResourceURI="file:lalune.jpg" /> </Image>
@@ -4,9 +4,10 @@ ^D <p><span id="title_page.xhtml"></span></p> <p><span id="nav.xhtml"></span></p>-<nav type="landmarks" id="landmarks" hidden="hidden">+<nav epub:type="landmarks" id="landmarks" hidden="hidden"> <ol>-<li><a href="#nav.xhtml#toc">Table of contents</a></li>+<li><a href="text/title_page.xhtml">Title Page</a></li>+<li><a href="#nav.xhtml#toc">Table of Contents</a></li> </ol> </nav> <p><span id="ch001.xhtml"></span></p>
@@ -0,0 +1,16 @@+```+% pandoc -t markdown -s+---+nvalue: false+value: true+---++text+^D+---+nvalue: false+value: true+---++text+```
@@ -0,0 +1,11 @@+```+%pandoc -f native -t opendocument+[Div ("divId",[],[])+ [Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "div."]],+Para [Span ("spanId",[],[]) [Str "And",Space,Str "here",Space,Str "is",Space,Str "a",Space,Str "span."]]]+^D+<text:section text:name="divId"><text:p text:style-name="Text_20_body">Here+is a div.</text:p></text:section>+<text:p text:style-name="Text_20_body"><text:bookmark-start text:name="spanId" />And+here is a span.<text:bookmark-end text:name="spanId" /></text:p>+```
@@ -0,0 +1,63 @@+```+% pandoc -f native -t opendocument --quiet+[Header 1 ("chapter1",[],[]) [Str "The",Space,Str "Chapter"]+,Para [Str "Chapter",Space,Str "1",Space,Str "references",Space,Link ("",[],[]) [Str "The",Space,Str "Chapter"] ("#chapter1","")]]+^D+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="chapter1" />The+Chapter<text:bookmark-end text:name="chapter1" /></text:h>+<text:p text:style-name="First_20_paragraph">Chapter 1 references+<text:a xlink:type="simple" xlink:href="#chapter1" office:name=""><text:span text:style-name="Definition">The+Chapter</text:span></text:a></text:p>+```+```+% pandoc -f native -t opendocument+xrefs_name --quiet+[Header 1 ("chapter1",[],[]) [Str "The",Space,Str "Chapter"]+,Para [Str "Chapter",Space,Str "1",Space,Str "references",Space,Link ("",[],[]) [Str "The",Space,Str "Chapter"] ("#chapter1","")]+,Para [Image ("lalune",[],[]) [Str "lalune"] ("lalune.jpg","fig:Voyage dans la Lune")]+,Para [Str "Image",Space,Str "1",Space,Str "references",Space,Link ("",[],[]) [Str "La",Space,Str "Lune"] ("#lalune","")]]+^D+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="chapter1" />The+Chapter<text:bookmark-end text:name="chapter1" /></text:h>+<text:p text:style-name="First_20_paragraph">Chapter 1 references+<text:bookmark-ref text:reference-format="text" text:ref-name="chapter1">The+Chapter</text:bookmark-ref></text:p>+<text:p text:style-name="FigureWithCaption"><draw:frame draw:name="img1"><draw:image xlink:href="lalune.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame></text:p>+<text:p text:style-name="FigureCaption">lalune</text:p>+<text:p text:style-name="Text_20_body">Image 1 references+<text:sequence-ref text:reference-format="caption" text:ref-name="lalune">La+Lune</text:sequence-ref></text:p>+```+```+% pandoc -f native -t opendocument+xrefs_number --quiet+[Header 1 ("chapter1",[],[]) [Str "The",Space,Str "Chapter"]+,Para [Str "Chapter",Space,Str "1",Space,Str "references",Space,Link ("",[],[]) [Str "The",Space,Str "Chapter"] ("#chapter1","")]+,Para [Image ("lalune",[],[]) [Str "lalune"] ("lalune.jpg","fig:Voyage dans la Lune")]+,Para [Str "Image",Space,Str "1",Space,Str "references",Space,Link ("",[],[]) [Str "La",Space,Str "Lune"] ("#lalune","")]]+^D+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="chapter1" />The+Chapter<text:bookmark-end text:name="chapter1" /></text:h>+<text:p text:style-name="First_20_paragraph">Chapter 1 references+<text:bookmark-ref text:reference-format="number" text:ref-name="chapter1"></text:bookmark-ref></text:p>+<text:p text:style-name="FigureWithCaption"><draw:frame draw:name="img1"><draw:image xlink:href="lalune.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame></text:p>+<text:p text:style-name="FigureCaption">lalune</text:p>+<text:p text:style-name="Text_20_body">Image 1 references+<text:sequence-ref text:reference-format="value" text:ref-name="lalune"></text:sequence-ref></text:p>+```+```+% pandoc -f native -t opendocument+xrefs_number+xrefs_name --quiet+[Header 1 ("chapter1",[],[]) [Str "The",Space,Str "Chapter"]+,Para [Str "Chapter",Space,Str "1",Space,Str "references",Space,Link ("",[],[]) [Str "The",Space,Str "Chapter"] ("#chapter1","")]+,Para [Image ("lalune",[],[]) [Str "lalune"] ("lalune.jpg","fig:Voyage dans la Lune")]+,Para [Str "Image",Space,Str "1",Space,Str "references",Space,Link ("",[],[]) [Str "La",Space,Str "Lune"] ("#lalune","")]]+^D+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="chapter1" />The+Chapter<text:bookmark-end text:name="chapter1" /></text:h>+<text:p text:style-name="First_20_paragraph">Chapter 1 references+<text:bookmark-ref text:reference-format="number" text:ref-name="chapter1"></text:bookmark-ref><text:s /><text:bookmark-ref text:reference-format="text" text:ref-name="chapter1">The+Chapter</text:bookmark-ref></text:p>+<text:p text:style-name="FigureWithCaption"><draw:frame draw:name="img1"><draw:image xlink:href="lalune.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame></text:p>+<text:p text:style-name="FigureCaption">lalune</text:p>+<text:p text:style-name="Text_20_body">Image 1 references+<text:sequence-ref text:reference-format="value" text:ref-name="lalune"></text:sequence-ref><text:s /><text:sequence-ref text:reference-format="caption" text:ref-name="lalune">La+Lune</text:sequence-ref></text:p>+```
@@ -0,0 +1,32 @@+```+% pandoc -f docbook -t native --quiet+<informaltable frame="all" rowsep="1" colsep="1">+<?dbfo table-width="50%"?>+<tgroup cols="2">+<colspec colname="col_1" colwidth="6.25*"/>+<colspec colname="col_2" colwidth="6.25*"/>+<tbody>+<row>+<entry align="center" valign="top"><simpara>2</simpara></entry>+<entry align="center" valign="top"><simpara>1</simpara></entry>+</row>+</tbody>+</tgroup>+</informaltable>+^D+[Table ("",[],[]) (Caption Nothing+ [])+ [(AlignDefault,ColWidth 0.25)+ ,(AlignDefault,ColWidth 0.25)]+ (TableHead ("",[],[])+ [])+ [(TableBody ("",[],[]) (RowHeadColumns 0)+ []+ [Row ("",[],[])+ [Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1)+ [Para [Str "2"]]+ ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1)+ [Para [Str "1"]]]])]+ (TableFoot ("",[],[])+ [])]+```
@@ -0,0 +1,66 @@+```+% pandoc -f native -t opendocument -s --quiet+[Table ("",[],[]) (Caption Nothing+ [])+ [(AlignDefault,ColWidth 0.25)+ ,(AlignDefault,ColWidth 0.25)]+ (TableHead ("",[],[])+ [])+ [(TableBody ("",[],[]) (RowHeadColumns 0)+ []+ [Row ("",[],[])+ [Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1)+ [Para [Str "2"]]+ ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1)+ [Para [Str "1"]]]])]+ (TableFoot ("",[],[])+ [])]+^D+<?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>+ <office:automatic-styles>+ <style:style style:name="fr2" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="paragraph-content" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" style:wrap="none" /></style:style>+ <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" /></style:style>+ <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Table_20_Contents">+ <style:paragraph-properties fo:text-align="center" style:justify-single-word="false" />+ </style:style>+ <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Table_20_Contents">+ <style:paragraph-properties fo:text-align="center" style:justify-single-word="false" />+ </style:style>+ <style:style style:name="TableHeaderRowCell" style:family="table-cell">+ <style:table-cell-properties fo:border="none" />+ </style:style>+ <style:style style:name="TableRowCell" style:family="table-cell">+ <style:table-cell-properties fo:border="none" />+ </style:style>+ <style:style style:name="Table1" style:family="table">+ <style:table-properties table:align="center" style:rel-width="50%" />+ </style:style>+ <style:style style:name="Table1.A" style:family="table-column">+ <style:table-column-properties style:rel-column-width="16383*" />+ </style:style>+ <style:style style:name="Table1.B" style:family="table-column">+ <style:table-column-properties style:rel-column-width="16383*" />+ </style:style>+ </office:automatic-styles>+<office:body>+<office:text>+<table:table table:name="Table1" table:style-name="Table1">+ <table:table-column table:style-name="Table1.A" />+ <table:table-column table:style-name="Table1.B" />+ <table:table-row>+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">+ <text:p text:style-name="P1">2</text:p>+ </table:table-cell>+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">+ <text:p text:style-name="P2">1</text:p>+ </table:table-cell>+ </table:table-row>+</table:table>+</office:text>+</office:body>+</office:document-content>+```
@@ -0,0 +1,6 @@+```+% pandoc -f latex -t native+\cite[„Aber“]{key}+^D+[Para [Cite [Citation {citationId = "key", citationPrefix = [], citationSuffix = [Str "\8222Aber\8220"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline (Format "latex") "\\cite[\8222Aber\8220]{key}"]]]+```
@@ -0,0 +1,7 @@+```+% pandoc -f latex -t native --citeproc+\cite[„Etwas […{]} auslassen“]{key}+^D+[WARNING] Citeproc: citation key not found+[Para [Cite [Citation {citationId = "key", citationPrefix = [], citationSuffix = [Str "\8222Etwas",Space,Str "[\8230",Span ("",[],[]) [Str "]"],Space,Str "auslassen\8220"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "(",Strong [Str "key?"],Str "\8222Etwas",Space,Str "[\8230",Span ("",[],[]) [Str "]"],Space,Str "auslassen\8220)"]]]+```
@@ -0,0 +1,36 @@+```+% pandoc -t native --citeproc+---+references:+- author:+ - family: Früchtel+ given: Frank+ - family: Budde+ given: Wolfgang+ - family: Cyprian+ given: Gudrun+ edition: 3+ id: fruchtel-sozialer-2013a+ issued: 2013+ language: de-DE+ publisher: Springer VS+ publisher-place: Wiesbaden, Germany+ title: "Sozialer Raum und Soziale Arbeit Fieldbook: Methoden und+ Techniken"+ title-short: Sozialer Raum und Soziale Arbeit Fieldbook+ type: book+---++@fruchtel-sozialer-2013a++Some text [^1].++[^1]: @fruchtel-sozialer-2013a+^D+[Para [Cite [Citation {citationId = "fruchtel-sozialer-2013a", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 1, citationHash = 0}] [Str "Fr\252chtel,",Space,Str "Budde,",Space,Str "and",Space,Str "Cyprian",Space,Str "(2013)"]]+,Para [Str "Some",Space,Str "text",Str ".",Note [Para [Cite [Citation {citationId = "fruchtel-sozialer-2013a", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 2, citationHash = 0}] [Str "Fr\252chtel,",Space,Str "Budde,",Space,Str "and",Space,Str "Cyprian",Space,Str "(2013)"]]],Str ""]+,Div ("refs",["references","csl-bib-body","hanging-indent"],[])+ [Div ("ref-fruchtel-sozialer-2013a",["csl-entry"],[])+ [Para [Str "Fr\252chtel,",Space,Str "Frank,",Space,Str "Wolfgang",Space,Str "Budde,",Space,Str "and",Space,Str "Gudrun",Space,Str "Cyprian.",Space,Str "2013.",Space,Emph [Str "Sozialer",Space,Str "Raum",Space,Str "und",Space,Str "Soziale",Space,Str "Arbeit",Space,Str "Fieldbook:",Space,Str "Methoden",Space,Str "und",Space,Str "Techniken"],Str ".",Space,Str "3rd",Space,Str "ed.",Space,Str "Wiesbaden,",Space,Str "Germany:",Space,Str "Springer",Space,Str "VS."]]]]+```+
@@ -0,0 +1,34 @@+```+% pandoc -f latex -t markdown+\documentclass{amsart}+\newtheorem{thm}{Theorem}[section]+\theoremstyle{definition}+\newtheorem{thm2}[section]{Theorem}+\begin{document}+\begin{thm}+a+\begin{figure}+\includegraphics[]{1.png}+\end{figure}+\end{thm}++\begin{thm2}+a+\begin{figure}+\includegraphics[]{1.png}+\end{figure}+\end{thm2}+\end{document}+^D+::: {.thm}+**Theorem 1**. *a*+++:::++::: {.thm2}+**Theorem 1**. a+++:::+```
@@ -0,0 +1,31 @@+Treat an image alone in its paragraph (but not a figure)+as an independent image:+```+% pandoc -f native -t rst+[Para [Image ("",["align-center"],[]) [Str "https://pandoc.org/diagram.jpg"] ("https://pandoc.org/diagram.jpg","")]]+^D+.. image:: https://pandoc.org/diagram.jpg+ :alt: https://pandoc.org/diagram.jpg+ :align: center+```++Here we just omit the center attribute as it's not valid:+```+% pandoc -f native -t rst+[Para [Str "hi",Space,Image ("",["align-center"],[]) [Str "https://pandoc.org/diagram.jpg"] ("https://pandoc.org/diagram.jpg","")]]+^D+hi |https://pandoc.org/diagram.jpg|++.. |https://pandoc.org/diagram.jpg| image:: https://pandoc.org/diagram.jpg+```++But we can use top, middle, or bottom alignment:+```+% pandoc -f native -t rst+[Para [Str "hi",Space,Image ("",["align-top"],[]) [Str "https://pandoc.org/diagram.jpg"] ("https://pandoc.org/diagram.jpg","")]]+^D+hi |https://pandoc.org/diagram.jpg|++.. |https://pandoc.org/diagram.jpg| image:: https://pandoc.org/diagram.jpg+ :align: top+```
@@ -0,0 +1,18 @@+```+% pandoc --citeproc -t plain --bibliography command/biblio.bib+---+references:+- id: foo+ title: Crazy+ type: book+...++[@foo; @item1]++^D+(Crazy, n.d.; Doe 2005)++Crazy. n.d.++Doe, John. 2005. First Book. Cambridge: Cambridge University Press.+```
@@ -0,0 +1,13 @@+# `\begin{center}`++```+% pandoc -f latex -t native+\begin{center}+Hello+\end{center}++^D+[Div ("",["center"],[])+ [Para [Str "Hello"]]]+```+
@@ -28,11 +28,13 @@ ::: {#refs .references .csl-bib-body} ::: {#ref-a .csl-entry}-[[Doe J.]{.smallcaps} ]{.csl-block}[2000, *Work A*,.]{.csl-left-margin}+[[Doe J.]{.smallcaps} ]{.csl-block}+[2000, *Work A*,.]{.csl-left-margin} ::: ::: {#ref-b .csl-entry}-[[Roe J.]{.smallcaps} ]{.csl-block}[1990, *Work B*,.]{.csl-left-margin}+[[Roe J.]{.smallcaps} ]{.csl-block}+[1990, *Work B*,.]{.csl-left-margin} ::: :::
@@ -23,6 +23,7 @@ <Profile type="string"> $ID/Embedded </Profile>+ <GraphicBounds Left="0" Top="0" Right="300" Bottom="200" /> </Properties> <Link Self="ueb" LinkResourceURI="file:command/corrupt.svg" /> </Image>@@ -56,6 +57,7 @@ <Profile type="string"> $ID/Embedded </Profile>+ <GraphicBounds Left="0" Top="0" Right="300" Bottom="200" /> </Properties> <Link Self="ueb" LinkResourceURI="file:command/SVG_logo.svg" /> </Image>@@ -89,6 +91,7 @@ <Profile type="string"> $ID/Embedded </Profile>+ <GraphicBounds Left="0" Top="0" Right="300" Bottom="200" /> </Properties> <Link Self="ueb" LinkResourceURI="file:command/SVG_logo-without-xml-declaration.svg" /> </Image>@@ -122,6 +125,7 @@ <Profile type="string"> $ID/Embedded </Profile>+ <GraphicBounds Left="0" Top="0" Right="109.5" Bottom="130.5" /> </Properties> <Link Self="ueb" LinkResourceURI="file:command/inkscape-cube.svg" /> </Image>
binary file changed (10052 → 10001 bytes)
binary file changed (9904 → 9853 bytes)
binary file changed (10239 → 10188 bytes)
binary file changed (10003 → 9952 bytes)
binary file changed (10624 → 10578 bytes)
binary file changed (12486 → 12434 bytes)
binary file changed (9895 → 9850 bytes)
binary file changed (9906 → 9856 bytes)
binary file changed (10384 → 10332 bytes)
binary file changed (10040 → 9989 bytes)
binary file changed (26718 → 26667 bytes)
binary file changed (9840 → 9789 bytes)
binary file changed (10010 → 9969 bytes)
binary file changed (26776 → 26725 bytes)
binary file changed (10061 → 10010 bytes)
binary file changed (10236 → 10185 bytes)
binary file changed (10325 → 10261 bytes)
binary file changed (10113 → 10052 bytes)
binary file changed (10208 → 10141 bytes)
binary file changed (10113 → 10053 bytes)
binary file changed (10199 → 10148 bytes)
binary file changed (10006 → 9955 bytes)
binary file changed (absent → 9888 bytes)
binary file changed (absent → 10023 bytes)
binary file changed (9885 → 9834 bytes)
binary file changed (10260 → 10199 bytes)
binary file changed (10276 → 10225 bytes)
binary file changed (9884 → 9833 bytes)
binary file changed (9867 → 9816 bytes)
binary file changed (9901 → 9850 bytes)
binary file changed (10013 → 9962 bytes)
binary file changed (9825 → 9774 bytes)
binary file changed (9873 → 9822 bytes)
@@ -0,0 +1,6 @@+[Para [Str "Cell",Space,Str "compartments"]+,RawBlock (Format "openxml") "<w:tbl>\n<w:tblPr>\n<w:tblW w:w=\"2000\" w:type=\"pct\"/>\n<w:tblBorders>\n<w:top w:val=\"single\" w:sz=\"4\" w:color=\"198200\"/>\n<w:start w:val=\"single\" w:sz=\"4\" w:color=\"198200\"/>\n<w:bottom w:val=\"single\" w:sz=\"4\" w:color=\"198200\"/>\n<w:end w:val=\"single\" w:sz=\"4\" w:color=\"198200\"/>\n</w:tblBorders>\n</w:tblPr>\n<w:tblGrid>\n<w:gridCol w:w=\"1871\" />\n<w:gridCol w:w=\"1872\" />\n</w:tblGrid>\n<w:tr>\n<w:tc>"+,Para [Str "Ribosome"]+,RawBlock (Format "openxml") "</w:tc>\n<w:tc>"+,Para [Str "Lysosome"]+,RawBlock (Format "openxml") "</w:tc>\n</w:tr>\n</w:tbl>"]
@@ -0,0 +1,3 @@+[Para [Str "Manual",Space,Str "endnotes."]+,Para [Str "Nullam",Space,Str "eu",Space,Str "ante",Space,Str "vel",Space,Str "est",Space,Str "convallis",Space,Str "dignissim.",Space,Str "Nunc",Space,Str "porta",Space,Str "vulputate",Space,Str "tellus.",Space,Str "Nunc",Space,Str "rutrum",Space,Str "turpis",Space,Str "sed",Space,Str "pede.",Space,Str "Sed",Space,Str "bibendum.",RawInline (Format "openxml") "<w:bookmarkStart w:id=\"0\" w:name=\"Aliquam\"/>",Str "Aliquam",Space,Str "posuere."]+,Para [Str "Nunc",Space,Str "aliquet,",Space,Str "augue",Space,Str "nec",Space,Str "adipiscing",Space,Str "interdum,",Space,Str "lacus",Space,Str "tellus",Space,Str "malesuada",Space,Str "massa,",Space,Str "quis",Space,Str "varius",Space,Str "mi",Space,Str "purus",Space,Str "non",Space,Str "odio.",RawInline (Format "openxml") "<w:bookmarkEnd w:id=\"0\"/>",Str "Pellentesque",Space,Str "condimentum,",Space,Str "magna",Space,Str "ut",Space,Str "suscipit",Space,Str "hendrerit,",Space,Str "ipsum",Space,Str "augue",Space,Str "ornare",Space,Str "nulla,",Space,Str "non",Space,Str "luctus",Space,Str "diam",Space,Str "neque",Space,Str "sit",Space,Str "amet",Space,Str "urna.",Space,Str "Curabitur",Space,Str "vulputate",Space,Str "vestibulum",Space,Str "lorem."]]
@@ -1,8 +1,8 @@ [Para [Image ("",[],[]) [] ("wasteland-cover.jpg","")] ,Para [Span ("wasteland-content.xhtml",[],[]) []]-,Div ("wasteland-content.xhtml#frontmatter",["section"],[("type","frontmatter")])+,Div ("wasteland-content.xhtml#frontmatter",["section","frontmatter"],[]) []-,Div ("wasteland-content.xhtml#bodymatter",["section"],[("type","bodymatter")])+,Div ("wasteland-content.xhtml#bodymatter",["section","bodymatter"],[]) [Div ("wasteland-content.xhtml#ch1",["section"],[]) [Header 2 ("",[],[]) [Str "I.",Space,Str "THE",Space,Str "BURIAL",Space,Str "OF",Space,Str "THE",Space,Str "DEAD"] ,Div ("",["linegroup"],[])@@ -922,8 +922,8 @@ [Plain [Str "Datta.",Space,Str "Dayadhvam.",Space,Str "Damyata."]] ,Div ("wasteland-content.xhtml#ln434",["linegroup","indent"],[]) [Plain [Span ("",[],[("lang","sa")]) [Str "Shantih",Space,Str "shantih",Space,Str "shantih",Note [Para [Link ("",[],[]) [Str "434."] ("#wasteland-content.xhtml#ln434",""),Space,Str "Shantih.",Space,Str "Repeated",Space,Str "as",Space,Str "here,",Space,Str "a",Space,Str "formal",Space,Str "ending",Space,Str "to",Space,Str "an",Space,Str "Upanishad.",Space,Str "'The",SoftBreak,Str "Peace",Space,Str "which",Space,Str "passeth",Space,Str "understanding'",Space,Str "is",Space,Str "a",Space,Str "feeble",Space,Str "translation",Space,Str "of",Space,Str "the",SoftBreak,Str "content",Space,Str "of",Space,Str "this",Space,Str "word."]],SoftBreak]]]]]]-,Div ("wasteland-content.xhtml#backmatter",["section"],[("type","backmatter")])- [Div ("wasteland-content.xhtml#rearnotes",["section"],[("type","rearnotes")])+,Div ("wasteland-content.xhtml#backmatter",["section","backmatter"],[])+ [Div ("wasteland-content.xhtml#rearnotes",["section","rearnotes"],[]) [Header 2 ("",[],[]) [Str "NOTES",Space,Str "ON",Space,Str "\"THE",Space,Str "WASTE",Space,Str "LAND\""] ,Para [Str "Not",Space,Str "only",Space,Str "the",Space,Str "title,",Space,Str "but",Space,Str "the",Space,Str "plan",Space,Str "and",Space,Str "a",Space,Str "good",Space,Str "deal",Space,Str "of",Space,Str "the",Space,Str "incidental",Space,Str "symbolism",Space,Str "of",SoftBreak,Str "the",Space,Str "poem",Space,Str "were",Space,Str "suggested",Space,Str "by",Space,Str "Miss",Space,Str "Jessie",Space,Str "L.",Space,Str "Weston's",Space,Str "book",Space,Str "on",Space,Str "the",Space,Str "Grail",Space,Str "legend:",SoftBreak,Str "From",Space,Str "Ritual",Space,Str "to",Space,Str "Romance"] ,Para [Str "Indeed,",Space,Str "so",Space,Str "deeply",Space,Str "am",Space,Str "I",Space,Str "indebted,",Space,Str "Miss",Space,Str "Weston's",Space,Str "book",Space,Str "will",Space,Str "elucidate",Space,Str "the",SoftBreak,Str "difficulties",Space,Str "of",Space,Str "the",Space,Str "poem",Space,Str "much",Space,Str "better",Space,Str "than",Space,Str "my",Space,Str "notes",Space,Str "can",Space,Str "do;",Space,Str "and",Space,Str "I",Space,Str "recommend",Space,Str "it",SoftBreak,Str "(apart",Space,Str "from",Space,Str "the",Space,Str "great",Space,Str "interest",Space,Str "of",Space,Str "the",Space,Str "book",Space,Str "itself)",Space,Str "to",Space,Str "any",Space,Str "who",Space,Str "think",Space,Str "such",SoftBreak,Str "elucidation",Space,Str "of",Space,Str "the",Space,Str "poem",Space,Str "worth",Space,Str "the",Space,Str "trouble.",Space,Str "To",Space,Str "another",Space,Str "work",Space,Str "of",Space,Str "anthropology",Space,Str "I",Space,Str "am",SoftBreak,Str "indebted",Space,Str "in",Space,Str "general,",Space,Str "one",Space,Str "which",Space,Str "has",Space,Str "influenced",Space,Str "our",Space,Str "generation",Space,Str "profoundly;",Space,Str "I",Space,Str "mean",SoftBreak,Str "The",Space,Str "Golden",Space,Str "Bough;",Space,Str "I",Space,Str "have",Space,Str "used",Space,Str "especially",Space,Str "the",Space,Str "two",Space,Str "volumes",Space,Str "Adonis,",Space,Str "Attis,",Space,Str "Osiris.",SoftBreak,Str "Anyone",Space,Str "who",Space,Str "is",Space,Str "acquainted",Space,Str "with",Space,Str "these",Space,Str "works",Space,Str "will",Space,Str "immediately",Space,Str "recognise",Space,Str "in",Space,Str "the",Space,Str "poem",SoftBreak,Str "certain",Space,Str "references",Space,Str "to",Space,Str "vegetation",Space,Str "ceremonies."]
@@ -487,6 +487,7 @@ </tbody> </table> <hr />+<p>Row headers</p> <table> <thead> <tr>@@ -656,6 +657,7 @@ </tbody> </table> <hr />+<p>tbody tags omitted</p> <table> <tr> <td>1</td>@@ -669,6 +671,7 @@ </tr> </table> <hr />+<p>empty head</p> <table> <thead> </thead>@@ -686,6 +689,7 @@ </tbody> </table> <hr />+<p>explicit body and foot</p> <table> <tbody> <tr>@@ -701,6 +705,78 @@ <td>6</td> </tr> </tfoot>+</table>+<h2>Colspans and Rowspans</h2>+<table>+ <tr>+ <td colspan="2">1 and 2</td>+ <td>3</td>+ </tr>+ <tr>+ <td colspan="3">4, 5, and 6</td>+ </tr>+</table>+<hr/>+<table>+ <thead>+ <tr>+ <th colspan="3">Numbers</th>+ </tr>+ </thead>+ <tbody>+ <tr>+ <td rowspan="2">1 and 4</td>+ <td>2</td>+ <td>3</td>+ </tr>+ <tr>+ <td>5</td>+ <td>6</td>+ </tr>+ </tbody>+</table>+<h2>Attributes</h2>+<table id="attrib-test-table">+ <thead class="table-head">+ <tr class="table-head-row">+ <th abbr="x" colspan="3">Cat X</th>+ </tr>+ <tbody data-part="body" class="main">+ <tr data-part="row">+ <td data-part="cell">1</td>+ <td valign="bottom">2</td>+ <td style="color: #151950">3</td>+ </tr>+ </tbody>+ <tfoot class="summary">+ <tr bgcolor="#ccc">+ <td data-square="true">4</td>+ <td>5</td>+ <td>6</td>+ </tr>+ </tfoot>+</table>+<h2>Tag omission</h2>+<p>thead, tbody, and tfoot</p>+<table>+ <thead>+ <tr>+ <td>X</td>+ <td>Y</td>+ <td>Z</td>+ </tr>+ <tbody>+ <tr>+ <td>1</td>+ <td>2</td>+ <td>3</td>+ </tr>+ <tfoot>+ <tr>+ <td>4</td>+ <td>5</td>+ <td>6</td>+ </tr> </table> <h2>Empty Tables</h2> <p>This section should be empty.</p>
@@ -395,6 +395,7 @@ (TableFoot ("",[],[]) []) ,HorizontalRule+,Para [Str "Row",Space,Str "headers"] ,Table ("",[],[]) (Caption Nothing []) [(AlignDefault,ColWidthDefault)@@ -408,7 +409,7 @@ [Plain [Str "Y"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Z"]]]])- [(TableBody ("",[],[]) (RowHeadColumns 0)+ [(TableBody ("",[],[]) (RowHeadColumns 1) [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)@@ -440,7 +441,7 @@ [Plain [Str "Y"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Z"]]]])- [(TableBody ("",[],[]) (RowHeadColumns 0)+ [(TableBody ("",[],[]) (RowHeadColumns 1) [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)@@ -448,16 +449,15 @@ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "3"]]]- ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "4"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "5"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "6"]]]])]+ [Plain [Str "3"]]]])] (TableFoot ("",[],[])- [])+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "6"]]]]) ,HorizontalRule ,Table ("",[],[]) (Caption Nothing [])@@ -473,15 +473,14 @@ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Z"]]]]) [(TableBody ("",[],[]) (RowHeadColumns 0)- [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "3"]]]- ,Row ("",[],[])+ [Plain [Str "3"]]]]+ [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)@@ -497,17 +496,17 @@ ,(AlignDefault,ColWidthDefault) ,(AlignDefault,ColWidthDefault)] (TableHead ("",[],[])- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "X"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "Y"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "Z"]]]])+ []) [(TableBody ("",[],[]) (RowHeadColumns 0)- [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "X"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Y"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Z"]]]]+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2"]]@@ -529,17 +528,17 @@ ,(AlignDefault,ColWidthDefault) ,(AlignDefault,ColWidthDefault)] (TableHead ("",[],[])- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "X"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "Y"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "Z"]]]])+ []) [(TableBody ("",[],[]) (RowHeadColumns 0)- [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "X"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Y"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Z"]]]]+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2"]]@@ -576,8 +575,10 @@ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "3"]]]- ,Row ("",[],[])+ [Plain [Str "3"]]]])+ ,(TableBody ("",[],[]) (RowHeadColumns 0)+ []+ [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)@@ -608,8 +609,10 @@ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Para [Str "2"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "3"]]]- ,Row ("",[],[])+ [Plain [Str "3"]]]])+ ,(TableBody ("",[],[]) (RowHeadColumns 0)+ []+ [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)@@ -645,6 +648,7 @@ (TableFoot ("",[],[]) []) ,HorizontalRule+,Para [Str "tbody",Space,Str "tags",Space,Str "omitted"] ,Table ("",[],[]) (Caption Nothing []) [(AlignDefault,ColWidthDefault)@@ -671,6 +675,7 @@ (TableFoot ("",[],[]) []) ,HorizontalRule+,Para [Str "empty",Space,Str "head"] ,Table ("",[],[]) (Caption Nothing []) [(AlignDefault,ColWidthDefault)@@ -697,6 +702,7 @@ (TableFoot ("",[],[]) []) ,HorizontalRule+,Para [Str "explicit",Space,Str "body",Space,Str "and",Space,Str "foot"] ,Table ("",[],[]) (Caption Nothing []) [(AlignDefault,ColWidthDefault)@@ -712,15 +718,119 @@ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "3"]]]])]+ (TableFoot ("",[],[])+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "6"]]]])+,Header 2 ("colspans-and-rowspans",[],[]) [Str "Colspans",Space,Str "and",Space,Str "Rowspans"]+,Table ("",[],[]) (Caption Nothing+ [])+ [(AlignDefault,ColWidthDefault)+ ,(AlignDefault,ColWidthDefault)+ ,(AlignDefault,ColWidthDefault)]+ (TableHead ("",[],[])+ [])+ [(TableBody ("",[],[]) (RowHeadColumns 0)+ []+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2)+ [Plain [Str "1",Space,Str "and",Space,Str "2"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "3"]]] ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)- [Plain [Str "4"]]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 3)+ [Plain [Str "4,",Space,Str "5,",Space,Str "and",Space,Str "6"]]]])]+ (TableFoot ("",[],[])+ [])+,HorizontalRule+,Table ("",[],[]) (Caption Nothing+ [])+ [(AlignDefault,ColWidthDefault)+ ,(AlignDefault,ColWidthDefault)+ ,(AlignDefault,ColWidthDefault)]+ (TableHead ("",[],[])+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 3)+ [Plain [Str "Numbers"]]]])+ [(TableBody ("",[],[]) (RowHeadColumns 0)+ []+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1)+ [Plain [Str "1",Space,Str "and",Space,Str "4"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "2"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "3"]]]+ ,Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5"]] ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "6"]]]])] (TableFoot ("",[],[]) [])+,Header 2 ("attributes",[],[]) [Str "Attributes"]+,Table ("attrib-test-table",[],[]) (Caption Nothing+ [])+ [(AlignDefault,ColWidthDefault)+ ,(AlignDefault,ColWidthDefault)+ ,(AlignDefault,ColWidthDefault)]+ (TableHead ("",["table-head"],[])+ [Row ("",["table-head-row"],[])+ [Cell ("",[],[("abbr","x")]) AlignDefault (RowSpan 1) (ColSpan 3)+ [Plain [Str "Cat",Space,Str "X"]]]])+ [(TableBody ("",["main"],[("part","body")]) (RowHeadColumns 0)+ []+ [Row ("",[],[("part","row")])+ [Cell ("",[],[("part","cell")]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "1"]]+ ,Cell ("",[],[("valign","bottom")]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "2"]]+ ,Cell ("",[],[("style","color: #151950")]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "3"]]]])]+ (TableFoot ("",["summary"],[])+ [Row ("",[],[("bgcolor","#ccc")])+ [Cell ("",[],[("square","true")]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "6"]]]])+,Header 2 ("tag-omission",[],[]) [Str "Tag",Space,Str "omission"]+,Para [Str "thead,",Space,Str "tbody,",Space,Str "and",Space,Str "tfoot"]+,Table ("",[],[]) (Caption Nothing+ [])+ [(AlignDefault,ColWidthDefault)+ ,(AlignDefault,ColWidthDefault)+ ,(AlignDefault,ColWidthDefault)]+ (TableHead ("",[],[])+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "X"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Y"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Z"]]]])+ [(TableBody ("",[],[]) (RowHeadColumns 0)+ []+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "1"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "2"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "3"]]]])]+ (TableFoot ("",[],[])+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "6"]]]]) ,Header 2 ("empty-tables",[],[]) [Str "Empty",Space,Str "Tables"] ,Para [Str "This",Space,Str "section",Space,Str "should",Space,Str "be",Space,Str "empty."]]
@@ -1,7 +1,8 @@ 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"])]}) [RawBlock (Format "latex") "\\maketitle" ,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",SoftBreak,Str "John",Space,Str "Gruber\8217s",Space,Str "markdown",Space,Str "test",Space,Str "suite."]-,HorizontalRule+,Div ("",["center"],[])+ [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"]]@@ -13,13 +14,15 @@ ,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+,Div ("",["center"],[])+ [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",SoftBreak,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",SoftBreak,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+,Div ("",["center"],[])+ [HorizontalRule] ,Header 1 ("block-quotes",[],[]) [Str "Block",Space,Str "Quotes"] ,Para [Str "E-mail",Space,Str "style:"] ,BlockQuote@@ -51,14 +54,16 @@ ,BlockQuote [Para [Str "Don\8217t",Space,Str "quote",Space,Str "me."]]] ,Para [Str "And",Space,Str "a",Space,Str "following",Space,Str "paragraph."]-,HorizontalRule+,Div ("",["center"],[])+ [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: \\$ \\\\ \\> \\[ \\{" ,Para [Str "this",Space,Str "has",Space,Emph [Str "two",LineBreak,Str "lines"]]-,HorizontalRule+,Div ("",["center"],[])+ [HorizontalRule] ,Header 1 ("lists",[],[]) [Str "Lists"] ,Header 2 ("unordered",[],[]) [Str "Unordered"] ,Para [Str "Asterisks",Space,Str "tight:"]@@ -179,7 +184,8 @@ ,Para [Str "Should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "list",Space,Str "item:"] ,Para [Str "M.A.",Space,Str "2007"] ,Para [Str "B.",Space,Str "Williams"]-,HorizontalRule+,Div ("",["center"],[])+ [HorizontalRule] ,Header 1 ("definition-lists",[],[]) [Str "Definition",Space,Str "Lists"] ,Para [Str "Tight",Space,Str "using",Space,Str "spaces:"] ,DefinitionList@@ -233,7 +239,8 @@ ,Para [Str "Code:"] ,CodeBlock ("",[],[]) "<hr />" ,Para [Str "Hr\8217s:"]-,HorizontalRule+,Div ("",["center"],[])+ [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 "."]@@ -247,7 +254,8 @@ ,Para [Str "Superscripts:",Space,Str "a",Superscript [Str "bc"],Str "d",SoftBreak,Str "a",Superscript [Emph [Str "hello"]],Space,Str "a",Superscript [Str "hello",Space,Str "there"],Str "."] ,Para [Str "Subscripts:",Space,Str "H",Subscript [Str "2"],Str "O,",Space,Str "H",Subscript [Str "23"],Str "O,",SoftBreak,Str "H",Subscript [Str "many",Space,Str "of",Space,Str "them"],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",SoftBreak,Str "unescaped",Space,Str "spaces:",Space,Str "a^b",Space,Str "c^d,",Space,Str "a",Math InlineMath "\\sim",Str "b",SoftBreak,Str "c",Math InlineMath "\\sim",Str "d."]-,HorizontalRule+,Div ("",["center"],[])+ [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 [Str "\8198",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."]@@ -257,7 +265,8 @@ ,Para [Str "Some",Space,Str "dashes:",Space,Str "one\8212two\8212three\8212four\8212five."] ,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+,Div ("",["center"],[])+ [HorizontalRule] ,Header 1 ("latex",[],[]) [Str "LaTeX"] ,BulletList [[Para [Cite [Citation {citationId = "smith.1899", citationPrefix = [], citationSuffix = [Str "22-23"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline (Format "latex") "\\cite[22-23]{smith.1899}"]]]@@ -315,7 +324,8 @@ [Plain [Str "Vegetable"]]]])] (TableFoot ("",[],[]) [])-,HorizontalRule+,Div ("",["center"],[])+ [HorizontalRule] ,Header 1 ("special-characters",[],[]) [Str "Special",Space,Str "Characters"] ,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode:"] ,BulletList@@ -345,7 +355,8 @@ ,Para [Str "Bang:",Space,Str "!"] ,Para [Str "Plus:",Space,Str "+"] ,Para [Str "Minus:",Space,Str "-"]-,HorizontalRule+,Div ("",["center"],[])+ [HorizontalRule] ,Header 1 ("links",[],[]) [Str "Links"] ,Header 2 ("explicit",[],[]) [Str "Explicit"] ,Para [Str "Just",Space,Str "a",Space,Link ("",[],[]) [Str "URL"] ("/url/",""),Str "."]@@ -386,12 +397,14 @@ [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+,Div ("",["center"],[])+ [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 "image"] ("lalune.jpg","")] ,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image ("",[],[]) [Str "image"] ("movie.jpg",""),Space,Str "icon."]-,HorizontalRule+,Div ("",["center"],[])+ [HorizontalRule] ,Header 1 ("footnotes",[],[]) [Str "Footnotes"] ,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",SoftBreak,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",SoftBreak,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."]],SoftBreak,Str "and",SoftBreak,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",SoftBreak,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",SoftBreak,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."]],SoftBreak,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",SoftBreak,Str "a",Space,Str "space.[^my",Space,Str "note]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",SoftBreak,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",SoftBreak,Link ("",[],[]) [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code ("",[],[]) "]",Space,Str "verbatim",Space,Str "characters,",SoftBreak,Str "as",Space,Str "well",Space,Str "as",Space,Str "[bracketed",Space,Str "text]."]]] ,BlockQuote
@@ -145,6 +145,7 @@ pre > code.sourceCode { white-space: pre; position: relative; } pre > code.sourceCode > span { display: inline-block; line-height: 1.25; } pre > code.sourceCode > span:empty { height: 1.2em; }+ .sourceCode { overflow: visible; } code.sourceCode > span { color: inherit; text-decoration: inherit; } div.sourceCode { margin: 1em 0; } pre.sourceCode { margin: 0; }
@@ -145,6 +145,7 @@ pre > code.sourceCode { white-space: pre; position: relative; } pre > code.sourceCode > span { display: inline-block; line-height: 1.25; } pre > code.sourceCode > span:empty { height: 1.2em; }+ .sourceCode { overflow: visible; } code.sourceCode > span { color: inherit; text-decoration: inherit; } div.sourceCode { margin: 1em 0; } pre.sourceCode { margin: 0; }
@@ -4,14 +4,13 @@ % \documentclass[ ]{article}+\usepackage{amsmath,amssymb} \usepackage{lmodern}-\usepackage{amsmath} \usepackage{ifxetex,ifluatex} \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage{textcomp} % provide euro and other symbols- \usepackage{amssymb} \else % if luatex or xetex \usepackage{unicode-math} \defaultfontfeatures{Scale=MatchLowercase}
@@ -4,14 +4,13 @@ % \documentclass[ ]{article}+\usepackage{amsmath,amssymb} \usepackage{lmodern}-\usepackage{amsmath} \usepackage{ifxetex,ifluatex} \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage{textcomp} % provide euro and other symbols- \usepackage{amssymb} \else % if luatex or xetex \usepackage{unicode-math} \defaultfontfeatures{Scale=MatchLowercase}
@@ -4,35 +4,31 @@ <p>Demonstration of simple table syntax.</p> </caption> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="left" /> <thead> <tr>- <th>Right</th>- <th>Left</th>- <th>Center</th>+ <th align="right">Right</th>+ <th align="left">Left</th>+ <th align="center">Center</th> <th>Default</th> </tr> </thead> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td> <td>12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td> <td>123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td> <td>1</td> </tr> </tbody>@@ -41,35 +37,31 @@ <p>Simple table without caption:</p> <table-wrap> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="left" /> <thead> <tr>- <th>Right</th>- <th>Left</th>- <th>Center</th>+ <th align="right">Right</th>+ <th align="left">Left</th>+ <th align="center">Center</th> <th>Default</th> </tr> </thead> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td> <td>12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td> <td>123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td> <td>1</td> </tr> </tbody>@@ -81,35 +73,31 @@ <p>Demonstration of simple table syntax.</p> </caption> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="left" /> <thead> <tr>- <th>Right</th>- <th>Left</th>- <th>Center</th>+ <th align="right">Right</th>+ <th align="left">Left</th>+ <th align="center">Center</th> <th>Default</th> </tr> </thead> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td> <td>12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td> <td>123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td> <td>1</td> </tr> </tbody>@@ -121,30 +109,33 @@ <p>Here’s the caption. It may span multiple lines.</p> </caption> <table>- <col width="15*" align="center" />- <col width="13*" align="left" />- <col width="16*" align="right" />- <col width="35*" align="left" />+ <colgroup>+ <col width="15%" />+ <col width="14%" />+ <col width="16%" />+ <col width="35%" />+ </colgroup> <thead> <tr>- <th>Centered Header</th>- <th>Left Aligned</th>- <th>Right Aligned</th>- <th>Default aligned</th>+ <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>- <td>First</td>- <td>row</td>- <td>12.0</td>- <td>Example of a row that spans multiple lines.</td>+ <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>- <td>Second</td>- <td>row</td>- <td>5.0</td>- <td>Here’s another one. Note the blank line between rows.</td>+ <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>@@ -152,30 +143,33 @@ <p>Multiline table without caption:</p> <table-wrap> <table>- <col width="15*" align="center" />- <col width="13*" align="left" />- <col width="16*" align="right" />- <col width="35*" align="left" />+ <colgroup>+ <col width="15%" />+ <col width="14%" />+ <col width="16%" />+ <col width="35%" />+ </colgroup> <thead> <tr>- <th>Centered Header</th>- <th>Left Aligned</th>- <th>Right Aligned</th>- <th>Default aligned</th>+ <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>- <td>First</td>- <td>row</td>- <td>12.0</td>- <td>Example of a row that spans multiple lines.</td>+ <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>- <td>Second</td>- <td>row</td>- <td>5.0</td>- <td>Here’s another one. Note the blank line between rows.</td>+ <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>@@ -183,28 +177,24 @@ <p>Table without column headers:</p> <table-wrap> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="right" /> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td>+ <td align="right">12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td>+ <td align="right">123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td>+ <td align="right">1</td> </tr> </tbody> </table>@@ -212,21 +202,23 @@ <p>Multiline table without column headers:</p> <table-wrap> <table>- <col width="15*" align="center" />- <col width="13*" align="left" />- <col width="16*" align="right" />- <col width="35*" align="left" />+ <colgroup>+ <col width="15%" />+ <col width="14%" />+ <col width="16%" />+ <col width="35%" />+ </colgroup> <tbody> <tr>- <td>First</td>- <td>row</td>- <td>12.0</td>+ <td align="center">First</td>+ <td align="left">row</td>+ <td align="right">12.0</td> <td>Example of a row that spans multiple lines.</td> </tr> <tr>- <td>Second</td>- <td>row</td>- <td>5.0</td>+ <td align="center">Second</td>+ <td align="left">row</td>+ <td align="right">5.0</td> <td>Here’s another one. Note the blank line between rows.</td> </tr> </tbody>
@@ -4,35 +4,31 @@ <p>Demonstration of simple table syntax.</p> </caption> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="left" /> <thead> <tr>- <th>Right</th>- <th>Left</th>- <th>Center</th>+ <th align="right">Right</th>+ <th align="left">Left</th>+ <th align="center">Center</th> <th>Default</th> </tr> </thead> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td> <td>12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td> <td>123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td> <td>1</td> </tr> </tbody>@@ -41,35 +37,31 @@ <p>Simple table without caption:</p> <table-wrap> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="left" /> <thead> <tr>- <th>Right</th>- <th>Left</th>- <th>Center</th>+ <th align="right">Right</th>+ <th align="left">Left</th>+ <th align="center">Center</th> <th>Default</th> </tr> </thead> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td> <td>12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td> <td>123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td> <td>1</td> </tr> </tbody>@@ -81,35 +73,31 @@ <p>Demonstration of simple table syntax.</p> </caption> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="left" /> <thead> <tr>- <th>Right</th>- <th>Left</th>- <th>Center</th>+ <th align="right">Right</th>+ <th align="left">Left</th>+ <th align="center">Center</th> <th>Default</th> </tr> </thead> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td> <td>12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td> <td>123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td> <td>1</td> </tr> </tbody>@@ -121,30 +109,33 @@ <p>Here’s the caption. It may span multiple lines.</p> </caption> <table>- <col width="15*" align="center" />- <col width="13*" align="left" />- <col width="16*" align="right" />- <col width="35*" align="left" />+ <colgroup>+ <col width="15%" />+ <col width="14%" />+ <col width="16%" />+ <col width="35%" />+ </colgroup> <thead> <tr>- <th>Centered Header</th>- <th>Left Aligned</th>- <th>Right Aligned</th>- <th>Default aligned</th>+ <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>- <td>First</td>- <td>row</td>- <td>12.0</td>- <td>Example of a row that spans multiple lines.</td>+ <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>- <td>Second</td>- <td>row</td>- <td>5.0</td>- <td>Here’s another one. Note the blank line between rows.</td>+ <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>@@ -152,30 +143,33 @@ <p>Multiline table without caption:</p> <table-wrap> <table>- <col width="15*" align="center" />- <col width="13*" align="left" />- <col width="16*" align="right" />- <col width="35*" align="left" />+ <colgroup>+ <col width="15%" />+ <col width="14%" />+ <col width="16%" />+ <col width="35%" />+ </colgroup> <thead> <tr>- <th>Centered Header</th>- <th>Left Aligned</th>- <th>Right Aligned</th>- <th>Default aligned</th>+ <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>- <td>First</td>- <td>row</td>- <td>12.0</td>- <td>Example of a row that spans multiple lines.</td>+ <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>- <td>Second</td>- <td>row</td>- <td>5.0</td>- <td>Here’s another one. Note the blank line between rows.</td>+ <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>@@ -183,28 +177,24 @@ <p>Table without column headers:</p> <table-wrap> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="right" /> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td>+ <td align="right">12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td>+ <td align="right">123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td>+ <td align="right">1</td> </tr> </tbody> </table>@@ -212,21 +202,23 @@ <p>Multiline table without column headers:</p> <table-wrap> <table>- <col width="15*" align="center" />- <col width="13*" align="left" />- <col width="16*" align="right" />- <col width="35*" align="left" />+ <colgroup>+ <col width="15%" />+ <col width="14%" />+ <col width="16%" />+ <col width="35%" />+ </colgroup> <tbody> <tr>- <td>First</td>- <td>row</td>- <td>12.0</td>+ <td align="center">First</td>+ <td align="left">row</td>+ <td align="right">12.0</td> <td>Example of a row that spans multiple lines.</td> </tr> <tr>- <td>Second</td>- <td>row</td>- <td>5.0</td>+ <td align="center">Second</td>+ <td align="left">row</td>+ <td align="right">5.0</td> <td>Here’s another one. Note the blank line between rows.</td> </tr> </tbody>
@@ -4,35 +4,31 @@ <p>Demonstration of simple table syntax.</p> </caption> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="left" /> <thead> <tr>- <th>Right</th>- <th>Left</th>- <th>Center</th>+ <th align="right">Right</th>+ <th align="left">Left</th>+ <th align="center">Center</th> <th>Default</th> </tr> </thead> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td> <td>12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td> <td>123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td> <td>1</td> </tr> </tbody>@@ -41,35 +37,31 @@ <p>Simple table without caption:</p> <table-wrap> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="left" /> <thead> <tr>- <th>Right</th>- <th>Left</th>- <th>Center</th>+ <th align="right">Right</th>+ <th align="left">Left</th>+ <th align="center">Center</th> <th>Default</th> </tr> </thead> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td> <td>12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td> <td>123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td> <td>1</td> </tr> </tbody>@@ -81,35 +73,31 @@ <p>Demonstration of simple table syntax.</p> </caption> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="left" /> <thead> <tr>- <th>Right</th>- <th>Left</th>- <th>Center</th>+ <th align="right">Right</th>+ <th align="left">Left</th>+ <th align="center">Center</th> <th>Default</th> </tr> </thead> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td> <td>12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td> <td>123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td> <td>1</td> </tr> </tbody>@@ -121,30 +109,33 @@ <p>Here’s the caption. It may span multiple lines.</p> </caption> <table>- <col width="15*" align="center" />- <col width="13*" align="left" />- <col width="16*" align="right" />- <col width="35*" align="left" />+ <colgroup>+ <col width="15%" />+ <col width="14%" />+ <col width="16%" />+ <col width="35%" />+ </colgroup> <thead> <tr>- <th>Centered Header</th>- <th>Left Aligned</th>- <th>Right Aligned</th>- <th>Default aligned</th>+ <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>- <td>First</td>- <td>row</td>- <td>12.0</td>- <td>Example of a row that spans multiple lines.</td>+ <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>- <td>Second</td>- <td>row</td>- <td>5.0</td>- <td>Here’s another one. Note the blank line between rows.</td>+ <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>@@ -152,30 +143,33 @@ <p>Multiline table without caption:</p> <table-wrap> <table>- <col width="15*" align="center" />- <col width="13*" align="left" />- <col width="16*" align="right" />- <col width="35*" align="left" />+ <colgroup>+ <col width="15%" />+ <col width="14%" />+ <col width="16%" />+ <col width="35%" />+ </colgroup> <thead> <tr>- <th>Centered Header</th>- <th>Left Aligned</th>- <th>Right Aligned</th>- <th>Default aligned</th>+ <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>- <td>First</td>- <td>row</td>- <td>12.0</td>- <td>Example of a row that spans multiple lines.</td>+ <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>- <td>Second</td>- <td>row</td>- <td>5.0</td>- <td>Here’s another one. Note the blank line between rows.</td>+ <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>@@ -183,28 +177,24 @@ <p>Table without column headers:</p> <table-wrap> <table>- <col align="right" />- <col align="left" />- <col align="center" />- <col align="right" /> <tbody> <tr>- <td>12</td>- <td>12</td>- <td>12</td>- <td>12</td>+ <td align="right">12</td>+ <td align="left">12</td>+ <td align="center">12</td>+ <td align="right">12</td> </tr> <tr>- <td>123</td>- <td>123</td>- <td>123</td>- <td>123</td>+ <td align="right">123</td>+ <td align="left">123</td>+ <td align="center">123</td>+ <td align="right">123</td> </tr> <tr>- <td>1</td>- <td>1</td>- <td>1</td>- <td>1</td>+ <td align="right">1</td>+ <td align="left">1</td>+ <td align="center">1</td>+ <td align="right">1</td> </tr> </tbody> </table>@@ -212,21 +202,23 @@ <p>Multiline table without column headers:</p> <table-wrap> <table>- <col width="15*" align="center" />- <col width="13*" align="left" />- <col width="16*" align="right" />- <col width="35*" align="left" />+ <colgroup>+ <col width="15%" />+ <col width="14%" />+ <col width="16%" />+ <col width="35%" />+ </colgroup> <tbody> <tr>- <td>First</td>- <td>row</td>- <td>12.0</td>+ <td align="center">First</td>+ <td align="left">row</td>+ <td align="right">12.0</td> <td>Example of a row that spans multiple lines.</td> </tr> <tr>- <td>Second</td>- <td>row</td>- <td>5.0</td>+ <td align="center">Second</td>+ <td align="left">row</td>+ <td align="right">5.0</td> <td>Here’s another one. Note the blank line between rows.</td> </tr> </tbody>
@@ -3,16 +3,16 @@ \begin{longtable}[]{@{}rlcl@{}} \caption{Demonstration of simple table syntax.}\tabularnewline \toprule-Right & Left & Center & Default\tabularnewline+Right & Left & Center & Default \\ \addlinespace \midrule \endfirsthead \toprule-Right & Left & Center & Default\tabularnewline+Right & Left & Center & Default \\ \addlinespace \midrule \endhead-12 & 12 & 12 & 12\tabularnewline-123 & 123 & 123 & 123\tabularnewline-1 & 1 & 1 & 1\tabularnewline+12 & 12 & 12 & 12 \\ \addlinespace+123 & 123 & 123 & 123 \\ \addlinespace+1 & 1 & 1 & 1 \\ \addlinespace \bottomrule \end{longtable} @@ -20,12 +20,12 @@ \begin{longtable}[]{@{}rlcl@{}} \toprule-Right & Left & Center & Default\tabularnewline+Right & Left & Center & Default \\ \addlinespace \midrule \endhead-12 & 12 & 12 & 12\tabularnewline-123 & 123 & 123 & 123\tabularnewline-1 & 1 & 1 & 1\tabularnewline+12 & 12 & 12 & 12 \\ \addlinespace+123 & 123 & 123 & 123 \\ \addlinespace+1 & 1 & 1 & 1 \\ \addlinespace \bottomrule \end{longtable} @@ -34,122 +34,60 @@ \begin{longtable}[]{@{}rlcl@{}} \caption{Demonstration of simple table syntax.}\tabularnewline \toprule-Right & Left & Center & Default\tabularnewline+Right & Left & Center & Default \\ \addlinespace \midrule \endfirsthead \toprule-Right & Left & Center & Default\tabularnewline+Right & Left & Center & Default \\ \addlinespace \midrule \endhead-12 & 12 & 12 & 12\tabularnewline-123 & 123 & 123 & 123\tabularnewline-1 & 1 & 1 & 1\tabularnewline+12 & 12 & 12 & 12 \\ \addlinespace+123 & 123 & 123 & 123 \\ \addlinespace+1 & 1 & 1 & 1 \\ \addlinespace \bottomrule \end{longtable} Multiline table with caption: -\begin{longtable}[]{@{}clrl@{}}+\begin{longtable}[]{@{}+ >{\centering\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.15}}+ >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.14}}+ >{\raggedleft\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.16}}+ >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.35}}@{}} \caption{Here's the caption. It may span multiple lines.}\tabularnewline \toprule-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering-Centered Header\strut-\end{minipage} &-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright-Left Aligned\strut-\end{minipage} &-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft-Right Aligned\strut-\end{minipage} &-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright-Default aligned\strut-\end{minipage}\tabularnewline+Centered Header & Left Aligned & Right Aligned & Default+aligned \\ \addlinespace \midrule \endfirsthead \toprule-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering-Centered Header\strut-\end{minipage} &-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright-Left Aligned\strut-\end{minipage} &-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft-Right Aligned\strut-\end{minipage} &-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright-Default aligned\strut-\end{minipage}\tabularnewline+Centered Header & Left Aligned & Right Aligned & Default+aligned \\ \addlinespace \midrule \endhead-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering-First\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright-row\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft-12.0\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright-Example of a row that spans multiple lines.\strut-\end{minipage}\tabularnewline-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering-Second\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright-row\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft-5.0\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright-Here's another one. Note the blank line between rows.\strut-\end{minipage}\tabularnewline+First & row & 12.0 & Example of a row that spans multiple+lines. \\ \addlinespace+Second & row & 5.0 & Here's another one. Note the blank line between+rows. \\ \addlinespace \bottomrule \end{longtable} Multiline table without caption: -\begin{longtable}[]{@{}clrl@{}}+\begin{longtable}[]{@{}+ >{\centering\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.15}}+ >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.14}}+ >{\raggedleft\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.16}}+ >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.35}}@{}} \toprule-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering-Centered Header\strut-\end{minipage} &-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright-Left Aligned\strut-\end{minipage} &-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft-Right Aligned\strut-\end{minipage} &-\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright-Default aligned\strut-\end{minipage}\tabularnewline+Centered Header & Left Aligned & Right Aligned & Default+aligned \\ \addlinespace \midrule \endhead-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering-First\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright-row\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft-12.0\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright-Example of a row that spans multiple lines.\strut-\end{minipage}\tabularnewline-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering-Second\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright-row\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft-5.0\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright-Here's another one. Note the blank line between rows.\strut-\end{minipage}\tabularnewline+First & row & 12.0 & Example of a row that spans multiple+lines. \\ \addlinespace+Second & row & 5.0 & Here's another one. Note the blank line between+rows. \\ \addlinespace \bottomrule \end{longtable} @@ -158,40 +96,24 @@ \begin{longtable}[]{@{}rlcr@{}} \toprule \endhead-12 & 12 & 12 & 12\tabularnewline-123 & 123 & 123 & 123\tabularnewline-1 & 1 & 1 & 1\tabularnewline+12 & 12 & 12 & 12 \\ \addlinespace+123 & 123 & 123 & 123 \\ \addlinespace+1 & 1 & 1 & 1 \\ \addlinespace \bottomrule \end{longtable} Multiline table without column headers: -\begin{longtable}[]{@{}clrl@{}}+\begin{longtable}[]{@{}+ >{\centering\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.15}}+ >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.14}}+ >{\raggedleft\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.16}}+ >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.35}}@{}} \toprule \endhead-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering-First\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright-row\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft-12.0\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright-Example of a row that spans multiple lines.\strut-\end{minipage}\tabularnewline-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering-Second\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright-row\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft-5.0\strut-\end{minipage} &-\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright-Here's another one. Note the blank line between rows.\strut-\end{minipage}\tabularnewline+First & row & 12.0 & Example of a row that spans multiple+lines. \\ \addlinespace+Second & row & 5.0 & Here's another one. Note the blank line between+rows. \\ \addlinespace \bottomrule \end{longtable}
@@ -1,46 +1,73 @@-[Table ("nordics",[],[("source","wikipedia")]) (Caption (Just [Str "Nordic countries"])- [Para [Str "States", Space, Str "belonging", Space, Str "to", Space, Str "the", Space, Emph [Str "Nordics."]]])+[Table ("nordics",[],[("source","wikipedia")]) (Caption (Just [Str "Nordic",Space,Str "countries"])+ [Para [Str "States",Space,Str "belonging",Space,Str "to",Space,Str "the",Space,Emph [Str "Nordics."]]]) [(AlignCenter,ColWidth 0.3) ,(AlignLeft,ColWidth 0.3) ,(AlignLeft,ColWidth 0.2) ,(AlignLeft,ColWidth 0.2)] (TableHead ("",["simple-head"],[])- [Row ("",[],[])- [Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1) [Plain [Str "Name"]]- ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1) [Plain [Str "Capital"]]- ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1) [Plain [Str "Population", LineBreak, Str "(in", Space, Str "2018)"]]- ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1) [Plain [Str "Area", LineBreak, Str "(in", Space, Str "km", Superscript [Str "2"], Str ")"]]]])+ [Row ("",[],[])+ [Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1)+ [Plain [Str "Name"]]+ ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1)+ [Plain [Str "Capital"]]+ ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1)+ [Plain [Str "Population",LineBreak,Str "(in",Space,Str "2018)"]]+ ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1)+ [Plain [Str "Area",LineBreak,Str "(in",Space,Str "km",Superscript [Str "2"],Str ")"]]]]) [(TableBody ("",["souvereign-states"],[]) (RowHeadColumns 1) [] [Row ("",["country"],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Denmark"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Copenhagen"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5,809,502"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "43,094"]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Denmark"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Copenhagen"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5,809,502"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "43,094"]]] ,Row ("",["country"],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Finland"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Helsinki"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5,537,364"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "338,145"]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Finland"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Helsinki"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5,537,364"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "338,145"]]] ,Row ("",["country"],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Iceland"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Reykjavik"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "343,518"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "103,000"]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Iceland"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Reykjavik"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "343,518"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "103,000"]]] ,Row ("",["country"],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Norway"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Oslo"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5,372,191"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "323,802"]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Norway"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Oslo"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5,372,191"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "323,802"]]] ,Row ("",["country"],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Sweden"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Stockholm"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "10,313,447"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "450,295"]]]])]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Sweden"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Stockholm"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "10,313,447"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "450,295"]]]])] (TableFoot ("",[],[])- [Row ("summary",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Total"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) []- ,Cell ("total-population",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "27,376,022"]]- ,Cell ("total-area",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1,258,336"]]]])-]+ [Row ("summary",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Total"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ []+ ,Cell ("total-population",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "27,376,022"]]+ ,Cell ("total-area",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "1,258,336"]]]])]
@@ -1,5 +1,5 @@ [Table ("",[],[]) (Caption Nothing- [Para [Str "Data about the planets of our solar system."]])+ [Para [Str "Data",Space,Str "about",Space,Str "the",Space,Str "planets",Space,Str "of",Space,Str "our",Space,Str "solar",Space,Str "system."]]) [(AlignCenter,ColWidthDefault) ,(AlignCenter,ColWidthDefault) ,(AlignDefault,ColWidthDefault)@@ -13,126 +13,229 @@ ,(AlignRight,ColWidthDefault) ,(AlignDefault,ColWidthDefault)] (TableHead ("",[],[])- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2) [Plain [Str ""]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Name"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Mass (10^24kg)"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Diameter (km)"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Density (kg/m^3)"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Gravity (m/s^2)"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Length of day (hours)"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Distance from Sun (10^6km)"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Mean temperature (C)"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Number of moons"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Notes"]]]]- )+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2)+ []+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Name"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Mass",Space,Str "(10^24kg)"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Diameter",Space,Str "(km)"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Density",Space,Str "(kg/m^3)"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Gravity",Space,Str "(m/s^2)"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Length",Space,Str "of",Space,Str "day",Space,Str "(hours)"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Distance",Space,Str "from",Space,Str "Sun",Space,Str "(10^6km)"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Mean",Space,Str "temperature",Space,Str "(C)"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Number",Space,Str "of",Space,Str "moons"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Notes"]]]]) [(TableBody ("",[],[]) (RowHeadColumns 3) [] [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 4) (ColSpan 2) [Plain [Str "Terrestrial planets"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Mercury"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0.330"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4,879"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5427"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "3.7"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4222.6"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "57.9"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "167"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Closest to the Sun"]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 4) (ColSpan 2)+ [Plain [Str "Terrestrial",Space,Str "planets"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Mercury"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "0.330"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4,879"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5427"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "3.7"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4222.6"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "57.9"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "167"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "0"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Closest",Space,Str "to",Space,Str "the",Space,Str "Sun"]]] ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Venus"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4.87"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "12,104"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5243"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "8.9"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2802.0"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "108.2"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "464"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str ""]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Venus"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4.87"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "12,104"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5243"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "8.9"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "2802.0"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "108.2"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "464"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "0"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ []] ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Earth"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5.97"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "12,756"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5514"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "9.8"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "24.0"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "149.6"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "15"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Our world"]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Earth"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5.97"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "12,756"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5514"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "9.8"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "24.0"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "149.6"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "15"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "1"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Our",Space,Str "world"]]] ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Mars"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0.642"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "6,792"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "3933"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "3.7"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "24.7"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "227.9"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-65"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "The red planet"]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Mars"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "0.642"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "6,792"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "3933"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "3.7"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "24.7"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "227.9"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "-65"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "2"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "The",Space,Str "red",Space,Str "planet"]]] ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 4) (ColSpan 1) [Plain [Str "Jovian planets"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1) [Plain [Str "Gas giants"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Jupiter"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1898"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "142,984"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1326"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "23.1"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "9.9"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "778.6"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-110"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "67"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "The largest planet"]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 4) (ColSpan 1)+ [Plain [Str "Jovian",Space,Str "planets"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1)+ [Plain [Str "Gas",Space,Str "giants"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Jupiter"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "1898"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "142,984"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "1326"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "23.1"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "9.9"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "778.6"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "-110"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "67"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "The",Space,Str "largest",Space,Str "planet"]]] ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Saturn"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "568"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "120,536"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "687"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "9.0"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "10.7"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1433.5"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-140"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "62"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str ""]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Saturn"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "568"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "120,536"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "687"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "9.0"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "10.7"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "1433.5"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "-140"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "62"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ []] ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1) [Plain [Str "Ice giants"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Uranus"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "86.8"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "51,118"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1271"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "8.7"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "17.2"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2872.5"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-195"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "27"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str ""]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1)+ [Plain [Str "Ice",Space,Str "giants"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Uranus"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "86.8"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "51,118"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "1271"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "8.7"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "17.2"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "2872.5"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "-195"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "27"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ []] ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Neptune"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "102"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "49,528"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1638"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "11.0"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "16.1"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4495.1"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-200"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "14"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str ""]]]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Neptune"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "102"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "49,528"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "1638"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "11.0"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "16.1"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4495.1"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "-200"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "14"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ []] ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2) [Plain [Str "Dwarf planets"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Pluto"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0.0146"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2,370"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2095"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0.7"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "153.3"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5906.4"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-225"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Declassified as a planet in 2006."]]]])]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2)+ [Plain [Str "Dwarf",Space,Str "planets"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Pluto"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "0.0146"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "2,370"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "2095"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "0.7"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "153.3"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5906.4"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "-225"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Declassified",Space,Str "as",Space,Str "a",Space,Str "planet",Space,Str "in",Space,Str "2006."]]]])] (TableFoot ("",[],[])- []- )-]+ [])]
@@ -1,37 +1,54 @@ [Table ("students",[],[("source","mdn")]) (Caption Nothing- [Para [Str "List", Space, Str "of", Space, Str "Students"]])+ [Para [Str "List",Space,Str "of",Space,Str "Students"]]) [(AlignLeft,ColWidth 0.5) ,(AlignLeft,ColWidth 0.5)] (TableHead ("",[],[])+ [Row ("",[],[])+ [Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1)+ [Plain [Str "Student",Space,Str "ID"]]+ ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1)+ [Plain [Str "Name"]]]])+ [(TableBody ("",["souvereign-states"],[]) (RowHeadColumns 0) [Row ("",[],[])- [Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1) [Plain [Str "Student", Space, Str "ID"]]- ,Cell ("",[],[]) AlignCenter (RowSpan 1) (ColSpan 1) [Plain [Str "Name"]]]])- [TableBody ("",["souvereign-states"],[]) (RowHeadColumns 0)- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2) [Plain [Str "Computer", Space, Str "Science"]]]]- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "3741255"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Jones,", Space, Str "Martha"]]]- ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4077830"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Pierce,", Space, Str "Benjamin"]]]- ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5151701"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Kirk,", Space, Str "James"]]]]- ,TableBody ("",[],[]) (RowHeadColumns 0)- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2) [Plain [Str "Russian", Space, Str "Literature"]]]]- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "3971244"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Nim,", Space, Str "Victor"]]]]- ,TableBody ("",[],[]) (RowHeadColumns 0)- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2) [Plain [Str "Astrophysics"]]]]- [Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4100332"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Petrov,", Space, Str "Alexandra"]]]- ,Row ("",[],[])- [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4100332"]]- ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Toyota,", Space, Str "Hiroko"]]]]]- (TableFoot ("",[],[]) [])-]+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2)+ [Plain [Str "Computer",Space,Str "Science"]]]]+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "3741255"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Jones,",Space,Str "Martha"]]]+ ,Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4077830"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Pierce,",Space,Str "Benjamin"]]]+ ,Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "5151701"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Kirk,",Space,Str "James"]]]])+ ,(TableBody ("",[],[]) (RowHeadColumns 0)+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2)+ [Plain [Str "Russian",Space,Str "Literature"]]]]+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "3971244"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Nim,",Space,Str "Victor"]]]])+ ,(TableBody ("",[],[]) (RowHeadColumns 0)+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2)+ [Plain [Str "Astrophysics"]]]]+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4100332"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Petrov,",Space,Str "Alexandra"]]]+ ,Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "4100332"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Toyota,",Space,Str "Hiroko"]]]])]+ (TableFoot ("",[],[])+ [])]
@@ -2800,6 +2800,7 @@ <Profile type="string"> $ID/Embedded </Profile>+ <GraphicBounds Left="0" Top="0" Right="150" Bottom="150" /> </Properties> <Link Self="ueb" LinkResourceURI="file:lalune.jpg" /> </Image>@@ -2836,6 +2837,7 @@ <Profile type="string"> $ID/Embedded </Profile>+ <GraphicBounds Left="0" Top="0" Right="20" Bottom="22" /> </Properties> <Link Self="ueb" LinkResourceURI="file:movie.jpg" /> </Image>
@@ -4,14 +4,13 @@ % \documentclass[ ]{article}+\usepackage{amsmath,amssymb} \usepackage{lmodern}-\usepackage{amsmath} \usepackage{ifxetex,ifluatex} \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage{textcomp} % provide euro and other symbols- \usepackage{amssymb} \else % if luatex or xetex \usepackage{unicode-math} \defaultfontfeatures{Scale=MatchLowercase}
@@ -5,14 +5,13 @@ \documentclass[ english, ]{article}+\usepackage{amsmath,amssymb} \usepackage{lmodern}-\usepackage{amsmath} \usepackage{ifxetex,ifluatex} \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage{textcomp} % provide euro and other symbols- \usepackage{amssymb} \else % if luatex or xetex \usepackage{unicode-math} \defaultfontfeatures{Scale=MatchLowercase}@@ -56,7 +55,10 @@ \setotherlanguage[]{spanish} \setotherlanguage[]{french} \else- \usepackage[shorthands=off,ngerman,british,nswissgerman,spanish,french,main=english]{babel}+ \usepackage[ngerman,british,nswissgerman,spanish,french,main=english]{babel}+% get rid of language-specific shorthands (see #6817):+\let\LanguageShortHands\languageshorthands+\def\languageshorthands#1{} \newcommand{\textgerman}[2][]{\foreignlanguage{ngerman}{#2}} \newenvironment{german}[2][]{\begin{otherlanguage}{ngerman}}{\end{otherlanguage}} \newcommand{\textenglish}[2][]{\foreignlanguage{british}{#2}}