packages feed

pandoc 2.0.3 → 2.0.4

raw patch · 55 files changed

+1094/−388 lines, 55 filesdep ~binarydep ~http-typesdep ~skylightingPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: binary, http-types, skylighting, tagsoup, tasty-hunit

API changes (from Hackage documentation)

+ Text.Pandoc.App: [optStripEmptyParagraphs] :: Opt -> Bool
+ Text.Pandoc.Shared: stripEmptyParagraphs :: Pandoc -> Pandoc
+ Text.Pandoc.Writers.HTML: tagWithAttributes :: WriterOptions -> Bool -> Bool -> Text -> Attr -> Text
- Text.Pandoc.App: Opt :: Int -> Bool -> Bool -> Maybe String -> Maybe String -> Bool -> Int -> Maybe FilePath -> [(String, String)] -> [(String, String)] -> Maybe FilePath -> [FilePath] -> Bool -> [Int] -> Bool -> Bool -> Bool -> Bool -> Maybe String -> [FilePath] -> TopLevelDivision -> HTMLMathMethod -> Maybe FilePath -> Maybe FilePath -> String -> Maybe FilePath -> [FilePath] -> Int -> Maybe FilePath -> Int -> Bool -> Bool -> Verbosity -> Bool -> Maybe FilePath -> Bool -> Bool -> ReferenceLocation -> Int -> WrapOption -> Int -> [FilePath] -> [FilePath] -> ObfuscationMethod -> String -> [String] -> Maybe FilePath -> CiteMethod -> Bool -> Maybe String -> [String] -> Maybe Int -> Bool -> Bool -> String -> Maybe FilePath -> TrackChanges -> Bool -> Maybe String -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [(String, String)] -> LineEnding -> Bool -> Opt
+ Text.Pandoc.App: Opt :: Int -> Bool -> Bool -> Maybe String -> Maybe String -> Bool -> Int -> Maybe FilePath -> [(String, String)] -> [(String, String)] -> Maybe FilePath -> [FilePath] -> Bool -> [Int] -> Bool -> Bool -> Bool -> Bool -> Maybe String -> [FilePath] -> TopLevelDivision -> HTMLMathMethod -> Maybe FilePath -> Maybe FilePath -> String -> Maybe FilePath -> [FilePath] -> Int -> Maybe FilePath -> Int -> Bool -> Bool -> Verbosity -> Bool -> Maybe FilePath -> Bool -> Bool -> ReferenceLocation -> Int -> WrapOption -> Int -> [FilePath] -> [FilePath] -> ObfuscationMethod -> String -> Bool -> [String] -> Maybe FilePath -> CiteMethod -> Bool -> Maybe String -> [String] -> Maybe Int -> Bool -> Bool -> String -> Maybe FilePath -> TrackChanges -> Bool -> Maybe String -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [(String, String)] -> LineEnding -> Bool -> Opt

Files

INSTALL.md view
@@ -3,22 +3,18 @@ ## Windows    - There is a package installer at pandoc's [download page].+    This will install pandoc, replacing older versions, and+    update your path to include the directory where pandoc's+    binaries are installed. +  - If you prefer not to use the msi installer, we also provide+    a zip file that contains pandoc's binaries and+    documentation.  Simply unzip this file and move the binaries+    to a directory of your choice.+   - For PDF output, you'll also need to install LaTeX.     We recommend [MiKTeX](http://miktex.org/). -  - If you'd prefer, you can extract the `pandoc` and `pandoc-citeproc`-    executables from the MSI and copy them directly to any directory,-    without running the installer.  Here is an example showing how to-    extract the executables from the pandoc-1.19.1 installer and copy-    them to `C:\Utils\Console\`:--        mkdir "%TEMP%\pandoc\"-        start /wait msiexec.exe /a pandoc-1.19.1-windows.msi /qn targetdir="%TEMP%\pandoc\"-        copy /y "%TEMP%\pandoc\pandoc.exe" C:\Utils\Console\-        copy /y "%TEMP%\pandoc\pandoc-citeproc.exe" C:\Utils\Console\-        rmdir /s /q "%TEMP%\pandoc\"- ## macOS    - You can install pandoc using@@ -29,15 +25,10 @@     by downloading [this script][uninstaller]     and running it with `perl uninstall-pandoc.pl`. -  - It is possible to extract the pandoc and pandoc-citeproc-    executables from the macOS pkg file, if you'd rather not run-    the installer.  To do this (for the version 1.19.1 package):--        mkdir pandoc-extract-        cd pandoc-extract-        xar -x -f ../pandoc-2.0-macOS.pkg-        cat pandoc.pkg/Payload | gunzip -dc | cpio -i-        # executables are now in ./usr/bin/, man pages in ./usr/share/man+  - We also provide a zip file containing the binaries and man+    pages, for those who prefer not to use the installer.  Simply+    unzip the file and move the binaries and man pages to+    whatever directory you like.    - For PDF output, you'll also need LaTeX.  Because a full [MacTeX]     installation takes more than a gigabyte of disk space, we recommend
MANUAL.txt view
@@ -1,6 +1,6 @@ % Pandoc User's Guide % John MacFarlane-% November 20, 2017+% December 2, 2017  Synopsis ========@@ -427,6 +427,12 @@  :   Specify the base level for headers (defaults to 1). +`--strip-empty-paragraphs`++:   Ignore paragraphs with non content.  This option is useful+    for converting word processing documents where users have+    used empty paragraphs to create inter-paragraph space.+ `--indented-code-classes=`*CLASSES*  :   Specify classes to use for indented code blocks--for example,@@ -685,8 +691,16 @@     Instead of a *STYLE* name, a JSON file with extension     `.theme` may be supplied.  This will be parsed as a KDE     syntax highlighting theme and (if valid) used as the-    highlighting style.  To see a sample theme that can be-    modified, `pandoc --print-default-data-file default.theme`.+    highlighting style.++    To generate the JSON version of an existing style,+    use `--print-highlight-style`.++`--print-highlight-style=`*STYLE*|*FILE*++:   Prints a JSON version of a highlighting style, which can+    be modified, saved with a `.theme` extension, and used+    with `--highlight-style`.  `--syntax-definition=`*FILE* 
changelog view
@@ -1,3 +1,163 @@+pandoc (2.0.4)++  * Add `--print-highlight-style` option.  This generates a JSON version+    of a highlighting style, which can be saved as a `.theme` file, modified,+    and used with `--highlight-style` (#4106, #4096).++  * Add `--strip-empty-paragraphs` option.  This works for any input format.+    It is primarily intended for use with docx and odt documents where+    empty paragraphs have been used for inter-paragraph spaces.++  * Support `--webtex` for `gfm` output.++  * Recognize `.muse` file extension.++  * Support beamer `\alert` in LaTeX reader. Closes #4091.++  * Docx reader: don't strip out empty paragraphs (#2252).+    Users who have a conversion pipeline from docx may want to consider adding+    `--strip-empty-paragraphs` to the command line.++  * Org reader (Albert Krewinkel): Allow empty list items (#4090).++  * Muse reader (Alexander Krotov):++    + Parse markup in definition list terms.+    + Allow definition to end with EOF.+    + Make code blocks round trip.+    + Drop common space prefix from list items.+    + Add partial round trip test.+    + Don't interpret XML entities.+    + Remove `nested`.+    + Parse `~~` as non-breaking space in Emacs mode.+    + Correctly remove indentation from notes.  Exactly one space is+      required and considered to be part of the marker.+    + Allow list items to be empty.+    + Add ordered list test.+    + Add more multiline definition tests.+    + Don't allow blockquotes within lists.+    + Fix reading of multiline definitions.+    + Add inline `<literal>` support.+    + Concatenate inlines of the same type++  * Docx writer: allow empty paragraphs (#2252).++  * CommonMark/gfm writer:++    + Use raw html for native divs/spans (#4113).  This allows a pandoc+      markdown native div or span to be rendered in gfm using raw html tags.+    + Implement `raw_html` and `raw_tex` extensions.  Note that `raw_html`+      is enabled by default for `gfm`, while `raw_tex` is disabled by default.++  * Muse writer (Alexander Krotov):++    + Test that inline math conversion result is normalized.+      Without normalization this test produced+      `<em>a</em><em>b</em><em>c</em>`.+    + Improve inline list normalization and move to writer.+    + Escape hash symbol.+    + Escape `----` to avoid accidental horizontal rules.+    + Escape only `</code>` inside code tag.+    + Additional `<verbatim>` is not needed as `<code>` is verbatim already.++  * LaTeX writer:++    + Allow specifying just width or height for image size.+      Previously both needed to be specified (unless the image was+      being resized to be smaller than its original size).+      If height but not width is specified, we now set width to+      textwidth. If width but not height is specified, we now set+      height to textheight.  Since we have `keepaspectratio`, this+      yields the desired result.+    + Escape `~` and `_` in code with `--listings` (#4111).++  * HTML writer: export `tagWithAttributes`.  This is a helper allowing+    other writers to create single HTML tags.++  * Let papersizes `a0`, `a1`, `a2`, ... be case-insensitive by+    converting the case as needed in LaTeX and ConTeXt writers.++  * Change `fixDisplayMath` from `Text.Pandoc.Writers.Shared`+    so that it no longer produces empty `Para`'s as an artifact.++  * `Text.Pandoc.Shared.blocksToInlines`:  rewrote using builder.+    This gives us automatic normalization, so we don't get+    for example two consecutive Spaces.++  * Include default CSS for 'underline' class in HTML-based templates.++  * revealjs template:  add `tex2jax` configuration for the+    math plugin.  With the next release of reveal.js, this will+    fix the problem of `$`s outside of math contexts being+    interpreted as math delimiters (#4027).++  * `pandoc.lua` module for use in lua filters (Albert Krewinkel):++    + Add basic lua List module (#4099, #4081).  The List module is+      automatically loaded, but not assigned to a global variable. It can be+      included in filters by calling `List = require 'List'`.  Lists of blocks,+      lists of inlines, and lists of classes are now given `List` as a metatable,+      making working with them more convenient.  E.g., it is now possible to+      concatenate lists of inlines using Lua's concatenation operator `..`+      (requires at least one of the operants to have `List` as a metatable):++          function Emph (emph)+            local s = {pandoc.Space(), pandoc.Str 'emphasized'}+            return pandoc.Span(emph.content .. s)+          end++      The `List` metatable is assigned to the tables which get passed to+      the constructors `MetaBlocks`, `MetaInline`, and `MetaList`. This+      enables the use of the resulting objects as lists.+    + `Lua/StackInstances`: push Pandoc and Meta via constructor.+      Pandoc and Meta elements are now pushed by calling the respective+      constructor functions of the pandoc Lua module. This makes serialization+      consistent with the way blocks and inlines are pushed to lua and allows+      to use List methods with the `blocks` value.+    + Add documentation for pandoc.List in `lua-filters.md`.++  * Use latest tagsoup.  This fixes a bug in parsing HTML tags with+    `&` (but not a valid entity) following them (#4094, #4088).++  * Use skylighting 0.4.4.1, fixing the color of unmarked code text+    when `numberLines` is used (#4103).++  * Make `normalizeDate` more forgiving (Mauro Bieg, #4101), not+    requiring a leading 0 on single-digit days.++  * Fix `--help` output for `--highlight-style` to include `FILE` (Mauro+    Bieg, #4095).++  * Clearer deprecation warning for `--latexmathml, --asciimathml, -m`.+    Previously we only mentioned `--latexmathml`, even if `-m` was+    used.++  * Changelog: fix description of lua filters in 2.0 release+    (Albert Krewinkel).  Lua filters were initially run *after* conventional+    (JSON) filters.  However, this was changed later to make it easier to deal+    with files in the mediabag. The changelog is updated to describe that+    feature of the 2.0 release correctly.++  * Change Generic JSON instances to TemplateHaskell (Jasper Van der Jeugt,+    #4085).  This reduces compile time and memory usage significantly.++  * `lua-filters.md`: Added tikz filter example.++  * Create alternative zip file for macOS binaries.++  * Create alternative zip file for Windows binaries.++  * Update INSTALL.md since we now provide zips for binaries.++  * Relax `http-types` dependency (Justus Sagemüller, #4084).++  * Add `epub.md`, `getting-started.md` to docs.  These used to live in+    the website repo.++  * Add `packages` target to Makefile.++  * Bump bounds for binary, http-types, tasty-hunit+ pandoc (2.0.3)    * Lua filters: preload text module (Albert Krewinkel, #4077).@@ -378,7 +538,7 @@   * Added lua filters (Albert Krewinkel, #3514).  The new `--lua-filter`     option works like `--filter` but takes pathnames of special lua filters     and uses the lua interpreter baked into pandoc, so that no external-    interpreter is needed.  Note that lua filters are all applied after+    interpreter is needed.  Note that lua filters are all applied before     regular filters, regardless of their position on the command line.     For documentation of lua filters, see `doc/lua-filters.md`. 
+ data/List.lua view
@@ -0,0 +1,120 @@+--[[+List.lua++Copyright © 2017 Albert Krewinkel++Permission to use, copy, modify, and/or distribute this software for any purpose+with or without fee is hereby granted, provided that the above copyright notice+and this permission notice appear in all copies.++THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF+THIS SOFTWARE.+]]++--- Pandoc's List type and helper methods+-- @classmod pandoc.List+-- @author Albert Krewinkel+-- @copyright © 2017 Albert Krewinkel+-- @license MIT+local List = {+  _VERSION = "0.1.0"+}++function List:new (o)+  o = o or {}+  setmetatable(o, self)+  self.__index = self+  return o+end++function List:__call (o)+  return self:new(o)+end++--- Concatenates two lists.+-- @param list second list concatenated to the first+-- @return a new list containing all elements from list1 and list2+function List:__concat (list)+  local res = List.clone(self)+  List.extend(res, list)+  return res+end++--- Returns a (shallow) copy of the list.+function List:clone ()+  local lst = setmetatable({}, getmetatable(self))+  List.extend(lst, self)+  return lst+end++--- Checks if the list has an item equal to the given needle.+-- @param needle item to search for+-- @param init index at which the search is started+-- @return true if a list item is equal to the needle, false otherwise+function List:includes (needle, init)+  return not (List.find(self, needle, init) == nil)+end++--- Returns the value and index of the first occurrence of the given item.+-- @param needle item to search for+-- @param init index at which the search is started+-- @return first item equal to the needle, or nil if no such item exists.+-- @return index of that element+function List:find (needle, init)+  return List.find_if(self, function(x) return x == needle end, init)+end++--- Returns the value and index of the first element for which the predicate+--- holds true.+-- @param pred the predicate function+-- @param init index at which the search is started+-- @return first item for which `test` succeeds, or nil if no such item exists.+-- @return index of that element+function List:find_if (pred, init)+  init = (init == nil and 1) or (init < 0 and #self - init) or init+  for i = init, #self do+    if pred(self[i], i) then+      return self[i], i+    end+  end+  return nil+end++--- Adds the given list to the end of this list.+-- @param list list to appended+function List:extend (list)+  for i = 1, #list do+    self[#self + 1] = list[i]+  end+end++--- Returns a copy of the current list by applying the given function to all+-- elements.+-- @param fn function which is applied to all list items.+function List:map (fn)+  local res = setmetatable({}, getmetatable(self))+  for i = 1, #self do+    res[i] = fn(self[i], i)+  end+  return res+end++--- Returns a new list containing all items satisfying a given condition.+-- @param pred condition items must satisfy.+-- @return a new list containing all items for which `test` was true.+function List:filter (pred)+  local res = setmetatable({}, getmetatable(self))+  for i = 1, #self do+    if pred(self[i], i) then+      res[#res + 1] = self[i]+    end+  end+  return res+end++return List
data/pandoc.lua view
@@ -26,6 +26,8 @@   _VERSION = "0.3.0" } +local List = require 'pandoc.List'+ ------------------------------------------------------------------------ -- The base class for pandoc's AST elements. -- @type Element@@ -141,7 +143,7 @@ function M.Pandoc(blocks, meta)   meta = meta or {}   return {-    ["blocks"] = blocks,+    ["blocks"] = List:new(blocks),     ["meta"] = meta,     ["pandoc-api-version"] = {1,17,0,5},   }@@ -151,6 +153,21 @@ M.Doc = M.Pandoc  ------------------------------------------------------------------------+-- Meta+-- @section Meta++--- Create a new Meta object. It sets the metatable of the given table to+--- `Meta`.+-- @function Meta+-- @tparam meta table table containing document meta information+M.Meta = {}+M.Meta.__call = function(t, meta)+  return setmetatable(meta, self)+end+setmetatable(M.Meta, M.Meta)+++------------------------------------------------------------------------ -- MetaValue -- @section MetaValue M.MetaValue = Element:make_subtype{}@@ -168,25 +185,25 @@ --- Meta list -- @function MetaList -- @tparam {MetaValue,...} meta_values list of meta values----- Meta map--- @function MetaMap--- @tparam table key_value_map a string-indexed map of meta values-M.meta_value_types = {+M.meta_value_list_types = {   "MetaBlocks",   "MetaInlines",   "MetaList",-  "MetaMap", }-for i = 1, #M.meta_value_types do-  M[M.meta_value_types[i]] = M.MetaValue:create_constructor(-    M.meta_value_types[i],+for i = 1, #M.meta_value_list_types do+  M[M.meta_value_list_types[i]] = M.MetaValue:create_constructor(+    M.meta_value_list_types[i],     function(content)-      return content+      return List:new(content)     end   ) end +--- Meta map+-- @function MetaMap+-- @tparam table key_value_map a string-indexed map of meta values+M.MetaValue:create_constructor("MetaMap", function (mm) return mm end)+ --- Creates string to be used in meta data. -- Does nothing, lua strings are meta strings. -- @function MetaString@@ -250,7 +267,7 @@ -- @treturn     Block block quote element M.DefinitionList = M.Block:create_constructor(   "DefinitionList",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -262,7 +279,7 @@ M.Div = M.Block:create_constructor(   "Div",   function(content, attr)-    return {c = {attr or M.Attr(), content}}+    return {c = {attr or M.Attr(), List:new(content)}}   end,   {{"identifier", "classes", "attributes"}, "content"} )@@ -295,7 +312,7 @@ -- @treturn     Block                   block quote element M.LineBlock = M.Block:create_constructor(   "LineBlock",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -316,7 +333,7 @@   "OrderedList",   function(items, listAttributes)     listAttributes = listAttributes or {1, M.DefaultStyle, M.DefaultDelim}-    return {c = {listAttributes, items}}+    return {c = {listAttributes, List:new(items)}}   end,   {{"start", "style", "delimiter"}, "content"} )@@ -327,7 +344,7 @@ -- @treturn     Block                   block quote element M.Para = M.Block:create_constructor(   "Para",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -337,7 +354,7 @@ -- @treturn     Block                   block quote element M.Plain = M.Block:create_constructor(   "Plain",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -363,7 +380,15 @@ M.Table = M.Block:create_constructor(   "Table",   function(caption, aligns, widths, headers, rows)-    return {c = {caption, aligns, widths, headers, rows}}+    return {+      c = {+        List:new(caption),+        List:new(aligns),+        List:new(widths),+        List:new(headers),+        List:new(rows)+      }+    }   end,   {"caption", "aligns", "widths", "headers", "rows"} )@@ -386,7 +411,9 @@ -- @treturn Inline citations element M.Cite = M.Inline:create_constructor(   "Cite",-  function(content, citations) return {c = {citations, content}} end,+  function(content, citations)+    return {c = {List:new(citations), List:new(content)}}+  end,   {"citations", "content"} ) @@ -407,7 +434,7 @@ -- @treturn Inline emphasis element M.Emph = M.Inline:create_constructor(   "Emph",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -423,7 +450,7 @@   function(caption, src, title, attr)     title = title or ""     attr = attr or M.Attr()-    return {c = {attr, caption, {src, title}}}+    return {c = {attr, List:new(caption), {src, title}}}   end,   {{"identifier", "classes", "attributes"}, "caption", {"src", "title"}} )@@ -448,7 +475,7 @@   function(content, target, title, attr)     title = title or ""     attr = attr or M.Attr()-    return {c = {attr, content, {target, title}}}+    return {c = {attr, List:new(content), {target, title}}}   end,   {{"identifier", "classes", "attributes"}, "content", {"target", "title"}} )@@ -489,7 +516,7 @@ -- @tparam      {Block,...} content     footnote block content M.Note = M.Inline:create_constructor(   "Note",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -500,7 +527,7 @@ -- @treturn     Inline                  quoted element M.Quoted = M.Inline:create_constructor(   "Quoted",-  function(quotetype, content) return {c = {quotetype, content}} end,+  function(quotetype, content) return {c = {quotetype, List:new(content)}} end,   {"quotetype", "content"} ) --- Creates a single-quoted inline element (DEPRECATED).@@ -541,7 +568,7 @@ -- @treturn     Inline                  smallcaps element M.SmallCaps = M.Inline:create_constructor(   "SmallCaps",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -568,7 +595,9 @@ -- @treturn Inline span element M.Span = M.Inline:create_constructor(   "Span",-  function(content, attr) return {c = {attr or M.Attr(), content}} end,+  function(content, attr)+    return {c = {attr or M.Attr(), List:new(content)}}+  end,   {{"identifier", "classes", "attributes"}, "content"} ) @@ -588,7 +617,7 @@ -- @treturn     Inline                  strikeout element M.Strikeout = M.Inline:create_constructor(   "Strikeout",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -598,7 +627,7 @@ -- @treturn     Inline                  strong element M.Strong = M.Inline:create_constructor(   "Strong",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -608,7 +637,7 @@ -- @treturn     Inline                  subscript element M.Subscript = M.Inline:create_constructor(   "Subscript",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -618,7 +647,7 @@ -- @treturn     Inline                  strong element M.Superscript = M.Inline:create_constructor(   "Superscript",-  function(content) return {c = content} end,+  function(content) return {c = List:new(content)} end,   "content" ) @@ -627,24 +656,8 @@ -- Helpers -- @section helpers --- Find a value pair in a list.--- @function find--- @tparam table list to be searched--- @param needle element to search for--- @param[opt] key when non-nil, compare on this field of each list element-local function find (alist, needle, key)-  local test-  if key then-    test = function(x) return x[key] == needle end-  else-    test = function(x) return x == needle end-  end-  for i, k in ipairs(alist) do-    if test(k) then-      return i, k-    end-  end-  return nil+local function assoc_key_equals (x)+  return function (y) return y[1] == x end end  -- Lookup a value in an associative list@@ -652,7 +665,7 @@ -- @tparam {{key, value},...} alist associative list -- @param key key for which the associated value is to be looked up local function lookup(alist, key)-  return (select(2, find(alist, key, 1)) or {})[2]+  return (List.find_if(alist, assoc_key_equals(key)) or {})[2] end  --- Return an iterator which returns key-value pairs of an associative list.@@ -684,7 +697,7 @@   end,    __newindex = function (t, k, v)-    local idx, cur = find(t, k, 1)+    local cur, idx = List.find_if(t, assoc_key_equals(k))     if v == nil then       table.remove(t, idx)     elseif cur then@@ -729,7 +742,7 @@ -- @return element attributes M.Attr.__call = function(t, identifier, classes, attributes)   identifier = identifier or ''-  classes = classes or {}+  classes = List:new(classes or {})   attributes = setmetatable(to_alist(attributes or {}), AttributeList)   local attr = {identifier, classes, attributes}   setmetatable(attr, t)
data/templates/default.dzslides view
@@ -15,6 +15,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;} $if(quotes)$
data/templates/default.epub2 view
@@ -9,6 +9,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;} $if(quotes)$
data/templates/default.epub3 view
@@ -8,6 +8,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;} $if(quotes)$
data/templates/default.html4 view
@@ -17,6 +17,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;} $if(quotes)$
data/templates/default.html5 view
@@ -17,6 +17,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;} $if(quotes)$
data/templates/default.revealjs view
@@ -20,6 +20,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;} $if(quotes)$@@ -234,6 +235,18 @@         math: {           mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js',           config: 'TeX-AMS_HTML-full',+          tex2jax: {+            inlineMath: [['\\(','\\)']],+            displayMath: [['\\[','\\]']],+            balanceBraces: true,+            processEscapes: false,+            processRefs: true,+            processEnvironments: true,+            preview: 'TeX',+            skipTags: ['script','noscript','style','textarea','pre','code'],+            ignoreClass: 'tex2jax_ignore',+            processClass: 'tex2jax_process'+          },         }, $endif$ 
data/templates/default.s5 view
@@ -18,6 +18,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;} $if(quotes)$
data/templates/default.slideous view
@@ -19,6 +19,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;} $if(quotes)$
data/templates/default.slidy view
@@ -19,6 +19,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;} $if(quotes)$
man/pandoc.1 view
@@ -1,5 +1,5 @@ .\"t-.TH PANDOC 1 "November 20, 2017" "pandoc 2.0.3"+.TH PANDOC 1 "December 2, 2017" "pandoc 2.0.4" .SH NAME pandoc - general markup converter .SH SYNOPSIS@@ -431,6 +431,13 @@ .RS .RE .TP+.B \f[C]\-\-strip\-empty\-paragraphs\f[]+Ignore paragraphs with non content.+This option is useful for converting word processing documents where+users have used empty paragraphs to create inter\-paragraph space.+.RS+.RE+.TP .B \f[C]\-\-indented\-code\-classes=\f[]\f[I]CLASSES\f[] Specify classes to use for indented code blocks\-\-for example, \f[C]perl,numberLines\f[] or \f[C]haskell\f[].@@ -738,8 +745,16 @@ \f[C]\&.theme\f[] may be supplied. This will be parsed as a KDE syntax highlighting theme and (if valid) used as the highlighting style.-To see a sample theme that can be modified,-\f[C]pandoc\ \-\-print\-default\-data\-file\ default.theme\f[].+.PP+To generate the JSON version of an existing style, use+\f[C]\-\-print\-highlight\-style\f[].+.RE+.TP+.B \f[C]\-\-print\-highlight\-style=\f[]\f[I]STYLE\f[]|\f[I]FILE\f[]+Prints a JSON version of a highlighting style, which can be modified,+saved with a \f[C]\&.theme\f[] extension, and used with+\f[C]\-\-highlight\-style\f[].+.RS .RE .TP .B \f[C]\-\-syntax\-definition=\f[]\f[I]FILE\f[]
pandoc.cabal view
@@ -1,5 +1,5 @@ name:            pandoc-version:         2.0.3+version:         2.0.4 cabal-version:   >= 1.10 build-type:      Custom license:         GPL@@ -11,7 +11,7 @@ stability:       alpha homepage:        http://pandoc.org category:        Text-tested-with:     GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.1+tested-with:     GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2 synopsis:        Conversion between markup formats description:     Pandoc is a Haskell library for converting from one markup                  format to another, and a command-line tool that uses@@ -110,6 +110,8 @@                  data/sample.lua                  -- pandoc lua module                  data/pandoc.lua+                 -- lua List module+                 data/List.lua                  -- sample highlighting theme                  data/default.theme                  -- bash completion template@@ -315,10 +317,10 @@                  pandoc-types >= 1.17.3 && < 1.18,                  aeson >= 0.7 && < 1.3,                  aeson-pretty >= 0.8 && < 0.9,-                 tagsoup >= 0.13.7 && < 0.15,+                 tagsoup >= 0.14.2 && < 0.15,                  base64-bytestring >= 0.1 && < 1.1,                  zlib >= 0.5 && < 0.7,-                 skylighting >= 0.4.3.2 && <0.5,+                 skylighting >= 0.4.4.1 && < 0.5,                  data-default >= 0.4 && < 0.8,                  temporary >= 1.1 && < 1.3,                  blaze-html >= 0.5 && < 0.10,@@ -328,7 +330,7 @@                  vector >= 0.10 && < 0.13,                  hslua >= 0.9 && < 0.10,                  hslua-module-text >= 0.1.2 && < 0.2,-                 binary >= 0.5 && < 0.9,+                 binary >= 0.5 && < 0.10,                  SHA >= 1.6 && < 1.7,                  haddock-library >= 1.1 && < 1.5,                  deepseq >= 1.3 && < 1.5,@@ -338,7 +340,7 @@                  doctemplates >= 0.2.1 && < 0.3,                  http-client >= 0.4.30 && < 0.6,                  http-client-tls >= 0.2.4 && < 0.4,-                 http-types >= 0.8 && < 0.10,+                 http-types >= 0.8 && < 0.12,                  case-insensitive >= 1.2 && < 1.3   if os(windows)     cpp-options:      -D_WINDOWS@@ -560,7 +562,7 @@                   temporary >= 1.1 && < 1.3,                   Diff >= 0.2 && < 0.4,                   tasty >= 0.11 && < 0.13,-                  tasty-hunit >= 0.9 && < 0.10,+                  tasty-hunit >= 0.9 && < 0.11,                   tasty-quickcheck >= 0.8 && < 0.10,                   tasty-golden >= 2.3 && < 2.4,                   QuickCheck >= 2.4 && < 2.11,
src/Text/Pandoc/App.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE CPP                 #-} {-# LANGUAGE DeriveGeneric       #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell     #-} {-# LANGUAGE TupleSections       #-} {- Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>@@ -44,8 +45,8 @@ import Control.Monad import Control.Monad.Except (catchError, throwError) import Control.Monad.Trans-import Data.Aeson (FromJSON (..), ToJSON (..), defaultOptions, eitherDecode',-                   encode, genericToEncoding)+import Data.Aeson (defaultOptions, eitherDecode', encode)+import Data.Aeson.TH (deriveJSON) import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as B import Data.Char (toLower, toUpper)@@ -62,7 +63,10 @@ import GHC.Generics import Network.URI (URI (..), parseURI) import Paths_pandoc (getDataDir)-import Skylighting (Style, Syntax (..), defaultSyntaxMap, parseTheme)+import Data.Aeson.Encode.Pretty (encodePretty', Config(..), keyOrder,+         defConfig, Indent(..), NumberFormat(..))+import Skylighting (Style, Syntax (..), defaultSyntaxMap, parseTheme,+                    pygments) import Skylighting.Parser (addSyntaxDefinition, missingIncludes,                            parseSyntaxDefinition) import System.Console.GetOpt@@ -82,8 +86,8 @@ import Text.Pandoc.PDF (makePDF) import Text.Pandoc.Process (pipeProcess) import Text.Pandoc.SelfContained (makeDataURI, makeSelfContained)-import Text.Pandoc.Shared (eastAsianLineBreakFilter, headerShift, isURI, ordNub,-                           safeRead, tabFilter)+import Text.Pandoc.Shared (eastAsianLineBreakFilter, stripEmptyParagraphs,+         headerShift, isURI, ordNub, safeRead, tabFilter) import qualified Text.Pandoc.UTF8 as UTF8 import Text.Pandoc.Writers.Math (defaultKaTeXURL, defaultMathJaxURL) import Text.Pandoc.XML (toEntities)@@ -95,10 +99,6 @@  data LineEnding = LF | CRLF | Native deriving (Show, Generic) -instance ToJSON LineEnding where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON LineEnding- parseOptions :: [OptDescr (Opt -> IO Opt)] -> Opt -> IO Opt parseOptions options' defaults = do   rawArgs <- map UTF8.decodeArg <$> getArgs@@ -461,14 +461,17 @@      let transforms = (case optBaseHeaderLevel opts of                           x | x > 1     -> (headerShift (x - 1) :)-                            | otherwise -> id) $+                            | otherwise -> id) .+                     (if optStripEmptyParagraphs opts+                         then (stripEmptyParagraphs :)+                         else id) .                      (if extensionEnabled Ext_east_asian_line_breaks                             readerExts &&                          not (extensionEnabled Ext_east_asian_line_breaks                               writerExts &&                               writerWrapText writerOptions == WrapPreserve)                          then (eastAsianLineBreakFilter :)-                         else id)+                         else id) $                      []      let sourceToDoc :: [FilePath] -> PandocIO Pandoc@@ -622,6 +625,7 @@     , optLuaFilters            :: [FilePath] -- ^ Lua filters to apply     , optEmailObfuscation      :: ObfuscationMethod     , optIdentifierPrefix      :: String+    , optStripEmptyParagraphs  :: Bool -- ^ Strip empty paragraphs     , optIndentedCodeClasses   :: [String] -- ^ Default classes for indented code blocks     , optDataDir               :: Maybe FilePath     , optCiteMethod            :: CiteMethod -- ^ Method to output cites@@ -646,10 +650,6 @@     , optStripComments         :: Bool       -- ^ Skip HTML comments     } deriving (Generic, Show) -instance ToJSON Opt where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON Opt- -- | Defaults for command-line options. defaultOpts :: Opt defaultOpts = Opt@@ -698,6 +698,7 @@     , optLuaFilters            = []     , optEmailObfuscation      = NoObfuscation     , optIdentifierPrefix      = ""+    , optStripEmptyParagraphs  = False     , optIndentedCodeClasses   = []     , optDataDir               = Nothing     , optCiteMethod            = Citeproc@@ -753,6 +754,7 @@     ".htm"      -> "html"     ".md"       -> "markdown"     ".markdown" -> "markdown"+    ".muse"     -> "muse"     ".tex"      -> "latex"     ".latex"    -> "latex"     ".ltx"      -> "latex"@@ -793,6 +795,7 @@     ".txt"      -> "markdown"     ".text"     -> "markdown"     ".md"       -> "markdown"+    ".muse"     -> "muse"     ".markdown" -> "markdown"     ".textile"  -> "textile"     ".lhs"      -> "markdown+lhs"@@ -942,7 +945,12 @@                   "NUMBER")                  "" -- "Headers base level" -     , Option "" ["indented-code-classes"]+    , Option "" ["strip-empty-paragraphs"]+                 (NoArg+                  (\opt -> return opt{ optStripEmptyParagraphs = True }))+                 "" -- "Strip empty paragraphs"++    , Option "" ["indented-code-classes"]                   (ReqArg                    (\arg opt -> return opt { optIndentedCodeClasses = words $                                              map (\c -> if c == ',' then ' ' else c) arg })@@ -1052,6 +1060,28 @@                   "FILE")                   "" -- "Print default data file" +    , Option "" ["print-highlight-style"]+                 (ReqArg+                  (\arg _ -> do+                     sty <- fromMaybe pygments <$>+                              lookupHighlightStyle (Just arg)+                     B.putStr $ encodePretty'+                       defConfig{confIndent = Spaces 4+                                ,confCompare = keyOrder+                                  (map T.pack+                                   ["text-color"+                                   ,"background-color"+                                   ,"line-numbers"+                                   ,"bold"+                                   ,"italic"+                                   ,"underline"+                                   ,"text-styles"])+                                ,confNumFormat = Generic+                                ,confTrailingNewline = True} sty+                     exitSuccess)+                  "STYLE|FILE")+                 "" -- "Print default template for FORMAT"+     , Option "" ["dpi"]                  (ReqArg                   (\arg opt ->@@ -1124,7 +1154,7 @@     , Option "" ["highlight-style"]                 (ReqArg                  (\arg opt -> return opt{ optHighlightStyle = Just arg })-                 "STYLE")+                 "STYLE|FILE")                  "" -- "Style for highlighted code"      , Option "" ["syntax-definition"]@@ -1442,7 +1472,7 @@     , Option "m" ["latexmathml", "asciimathml"]                  (OptArg                   (\arg opt -> do-                      deprecatedOption "--latexmathml"+                      deprecatedOption "--latexmathml, --asciimathml, -m"                       return opt { optHTMLMathMethod = LaTeXMathML arg })                   "URL")                  "" -- "Use LaTeXMathML script in html output"@@ -1675,3 +1705,8 @@     \r -> case r of        Right () -> return ()        Left e   -> E.throwIO e++-- see https://github.com/jgm/pandoc/pull/4083+-- using generic deriving caused long compilation times+$(deriveJSON defaultOptions ''LineEnding)+$(deriveJSON defaultOptions ''Opt)
src/Text/Pandoc/Extensions.hs view
@@ -15,8 +15,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA -}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE DeriveGeneric              #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE TemplateHaskell            #-}  {- |    Module      : Text.Pandoc.Extensions@@ -45,8 +47,8 @@                               , githubMarkdownExtensions                               , multimarkdownExtensions ) where-import Data.Aeson (FromJSON (..), ToJSON (..), defaultOptions,-                   genericToEncoding)+import Data.Aeson (FromJSON (..), ToJSON (..), defaultOptions)+import Data.Aeson.TH (deriveJSON) import Data.Bits (clearBit, setBit, testBit, (.|.)) import Data.Data (Data) import Data.Typeable (Typeable)@@ -55,11 +57,7 @@ import Text.Parsec  newtype Extensions = Extensions Integer-  deriving (Show, Read, Eq, Ord, Data, Typeable, Generic)--instance ToJSON Extensions where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON Extensions+  deriving (Show, Read, Eq, Ord, Data, Typeable, Generic, ToJSON, FromJSON)  instance Monoid Extensions where   mempty = Extensions 0@@ -156,10 +154,6 @@     | Ext_amuse -- ^ Enable Text::Amuse extensions to Emacs Muse markup     deriving (Show, Read, Enum, Eq, Ord, Bounded, Data, Typeable, Generic) -instance ToJSON Extension where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON Extension- -- | Extensions to be used with pandoc-flavored markdown. pandocExtensions :: Extensions pandocExtensions = extensionsFromList@@ -373,3 +367,5 @@           return $ case polarity of                         '-' -> disableExtension ext                         _   -> enableExtension ext++$(deriveJSON defaultOptions ''Extension)
src/Text/Pandoc/Lua/PandocModule.hs view
@@ -59,10 +59,12 @@ import qualified Text.Pandoc.MediaBag as MB import Text.Pandoc.Lua.Filter (walkInlines, walkBlocks, LuaFilter) --- | Push the "pandoc" on the lua stack.+-- | Push the "pandoc" on the lua stack. Requires the `list` module to be+-- loaded. pushPandocModule :: Maybe FilePath -> Lua () pushPandocModule datadir = do-  script <- liftIO (pandocModuleScript datadir)+  loadListModule datadir+  script <- liftIO (moduleScript datadir "pandoc.lua")   status <- Lua.loadstring script   unless (status /= Lua.OK) $ Lua.call 0 1   addFunction "_pipe" pipeFn@@ -72,9 +74,25 @@   addFunction "walk_inline" walkInline  -- | Get the string representation of the pandoc module-pandocModuleScript :: Maybe FilePath -> IO String-pandocModuleScript datadir = unpack <$>-  runIOorExplode (setUserDataDir datadir >> readDataFile "pandoc.lua")+moduleScript :: Maybe FilePath -> FilePath -> IO String+moduleScript datadir moduleFile = unpack <$>+  runIOorExplode (setUserDataDir datadir >> readDataFile moduleFile)++-- Loads pandoc's list module without assigning it to a variable.+pushListModule :: Maybe FilePath -> Lua ()+pushListModule datadir = do+  script <- liftIO (moduleScript datadir "List.lua")+  status <- Lua.loadstring script+  if status == Lua.OK+    then Lua.call 0 1+    else Lua.throwTopMessageAsError' ("Error while loading module `list`\n" ++)++loadListModule :: Maybe FilePath -> Lua ()+loadListModule datadir = do+  Lua.getglobal' "package.loaded"+  pushListModule datadir+  Lua.setfield (-2) "pandoc.List"+  Lua.pop 1  walkElement :: (ToLuaStack a, Walkable [Inline] a, Walkable [Block] a)             => a -> LuaFilter -> Lua NumResults
src/Text/Pandoc/Lua/StackInstances.hs view
@@ -36,17 +36,14 @@ import Foreign.Lua (FromLuaStack (peek), Lua, LuaInteger, LuaNumber, StackIndex,                     ToLuaStack (push), Type (..), throwLuaError, tryLua) import Text.Pandoc.Definition-import Text.Pandoc.Lua.Util (addValue, adjustIndexBy, getTable,-                             pushViaConstructor)+import Text.Pandoc.Lua.Util (adjustIndexBy, getTable, pushViaConstructor) import Text.Pandoc.Shared (safeRead)  import qualified Foreign.Lua as Lua  instance ToLuaStack Pandoc where-  push (Pandoc meta blocks) = do-    Lua.newtable-    addValue "blocks" blocks-    addValue "meta"   meta+  push (Pandoc meta blocks) =+    pushViaConstructor "Pandoc" blocks meta  instance FromLuaStack Pandoc where   peek idx = do@@ -55,7 +52,8 @@     return $ Pandoc meta blocks  instance ToLuaStack Meta where-  push (Meta mmap) = push mmap+  push (Meta mmap) =+    pushViaConstructor "Meta" mmap instance FromLuaStack Meta where   peek idx = Meta <$> peek idx 
src/Text/Pandoc/Options.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE TemplateHaskell    #-} {- Copyright (C) 2012-2017 John MacFarlane <jgm@berkeley.edu> @@ -45,8 +46,8 @@                            , def                            , isEnabled                            ) where-import Data.Aeson (FromJSON (..), ToJSON (..), defaultOptions,-                   genericToEncoding)+import Data.Aeson (defaultOptions)+import Data.Aeson.TH (deriveJSON) import Data.Data (Data) import Data.Default import qualified Data.Set as Set@@ -75,10 +76,6 @@ instance HasSyntaxExtensions ReaderOptions where   getExtensions opts = readerExtensions opts -instance ToJSON ReaderOptions where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON ReaderOptions- instance Default ReaderOptions   where def = ReaderOptions{                  readerExtensions            = emptyExtensions@@ -116,29 +113,17 @@                     | KaTeX String                -- url of KaTeX files                     deriving (Show, Read, Eq, Data, Typeable, Generic) -instance ToJSON HTMLMathMethod where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON HTMLMathMethod- data CiteMethod = Citeproc                        -- use citeproc to render them                   | Natbib                        -- output natbib cite commands                   | Biblatex                      -- output biblatex cite commands                 deriving (Show, Read, Eq, Data, Typeable, Generic) -instance ToJSON CiteMethod where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON CiteMethod- -- | Methods for obfuscating email addresses in HTML. data ObfuscationMethod = NoObfuscation                        | ReferenceObfuscation                        | JavascriptObfuscation                        deriving (Show, Read, Eq, Data, Typeable, Generic) -instance ToJSON ObfuscationMethod where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON ObfuscationMethod- -- | Varieties of HTML slide shows. data HTMLSlideVariant = S5Slides                       | SlidySlides@@ -148,30 +133,18 @@                       | NoSlides                       deriving (Show, Read, Eq, Data, Typeable, Generic) -instance ToJSON HTMLSlideVariant where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON HTMLSlideVariant- -- | Options for accepting or rejecting MS Word track-changes. data TrackChanges = AcceptChanges                   | RejectChanges                   | AllChanges                   deriving (Show, Read, Eq, Data, Typeable, Generic) -instance ToJSON TrackChanges where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON TrackChanges- -- | Options for wrapping text in the output. data WrapOption = WrapAuto        -- ^ Automatically wrap to width                 | WrapNone        -- ^ No non-semantic newlines                 | WrapPreserve    -- ^ Preserve wrapping of input source                 deriving (Show, Read, Eq, Data, Typeable, Generic) -instance ToJSON WrapOption where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON WrapOption- -- | Options defining the type of top-level headers. data TopLevelDivision = TopLevelPart      -- ^ Top-level headers become parts                       | TopLevelChapter   -- ^ Top-level headers become chapters@@ -180,20 +153,12 @@                                           --   heuristics                       deriving (Show, Read, Eq, Data, Typeable, Generic) -instance ToJSON TopLevelDivision where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON TopLevelDivision- -- | Locations for footnotes and references in markdown output data ReferenceLocation = EndOfBlock    -- ^ End of block                        | EndOfSection  -- ^ prior to next section header (or end of document)                        | EndOfDocument -- ^ at end of document                        deriving (Show, Read, Eq, Data, Typeable, Generic) -instance ToJSON ReferenceLocation where-  toEncoding = genericToEncoding defaultOptions-instance FromJSON ReferenceLocation- -- | Options for writers data WriterOptions = WriterOptions   { writerTemplate          :: Maybe String -- ^ Template to use@@ -271,3 +236,13 @@ -- | Returns True if the given extension is enabled. isEnabled :: HasSyntaxExtensions a => Extension -> a -> Bool isEnabled ext opts = ext `extensionEnabled` getExtensions opts++$(deriveJSON defaultOptions ''ReaderOptions)+$(deriveJSON defaultOptions ''HTMLMathMethod)+$(deriveJSON defaultOptions ''CiteMethod)+$(deriveJSON defaultOptions ''ObfuscationMethod)+$(deriveJSON defaultOptions ''HTMLSlideVariant)+$(deriveJSON defaultOptions ''TrackChanges)+$(deriveJSON defaultOptions ''WrapOption)+$(deriveJSON defaultOptions ''TopLevelDivision)+$(deriveJSON defaultOptions ''ReferenceLocation)
src/Text/Pandoc/Readers/Docx.hs view
@@ -534,9 +534,7 @@       then do modify $ \s -> s { docxDropCap = ils' }               return mempty       else do modify $ \s -> s { docxDropCap = mempty }-              return $ case isNull ils' of-                True -> mempty-                _    -> parStyleToTransform pPr $ para ils'+              return $ parStyleToTransform pPr $ para ils' bodyPartToBlocks (ListItem pPr numId lvl (Just levelInfo) parparts) = do   let     kvs = case levelInfo of
src/Text/Pandoc/Readers/HTML.hs view
@@ -1147,7 +1147,7 @@   -- <www.boe.es/buscar/act.php?id=BOE-A-1996-8930#a66>   -- should NOT be parsed as an HTML tag, see #2277,   -- so we exclude . even though it's a valid character-  -- in XML elemnet names+  -- in XML element names   let isNameChar c = isAlphaNum c || c == ':' || c == '-' || c == '_'   let isName s = case s of                       []     -> False
src/Text/Pandoc/Readers/LaTeX.hs view
@@ -1245,6 +1245,7 @@   , ("textup", extractSpaces (spanWith ("",["upright"],[])) <$> tok)   , ("texttt", ttfamily)   , ("sout", extractSpaces strikeout <$> tok)+  , ("alert", skipangles >> spanWith ("",["alert"],[]) <$> tok) -- beamer   , ("lq", return (str "‘"))   , ("rq", return (str "’"))   , ("textquoteleft", return (str "‘"))
src/Text/Pandoc/Readers/Muse.hs view
@@ -55,10 +55,9 @@ import Text.Pandoc.Definition import Text.Pandoc.Logging import Text.Pandoc.Options-import Text.Pandoc.Parsing hiding (nested)+import Text.Pandoc.Parsing import Text.Pandoc.Readers.HTML (htmlTag) import Text.Pandoc.Shared (crFilter)-import Text.Pandoc.XML (fromEntities)  -- | Read Muse from an input string and return a Pandoc document. readMuse :: PandocMonad m@@ -102,15 +101,6 @@ eol :: Stream s m Char => ParserT s st m () eol = void newline <|> eof -nested :: PandocMonad m => MuseParser m a -> MuseParser m a-nested p = do-  nestlevel <- stateMaxNestingLevel <$>  getState-  guard $ nestlevel > 0-  updateState $ \st -> st{ stateMaxNestingLevel = stateMaxNestingLevel st - 1 }-  res <- p-  updateState $ \st -> st{ stateMaxNestingLevel = nestlevel }-  return res- htmlElement :: PandocMonad m => String -> MuseParser m (Attr, String) htmlElement tag = try $ do   (TagOpen _ attr, _) <- htmlTag (~== TagOpen tag [])@@ -133,12 +123,19 @@   parsedContent <- parseContent (content ++ "\n")   return (attr, parsedContent)   where-    parseContent = parseFromString $ nested $ manyTill parser endOfContent+    parseContent = parseFromString $ manyTill parser endOfContent     endOfContent = try $ skipMany blankline >> skipSpaces >> eof  parseHtmlContent :: PandocMonad m => String -> MuseParser m a -> MuseParser m [a] parseHtmlContent tag p = fmap snd (parseHtmlContentWithAttrs tag p) +commonPrefix :: String -> String -> String+commonPrefix _ [] = []+commonPrefix [] _ = []+commonPrefix (x:xs) (y:ys)+  | x == y    = x : commonPrefix xs ys+  | otherwise = []+ -- -- directive parsers --@@ -228,23 +225,28 @@   contents <- manyTill anyChar $ try (optionMaybe blankline >> string "}}}")   return $ return $ B.codeBlock contents -exampleTag :: PandocMonad m => MuseParser m (F Blocks)-exampleTag = do-  (attr, contents) <- htmlElement "example"-  return $ return $ B.codeBlockWith attr $ chop contents+-- Trim up to one newline from the beginning and the end,+-- in case opening and/or closing tags are on separate lines.+chop :: String -> String+chop = lchop . rchop   where lchop s = case s of                     '\n':ss -> ss                     _       -> s         rchop = reverse . lchop . reverse-        -- Trim up to one newline from the beginning and the end,-        -- in case opening and/or closing tags are on separate lines.-        chop = lchop . rchop +exampleTag :: PandocMonad m => MuseParser m (F Blocks)+exampleTag = do+  (attr, contents) <- htmlElement "example"+  return $ return $ B.codeBlockWith attr $ chop contents+ literal :: PandocMonad m => MuseParser m (F Blocks)-literal = (return . rawBlock) <$> htmlElement "literal"+literal = do+  guardDisabled Ext_amuse -- Text::Amuse does not support <literal>+  (return . rawBlock) <$> htmlElement "literal"   where-    format (_, _, kvs)        = fromMaybe "html" $ lookup "format" kvs-    rawBlock (attrs, content) = B.rawBlock (format attrs) content+    -- FIXME: Emacs Muse inserts <literal> without style into all output formats, but we assume HTML+    format (_, _, kvs)        = fromMaybe "html" $ lookup "style" kvs+    rawBlock (attrs, content) = B.rawBlock (format attrs) $ chop content  blockTag :: PandocMonad m           => (Blocks -> Blocks)@@ -296,7 +298,8 @@ para :: PandocMonad m => MuseParser m (F Blocks) para = do  indent <- length <$> many spaceChar- let f = if indent >= 2 && indent < 6 then B.blockQuote else id+ st <- stateParserContext <$> getState+ let f = if st /= ListItemState && indent >= 2 && indent < 6 then B.blockQuote else id  fmap (f . B.para) . trimInlinesF . mconcat <$> many1Till inline endOfParaElement  where    endOfParaElement = lookAhead $ endOfInput <|> endOfPara <|> newBlockElement@@ -315,8 +318,8 @@ amuseNoteBlock = try $ do   guardEnabled Ext_amuse   pos <- getPosition-  ref <- noteMarker <* skipSpaces-  content <- listItemContents $ 2 + length ref+  ref <- noteMarker <* spaceChar+  content <- listItemContents $ 3 + length ref   oldnotes <- stateNotes' <$> getState   case M.lookup ref oldnotes of     Just _  -> logMessage $ DuplicateNoteReference ref pos@@ -369,7 +372,7 @@ listLine :: PandocMonad m => Int -> MuseParser m String listLine markerLength = try $ do   indentWith markerLength-  anyLineNewline+  manyTill anyChar eol  withListContext :: PandocMonad m => MuseParser m a -> MuseParser m a withListContext p = do@@ -380,11 +383,11 @@   updateState (\st -> st {stateParserContext = oldContext})   return parsed -listContinuation :: PandocMonad m => Int -> MuseParser m String+listContinuation :: PandocMonad m => Int -> MuseParser m [String] listContinuation markerLength = try $ do   result <- many1 $ listLine markerLength-  blank <- option "" ("\n" <$ blankline)-  return $ concat result ++ blank+  blank <- option id ((++ [""]) <$ blankline)+  return $ blank result  listStart :: PandocMonad m => MuseParser m Int -> MuseParser m Int listStart marker = try $ do@@ -392,17 +395,24 @@   st <- stateParserContext <$> getState   getPosition >>= \pos -> guard (st == ListItemState || sourceColumn pos /= 1)   markerLength <- marker-  many1 spaceChar+  void spaceChar <|> eol   return $ preWhitespace + markerLength + 1 +dropSpacePrefix :: [String] -> [String]+dropSpacePrefix lns =+  map (drop maxIndent) lns+  where flns = filter (\s -> not $ all (== ' ') s) lns+        maxIndent = if null flns then 0 else length $ takeWhile (== ' ') $ foldl1 commonPrefix flns+ listItemContents :: PandocMonad m => Int -> MuseParser m (F Blocks) listItemContents markerLength = do-  firstLine <- anyLineNewline+  firstLine <- manyTill anyChar eol   restLines <- many $ listLine markerLength-  blank <- option "" ("\n" <$ blankline)-  let first = firstLine ++ concat restLines ++ blank+  blank <- option id ((++ [""]) <$ blankline)+  let first = firstLine : blank restLines   rest <- many $ listContinuation markerLength-  parseFromString (withListContext parseBlocks) $ concat (first:rest) ++ "\n"+  let allLines = concat (first : rest)+  parseFromString (withListContext parseBlocks) $ unlines (dropSpacePrefix allLines)  listItem :: PandocMonad m => MuseParser m Int -> MuseParser m (F Blocks) listItem start = try $ do@@ -428,7 +438,7 @@  orderedList :: PandocMonad m => MuseParser m (F Blocks) orderedList = try $ do-  p@(_, style, delim) <- lookAhead (many spaceChar *> anyOrderedListMarker <* spaceChar)+  p@(_, style, delim) <- lookAhead (many spaceChar *> anyOrderedListMarker <* (eol <|> void spaceChar))   guard $ style `elem` [Decimal, LowerAlpha, UpperAlpha, LowerRoman, UpperRoman]   guard $ delim == Period   items <- sequence <$> many1 (listItem $ orderedListStart style delim)@@ -436,20 +446,22 @@  definitionListItem :: PandocMonad m => MuseParser m (F (Inlines, [Blocks])) definitionListItem = try $ do-  term <- termParser+  rawTerm <- termParser+  term <- parseFromString (trimInlinesF . mconcat <$> many inline) rawTerm   many1 spaceChar   string "::"-  firstLine <- anyLineNewline-  restLines <- manyTill anyLineNewline endOfListItemElement-  let lns = firstLine : restLines-  lineContent <- parseFromString (withListContext parseBlocks) $ concat lns ++ "\n"+  firstLine <- manyTill anyChar eol+  restLines <- manyTill anyLine endOfListItemElement+  let lns = dropWhile (== ' ') firstLine : dropSpacePrefix restLines+  lineContent <- parseFromString (withListContext parseBlocks) $ unlines lns   pure $ do lineContent' <- lineContent-            pure (B.text term, [lineContent'])+            term' <- term+            pure (term', [lineContent'])   where     termParser = (guardDisabled Ext_amuse <|> void spaceChar) >> -- Initial space is required by Amusewiki, but not Emacs Muse                  many spaceChar >>-                 many1Till anyChar (lookAhead (void (try (spaceChar >> string "::")) <|> void newline))-    endOfInput = try $ skipMany blankline >> skipSpaces >> eof+                 many1Till (noneOf "\n") (lookAhead (void (try (spaceChar >> string "::"))))+    endOfInput = lookAhead $ try $ skipMany blankline >> skipSpaces >> eof     twoBlankLines = try $ blankline >> skipMany1 blankline     newDefinitionListItem = try $ void termParser     endOfListItemElement = lookAhead $ endOfInput <|> newDefinitionListItem <|> twoBlankLines@@ -569,9 +581,11 @@              , subscriptTag              , strikeoutTag              , verbatimTag+             , nbsp              , link              , code              , codeTag+             , inlineLiteralTag              , whitespace              , str              , symbol@@ -667,8 +681,14 @@ verbatimTag :: PandocMonad m => MuseParser m (F Inlines) verbatimTag = do   content <- parseHtmlContent "verbatim" anyChar-  return $ return $ B.text $ fromEntities content+  return $ return $ B.text content +nbsp :: PandocMonad m => MuseParser m (F Inlines)+nbsp = do+  guardDisabled Ext_amuse -- Supported only by Emacs Muse+  string "~~"+  return $ return $ B.str "\160"+ code :: PandocMonad m => MuseParser m (F Inlines) code = try $ do   pos <- getPosition@@ -686,13 +706,23 @@ codeTag :: PandocMonad m => MuseParser m (F Inlines) codeTag = do   (attrs, content) <- parseHtmlContentWithAttrs "code" anyChar-  return $ return $ B.codeWith attrs $ fromEntities content+  return $ return $ B.codeWith attrs content +inlineLiteralTag :: PandocMonad m => MuseParser m (F Inlines)+inlineLiteralTag = do+  guardDisabled Ext_amuse -- Text::Amuse does not support <literal>+  (attrs, content) <- parseHtmlContentWithAttrs "literal" anyChar+  return $ return $ rawInline (attrs, content)+  where+    -- FIXME: Emacs Muse inserts <literal> without style into all output formats, but we assume HTML+    format (_, _, kvs)        = fromMaybe "html" $ lookup "style" kvs+    rawInline (attrs, content) = B.rawInline (format attrs) content+ str :: PandocMonad m => MuseParser m (F Inlines)-str = fmap (return . B.str) (many1 alphaNum <|> count 1 characterReference)+str = return . B.str <$> many1 alphaNum  symbol :: PandocMonad m => MuseParser m (F Inlines)-symbol = (return . B.str) <$> count 1 nonspaceChar+symbol = return . B.str <$> count 1 nonspaceChar  link :: PandocMonad m => MuseParser m (F Inlines) link = try $ do
src/Text/Pandoc/Readers/Org/BlockStarts.hs view
@@ -75,21 +75,25 @@    latexEnvName :: Monad m => OrgParser m String    latexEnvName = try $ mappend <$> many1 alphaNum <*> option "" (string "*") ---- | Parses bullet list marker.-bulletListStart :: Monad m => OrgParser m ()-bulletListStart = try $-  choice-  [ () <$ skipSpaces  <* oneOf "+-" <* skipSpaces1-  , () <$ skipSpaces1 <* char '*'   <* skipSpaces1-  ]+bulletListStart :: Monad m => OrgParser m Int+bulletListStart = try $ do+  ind <- length <$> many spaceChar+   -- Unindented lists cannot use '*' bullets.+  oneOf (if ind == 0 then "+-" else "*+-")+  skipSpaces1 <|> lookAhead eol+  return (ind + 1)  genericListStart :: Monad m                  => OrgParser m String                  -> OrgParser m Int-genericListStart listMarker = try $-  (+) <$> (length <$> many spaceChar)-      <*> (length <$> listMarker <* many1 spaceChar)+genericListStart listMarker = try $ do+  ind <- length <$> many spaceChar+  void listMarker+  skipSpaces1 <|> lookAhead eol+  return (ind + 1)++eol :: Monad m => OrgParser m ()+eol = void (char '\n')  orderedListStart :: Monad m => OrgParser m Int orderedListStart = genericListStart orderedListMarker
src/Text/Pandoc/Readers/Org/Blocks.hs view
@@ -744,7 +744,7 @@   -- is directly followed by a list item, in which case the block is read as   -- plain text.   try (guard nl-       *> notFollowedBy (inList *> (() <$ orderedListStart <|> bulletListStart))+       *> notFollowedBy (inList *> (orderedListStart <|> bulletListStart))        *> return (B.para <$> ils))     <|>  return (B.plain <$> ils) @@ -757,40 +757,34 @@ list = choice [ definitionList, bulletList, orderedList ] <?> "list"  definitionList :: PandocMonad m => OrgParser m (F Blocks)-definitionList = try $ do n <- lookAhead (bulletListStart' Nothing)-                          fmap (B.definitionList . compactifyDL) . sequence-                            <$> many1 (definitionListItem $ bulletListStart' (Just n))+definitionList = try $ do+  indent <- lookAhead bulletListStart+  fmap (B.definitionList . compactifyDL) . sequence+    <$> many1 (definitionListItem (bulletListStart `indented` indent))  bulletList :: PandocMonad m => OrgParser m (F Blocks)-bulletList = try $ do n <- lookAhead (bulletListStart' Nothing)-                      fmap (B.bulletList . compactify) . sequence-                        <$> many1 (listItem (bulletListStart' $ Just n))--orderedList :: PandocMonad m => OrgParser m (F Blocks)-orderedList = fmap (B.orderedList . compactify) . sequence-              <$> many1 (listItem orderedListStart)+bulletList = try $ do+  indent <- lookAhead bulletListStart+  fmap (B.bulletList . compactify) . sequence+    <$> many1 (listItem (bulletListStart `indented` indent)) -bulletListStart' :: Monad m => Maybe Int -> OrgParser m Int--- returns length of bulletList prefix, inclusive of marker-bulletListStart' Nothing  = do ind <- length <$> many spaceChar-                               oneOf (bullets $ ind == 0)-                               skipSpaces1-                               return (ind + 1)-bulletListStart' (Just n) = do count (n-1) spaceChar-                               oneOf (bullets $ n == 1)-                               many1 spaceChar-                               return n+indented :: Monad m => OrgParser m Int -> Int -> OrgParser m Int+indented indentedMarker minIndent = try $ do+  n <- indentedMarker+  guard (minIndent <= n)+  return n --- Unindented lists are legal, but they can't use '*' bullets.--- We return n to maintain compatibility with the generic listItem.-bullets :: Bool -> String-bullets unindented = if unindented then "+-" else "*+-"+orderedList :: PandocMonad m => OrgParser m (F Blocks)+orderedList = try $ do+  indent <- lookAhead orderedListStart+  fmap (B.orderedList . compactify) . sequence+    <$> many1 (listItem (orderedListStart `indented` indent))  definitionListItem :: PandocMonad m                    => OrgParser m Int                    -> OrgParser m (F (Inlines, [Blocks]))-definitionListItem parseMarkerGetLength = try $ do-  markerLength <- parseMarkerGetLength+definitionListItem parseIndentedMarker = try $ do+  markerLength <- parseIndentedMarker   term <- manyTill (noneOf "\n\r") (try definitionMarker)   line1 <- anyLineNewline   blank <- option "" ("\n" <$ blankline)@@ -802,13 +796,12 @@    definitionMarker =      spaceChar *> string "::" <* (spaceChar <|> lookAhead newline) ---- parse raw text for one list item, excluding start marker and continuations+-- | parse raw text for one list item listItem :: PandocMonad m          => OrgParser m Int          -> OrgParser m (F Blocks)-listItem start = try . withContext ListItemState $ do-  markerLength <- try start+listItem parseIndentedMarker = try . withContext ListItemState $ do+  markerLength <- try parseIndentedMarker   firstLine <- anyLineNewline   blank <- option "" ("\n" <$ blankline)   rest <- concat <$> many (listContinuation markerLength)@@ -818,9 +811,9 @@ -- Note: nested lists are parsed as continuations. listContinuation :: Monad m => Int                  -> OrgParser m String-listContinuation markerLength = try $+listContinuation markerLength = try $ do   notFollowedBy' blankline-  *> (mappend <$> (concat <$> many1 listLine)-              <*> many blankline)+  mappend <$> (concat <$> many1 listLine)+          <*> many blankline  where    listLine = try $ indentWith markerLength *> anyLineNewline
src/Text/Pandoc/Shared.hs view
@@ -72,6 +72,7 @@                      inlineListToIdentifier,                      isHeaderBlock,                      headerShift,+                     stripEmptyParagraphs,                      isTightList,                      addMetaField,                      makeMeta,@@ -106,7 +107,7 @@ import Data.Char (isAlpha, isDigit, isLetter, isLower, isSpace, isUpper,                   toLower) import Data.Data (Data, Typeable)-import Data.List (find, intercalate, stripPrefix)+import Data.List (find, intercalate, intersperse, stripPrefix) import qualified Data.Map as M import Data.Maybe (mapMaybe) import Data.Monoid ((<>))@@ -291,7 +292,7 @@              parseTime defaultTimeLocale #endif         formats = ["%x","%m/%d/%Y", "%D","%F", "%d %b %Y",-                    "%d %B %Y", "%b. %d, %Y", "%B %d, %Y",+                    "%e %B %Y", "%b. %e, %Y", "%B %e, %Y",                     "%Y%m%d", "%Y%m", "%Y"]  --@@ -529,6 +530,14 @@         shift (Header level attr inner) = Header (level + n) attr inner         shift x                         = x +-- | Remove empty paragraphs.+stripEmptyParagraphs :: Pandoc -> Pandoc+stripEmptyParagraphs = walk go+  where go :: [Block] -> [Block]+        go = filter (not . isEmptyParagraph)+        isEmptyParagraph (Para []) = True+        isEmptyParagraph _         = False+ -- | Detect if a list is tight. isTightList :: [[Block]] -> Bool isTightList = all firstIsPlain@@ -708,37 +717,40 @@ --- Squash blocks into inlines --- -blockToInlines :: Block -> [Inline]-blockToInlines (Plain ils) = ils-blockToInlines (Para ils) = ils-blockToInlines (LineBlock lns) = combineLines lns-blockToInlines (CodeBlock attr str) = [Code attr str]-blockToInlines (RawBlock fmt str) = [RawInline fmt str]-blockToInlines (BlockQuote blks) = blocksToInlines blks+blockToInlines :: Block -> Inlines+blockToInlines (Plain ils) = B.fromList ils+blockToInlines (Para ils) = B.fromList ils+blockToInlines (LineBlock lns) = B.fromList $ combineLines lns+blockToInlines (CodeBlock attr str) = B.codeWith attr str+blockToInlines (RawBlock (Format fmt) str) = B.rawInline fmt str+blockToInlines (BlockQuote blks) = blocksToInlines' blks blockToInlines (OrderedList _ blkslst) =-  concatMap blocksToInlines blkslst+  mconcat $ map blocksToInlines' blkslst blockToInlines (BulletList blkslst) =-  concatMap blocksToInlines blkslst+  mconcat $ map blocksToInlines' blkslst blockToInlines (DefinitionList pairslst) =-  concatMap f pairslst+  mconcat $ map f pairslst   where-    f (ils, blkslst) = ils ++-      [Str ":", Space] ++-      concatMap blocksToInlines blkslst-blockToInlines (Header _ _  ils) = ils-blockToInlines HorizontalRule = []+    f (ils, blkslst) = B.fromList ils <> B.str ":" <> B.space <>+      mconcat (map blocksToInlines' blkslst)+blockToInlines (Header _ _  ils) = B.fromList ils+blockToInlines HorizontalRule = mempty blockToInlines (Table _ _ _ headers rows) =-  intercalate [LineBreak] $ map (concatMap blocksToInlines) tbl-  where-    tbl = headers : rows-blockToInlines (Div _ blks) = blocksToInlines blks-blockToInlines Null = []+  mconcat $ intersperse B.linebreak $+    map (mconcat . map blocksToInlines') (headers:rows)+blockToInlines (Div _ blks) = blocksToInlines' blks+blockToInlines Null = mempty -blocksToInlinesWithSep :: [Inline] -> [Block] -> [Inline]-blocksToInlinesWithSep sep blks = intercalate sep $ map blockToInlines blks+blocksToInlinesWithSep :: Inlines -> [Block] -> Inlines+blocksToInlinesWithSep sep =+  mconcat . intersperse sep . map blockToInlines +blocksToInlines' :: [Block] -> Inlines+blocksToInlines' = blocksToInlinesWithSep parSep+  where parSep = B.space <> B.str "¶" <> B.space+ blocksToInlines :: [Block] -> [Inline]-blocksToInlines = blocksToInlinesWithSep [Space, Str "¶", Space]+blocksToInlines = B.toList . blocksToInlines'   --
src/Text/Pandoc/Writers/CommonMark.hs view
@@ -39,13 +39,14 @@ import Data.Monoid (Any (..), (<>)) import Data.Text (Text) import qualified Data.Text as T+import Network.HTTP (urlEncode) import Text.Pandoc.Class (PandocMonad) import Text.Pandoc.Definition import Text.Pandoc.Options import Text.Pandoc.Shared (isTightList, linesToPara, substitute) import Text.Pandoc.Templates (renderTemplate') import Text.Pandoc.Walk (query, walk, walkM)-import Text.Pandoc.Writers.HTML (writeHtml5String)+import Text.Pandoc.Writers.HTML (writeHtml5String, tagWithAttributes) import Text.Pandoc.Writers.Shared  -- | Convert Pandoc to CommonMark.@@ -110,9 +111,12 @@ blockToNodes opts (LineBlock lns) ns = blockToNodes opts (linesToPara lns) ns blockToNodes _ (CodeBlock (_,classes,_) xs) ns = return   (node (CODE_BLOCK (T.pack (unwords classes)) (T.pack xs)) [] : ns)-blockToNodes _ (RawBlock fmt xs) ns-  | fmt == Format "html" = return (node (HTML_BLOCK (T.pack xs)) [] : ns)-  | otherwise = return (node (CUSTOM_BLOCK (T.pack xs) T.empty) [] : ns)+blockToNodes opts (RawBlock fmt xs) ns+  | fmt == Format "html" && isEnabled Ext_raw_html opts+              = return (node (HTML_BLOCK (T.pack xs)) [] : ns)+  | fmt == Format "latex" || fmt == Format "tex" && isEnabled Ext_raw_tex opts+              = return (node (CUSTOM_BLOCK (T.pack xs) T.empty) [] : ns)+  | otherwise = return ns blockToNodes opts (BlockQuote bs) ns = do   nodes <- blocksToNodes opts bs   return (node BLOCK_QUOTE nodes : ns)@@ -136,9 +140,13 @@ blockToNodes _ HorizontalRule ns = return (node THEMATIC_BREAK [] : ns) blockToNodes opts (Header lev _ ils) ns =   return (node (HEADING lev) (inlinesToNodes opts ils) : ns)-blockToNodes opts (Div _ bs) ns = do+blockToNodes opts (Div attr bs) ns = do   nodes <- blocksToNodes opts bs-  return (nodes ++ ns)+  let op = tagWithAttributes opts True False "div" attr+  if isEnabled Ext_raw_html opts+     then return (node (HTML_BLOCK op) [] : nodes +++                  [node (HTML_BLOCK (T.pack "</div>")) []] ++ ns)+     else return (nodes ++ ns) blockToNodes opts (DefinitionList items) ns =   blockToNodes opts (BulletList items') ns   where items' = map dlToBullet items@@ -262,9 +270,12 @@   inlineToNodes opts (Image alt ils (url,tit)) inlineToNodes opts (Image _ ils (url,tit)) =   (node (IMAGE (T.pack url) (T.pack tit)) (inlinesToNodes opts ils) :)-inlineToNodes _ (RawInline fmt xs)-  | fmt == Format "html" = (node (HTML_INLINE (T.pack xs)) [] :)-  | otherwise = (node (CUSTOM_INLINE (T.pack xs) T.empty) [] :)+inlineToNodes opts (RawInline fmt xs)+  | fmt == Format "html" && isEnabled Ext_raw_html opts+              = (node (HTML_INLINE (T.pack xs)) [] :)+  | (fmt == Format "latex" || fmt == Format "tex") && isEnabled Ext_raw_tex opts+              = (node (CUSTOM_INLINE (T.pack xs) T.empty) [] :)+  | otherwise = id inlineToNodes opts (Quoted qt ils) =   ((node (TEXT start) [] :    inlinesToNodes opts ils ++ [node (TEXT end) []]) ++)@@ -276,13 +287,28 @@                             | isEnabled Ext_smart opts -> ("\"", "\"")                             | otherwise -> ("“", "”") inlineToNodes _ (Code _ str) = (node (CODE (T.pack str)) [] :)-inlineToNodes _ (Math mt str) =-  case mt of-    InlineMath  ->-      (node (HTML_INLINE (T.pack ("\\(" ++ str ++ "\\)"))) [] :)-    DisplayMath ->-      (node (HTML_INLINE (T.pack ("\\[" ++ str ++ "\\]"))) [] :)-inlineToNodes opts (Span _ ils) = (inlinesToNodes opts ils ++)+inlineToNodes opts (Math mt str) =+  case writerHTMLMathMethod opts of+       WebTeX url ->+           let core = inlineToNodes opts+                        (Image nullAttr [Str str] (url ++ urlEncode str, str))+               sep = if mt == DisplayMath+                        then (node LINEBREAK [] :)+                        else id+           in  (sep . core . sep)+       _  ->+           case mt of+            InlineMath  ->+              (node (HTML_INLINE (T.pack ("\\(" ++ str ++ "\\)"))) [] :)+            DisplayMath ->+              (node (HTML_INLINE (T.pack ("\\[" ++ str ++ "\\]"))) [] :)+inlineToNodes opts (Span attr ils) =+  let nodes = inlinesToNodes opts ils+      op = tagWithAttributes opts True False "span" attr+  in  if isEnabled Ext_raw_html opts+         then ((node (HTML_INLINE op) [] : nodes +++                [node (HTML_INLINE (T.pack "</span>")) []]) ++)+         else (nodes ++) inlineToNodes opts (Cite _ ils) = (inlinesToNodes opts ils ++) inlineToNodes _ (Note _) = id -- should not occur -- we remove Note elements in preprocessing
src/Text/Pandoc/Writers/ConTeXt.hs view
@@ -31,7 +31,7 @@ -} module Text.Pandoc.Writers.ConTeXt ( writeConTeXt ) where import Control.Monad.State.Strict-import Data.Char (ord)+import Data.Char (ord, isDigit) import Data.List (intercalate, intersperse) import Data.Maybe (mapMaybe) import Data.Text (Text)@@ -104,8 +104,9 @@                 $ defField "number-sections" (writerNumberSections options)                 $ maybe id (defField "context-lang") mblang                 $ (case getField "papersize" metadata of-                        Just ("a4" :: String) -> resetField "papersize"-                                                    ("A4" :: String)+                        Just (('a':d:ds) :: String)+                          | all isDigit (d:ds) -> resetField "papersize"+                                                     (('A':d:ds) :: String)                         _                     -> id) metadata   let context' = defField "context-dir" (toContextDir                                          $ getField "dir" context) context
src/Text/Pandoc/Writers/Docx.hs view
@@ -922,8 +922,6 @@   captionNode <- withParaProp (pCustomStyle "ImageCaption")                  $ blockToOpenXML opts (Para alt)   return $ mknode "w:p" [] (paraProps ++ contents) : captionNode--- fixDisplayMath sometimes produces a Para [] as artifact-blockToOpenXML' _ (Para []) = return [] blockToOpenXML' opts (Para lst) = do   isFirstPara <- gets stFirstPara   paraProps <- getParaProps $ case lst of
src/Text/Pandoc/Writers/HTML.hs view
@@ -41,7 +41,8 @@   writeSlidy,   writeSlideous,   writeDZSlides,-  writeRevealJs+  writeRevealJs,+  tagWithAttributes   ) where import Control.Monad.State.Strict import Data.Char (ord, toLower)@@ -55,6 +56,7 @@ import Network.HTTP (urlEncode) import Network.URI (URI (..), parseURIReference, unEscapeString) import Numeric (showHex)+import Text.Blaze.Internal (customLeaf) import Text.Blaze.Html hiding (contents) import Text.Pandoc.Definition import Text.Pandoc.Highlighting (formatHtmlBlock, formatHtmlInline, highlight,@@ -83,7 +85,7 @@ import Text.Blaze.Html.Renderer.Text (renderHtml) import qualified Text.Blaze.XHtml1.Transitional as H import qualified Text.Blaze.XHtml1.Transitional.Attributes as A-import Text.Pandoc.Class (PandocMonad, report)+import Text.Pandoc.Class (PandocMonad, report, runPure) import Text.Pandoc.Error import Text.Pandoc.Logging import Text.TeXMath@@ -541,6 +543,21 @@ -- | Obfuscate string using entities. obfuscateString :: String -> String obfuscateString = concatMap obfuscateChar . fromEntities++-- | Create HTML tag with attributes.+tagWithAttributes :: WriterOptions+                  -> Bool -- ^ True for HTML5+                  -> Bool -- ^ True if self-closing tag+                  -> Text -- ^ Tag text+                  -> Attr -- ^ Pandoc style tag attributes+                  -> Text+tagWithAttributes opts html5 selfClosing tagname attr =+  let mktag = (TL.toStrict . renderHtml <$> evalStateT+               (addAttrs opts attr (customLeaf (textTag tagname) selfClosing))+               defaultWriterState{ stHtml5 = html5 })+  in  case runPure mktag of+           Left _  -> mempty+           Right t -> t  addAttrs :: PandocMonad m          => WriterOptions -> Attr -> Html -> StateT WriterState m Html
src/Text/Pandoc/Writers/LaTeX.hs view
@@ -253,8 +253,10 @@                   defField "section-titles" True $                   defField "geometry" geometryFromMargins $                   (case getField "papersize" metadata of-                        Just ("A4" :: String) -> resetField "papersize"-                                                    ("a4" :: String)+                        -- uppercase a4, a5, etc.+                        Just (('A':d:ds) :: String)+                          | all isDigit (d:ds) -> resetField "papersize"+                                                    (('a':d:ds) :: String)                         _                     -> id)                   metadata   let context' =@@ -1011,7 +1013,7 @@         let chr = case "!\"&'()*,-./:;?@_" \\ str of                        (c:_) -> c                        []    -> '!'-        let str' = escapeStringUsing (backslashEscapes "\\{}%") str+        let str' = escapeStringUsing (backslashEscapes "\\{}%~_") str         -- we always put lstinline in a dummy 'passthrough' command         -- (defined in the default template) so that we don't have         -- to change the way we escape characters depending on whether@@ -1122,7 +1124,12 @@                          Just dim         ->                            [d <> text (show dim)]                          Nothing          ->-                           []+                           case dir of+                                Width | isJust (dimension Height attr) ->+                                  [d <> "\\textwidth"]+                                Height | isJust (dimension Width attr) ->+                                  [d <> "\\textheight"]+                                _ -> []       dimList = showDim Width ++ showDim Height       dims = if null dimList                 then empty
src/Text/Pandoc/Writers/Markdown.hs view
@@ -1068,9 +1068,8 @@   return $ text str' inlineToMarkdown opts (Math InlineMath str) =   case writerHTMLMathMethod opts of-       WebTeX url ->-             inlineToMarkdown opts (Image nullAttr [Str str]-                 (url ++ urlEncode str, str))+       WebTeX url -> inlineToMarkdown opts+                       (Image nullAttr [Str str] (url ++ urlEncode str, str))        _ | isEnabled Ext_tex_math_dollars opts ->              return $ "$" <> text str <> "$"          | isEnabled Ext_tex_math_single_backslash opts ->
src/Text/Pandoc/Writers/Muse.hs view
@@ -284,16 +284,40 @@  -- | Escape special characters for Muse if needed. conditionalEscapeString :: String -> String-conditionalEscapeString s-  | any (`elem` ("*<=>[]|" :: String)) s ||-    "::" `isInfixOf` s = escapeString s-  | otherwise = s+conditionalEscapeString s =+  if any (`elem` ("#*<=>[]|" :: String)) s ||+     "::" `isInfixOf` s ||+     "----" `isInfixOf` s+    then escapeString s+    else s +normalizeInlineList :: [Inline] -> [Inline]+normalizeInlineList (Emph x1 : Emph x2 : ils)+  = normalizeInlineList $ Emph (x1 ++ x2) : ils+normalizeInlineList (Strong x1 : Strong x2 : ils)+  = normalizeInlineList $ Strong (x1 ++ x2) : ils+normalizeInlineList (Strikeout x1 : Strikeout x2 : ils)+  = normalizeInlineList $ Strikeout (x1 ++ x2) : ils+normalizeInlineList (Superscript x1 : Superscript x2 : ils)+  = normalizeInlineList $ Superscript (x1 ++ x2) : ils+normalizeInlineList (Subscript x1 : Subscript x2 : ils)+  = normalizeInlineList $ Subscript (x1 ++ x2) : ils+normalizeInlineList (SmallCaps x1 : SmallCaps x2 : ils)+  = normalizeInlineList $ SmallCaps (x1 ++ x2) : ils+normalizeInlineList (Code a1 x1 : Code a2 x2 : ils) | a1 == a2+  = normalizeInlineList $ Code a1 (x1 ++ x2) : ils+normalizeInlineList (RawInline f1 x1 : RawInline f2 x2 : ils) | f1 == f2+  = normalizeInlineList $ RawInline f1 (x1 ++ x2) : ils+normalizeInlineList (Span a1 x1 : Span a2 x2 : ils) | a1 == a2+  = normalizeInlineList $ Span a1 (x1 ++ x2) : ils+normalizeInlineList (x:xs) = x : normalizeInlineList xs+normalizeInlineList [] = []+ -- | Convert list of Pandoc inline elements to Muse. inlineListToMuse :: PandocMonad m                  => [Inline]                  -> StateT WriterState m Doc-inlineListToMuse lst = liftM hcat (mapM inlineToMuse lst)+inlineListToMuse lst = liftM hcat (mapM inlineToMuse (normalizeInlineList lst))  -- | Convert Pandoc inline element to Muse. inlineToMuse :: PandocMonad m@@ -328,7 +352,7 @@ -- so just fallback to expanding inlines. inlineToMuse (Cite _  lst) = inlineListToMuse lst inlineToMuse (Code _ str) = return $-  "<code>" <> text (conditionalEscapeString str) <> "</code>"+  "<code>" <> text (substitute "</code>" "<</code><code>/code>" str) <> "</code>" inlineToMuse (Math InlineMath str) =   lift (texMathToInlines InlineMath str) >>= inlineListToMuse inlineToMuse (Math DisplayMath str) = do
src/Text/Pandoc/Writers/Shared.hs view
@@ -196,13 +196,19 @@ fixDisplayMath (Plain lst)   | any isDisplayMath lst && not (all isDisplayMath lst) =     -- chop into several paragraphs so each displaymath is its own-    Div ("",["math"],[]) $ map (Plain . stripLeadingTrailingSpace) $+    Div ("",["math"],[]) $+       map Plain $+       filter (not . null) $+       map stripLeadingTrailingSpace $        groupBy (\x y -> (isDisplayMath x && isDisplayMath y) ||                          not (isDisplayMath x || isDisplayMath y)) lst fixDisplayMath (Para lst)   | any isDisplayMath lst && not (all isDisplayMath lst) =     -- chop into several paragraphs so each displaymath is its own-    Div ("",["math"],[]) $ map (Para . stripLeadingTrailingSpace) $+    Div ("",["math"],[]) $+       map Para $+       filter (not . null) $+       map stripLeadingTrailingSpace $        groupBy (\x y -> (isDisplayMath x && isDisplayMath y) ||                          not (isDisplayMath x || isDisplayMath y)) lst fixDisplayMath x = x
stack.yaml view
@@ -10,11 +10,12 @@ - pandoc-types-1.17.3 - hslua-0.9.2 - hslua-module-text-0.1.2-- skylighting-0.4.3.2+- skylighting-0.4.4.1 - texmath-0.10 - cmark-gfm-0.1.1 - QuickCheck-2.10.0.1 - tasty-quickcheck-0.9.1 - doctemplates-0.2.1 - haddock-library-1.4.3-resolver: lts-9.9+- tagsoup-0.14.2+resolver: lts-9.14
test/Tests/Readers/Docx.hs view
@@ -10,6 +10,7 @@ import Test.Tasty.HUnit import Tests.Helpers import Text.Pandoc+import Text.Pandoc.Shared (stripEmptyParagraphs) import qualified Text.Pandoc.Class as P import Text.Pandoc.MediaBag (MediaBag, lookupMedia, mediaDirectory) import Text.Pandoc.UTF8 as UTF8@@ -37,20 +38,23 @@ instance ToPandoc NoNormPandoc where   toPandoc = unNoNorm -compareOutput :: ReaderOptions-                 -> FilePath-                 -> FilePath-                 -> IO (NoNormPandoc, NoNormPandoc)-compareOutput opts docxFile nativeFile = do+compareOutput :: Bool+              -> ReaderOptions+              -> FilePath+              -> FilePath+              -> IO (NoNormPandoc, NoNormPandoc)+compareOutput strip opts docxFile nativeFile = do   df <- B.readFile docxFile   nf <- UTF8.toText <$> BS.readFile nativeFile   p <- runIOorExplode $ readDocx opts df   df' <- runIOorExplode $ readNative def nf-  return $ (noNorm p, noNorm df')+  return $ (noNorm (if strip+                       then stripEmptyParagraphs p+                       else p), noNorm df')  testCompareWithOptsIO :: ReaderOptions -> String -> FilePath -> FilePath -> IO TestTree testCompareWithOptsIO opts name docxFile nativeFile = do-  (dp, np) <- compareOutput opts docxFile nativeFile+  (dp, np) <- compareOutput True opts docxFile nativeFile   return $ test id name (dp, np)  testCompareWithOpts :: ReaderOptions -> String -> FilePath -> FilePath -> TestTree@@ -71,6 +75,11 @@ testForWarningsWithOpts opts name docxFile expected =   unsafePerformIO $ testForWarningsWithOptsIO opts name docxFile expected +testCompareNoStrip :: String -> FilePath -> FilePath -> TestTree+testCompareNoStrip name docxFile nativeFile = unsafePerformIO $ do+  (dp, np) <- compareOutput False defopts docxFile nativeFile+  return $ test id name (dp, np)+ -- testForWarnings :: String -> FilePath -> [String] -> TestTree -- testForWarnings = testForWarningsWithOpts defopts @@ -257,6 +266,10 @@             "dropcap paragraphs"             "docx/drop_cap.docx"             "docx/drop_cap.native"+          , testCompareNoStrip+            "empty paragraphs without stripping"+            "docx/drop_cap.docx"+            "docx/drop_cap_nostrip.native"           ]         , testGroup "track changes"           [ testCompare
test/Tests/Readers/Muse.hs view
@@ -5,10 +5,12 @@ import Data.Text (Text) import qualified Data.Text as T import Test.Tasty+-- import Test.Tasty.QuickCheck import Tests.Helpers import Text.Pandoc import Text.Pandoc.Arbitrary () import Text.Pandoc.Builder+-- import Text.Pandoc.Walk (walk)  amuse :: Text -> Pandoc amuse = purely $ readMuse def { readerExtensions = extensionsFromList [Ext_amuse]}@@ -24,6 +26,28 @@ spcSep :: [Inlines] -> Inlines spcSep = mconcat . intersperse space +{-+-- Tables and code blocks don't round-trip yet++removeTables :: Block -> Block+removeTables (Table{}) = Para [Str "table was here"]+removeTables x = x++-- Demand that any AST produced by Muse reader and written by Muse writer can be read back exactly the same way.+-- Currently we remove code blocks and tables and compare third rewrite to the second.+-- First and second rewrites are not equal yet.+roundTrip :: Block -> Bool+roundTrip b = d'' == d'''+  where d = walk removeTables $ Pandoc nullMeta [b]+        d' = rewrite d+        d'' = rewrite d'+        d''' = rewrite d''+        rewrite = amuse . T.pack . (++ "\n") . T.unpack .+                  (purely $ writeMuse def { writerExtensions = extensionsFromList [Ext_amuse]+                                          , writerWrapText = WrapPreserve+                                          })+-}+ tests :: [TestTree] tests =   [ testGroup "Inlines"@@ -31,6 +55,8 @@           "Hello, World" =?>           para "Hello, World" +      , "Muse is not XML" =: "&lt;" =?> para "&lt;"+       , "Emphasis" =:         "*Foo bar*" =?>         para (emph . spcSep $ ["Foo", "bar"])@@ -81,6 +107,9 @@        , "Linebreak" =: "Line <br>  break" =?> para ("Line" <> linebreak <> "break") +      , test emacsMuse "Non-breaking space"+        ("Foo~~bar" =?> para ("Foo\160bar"))+       , testGroup "Code markup"         [ "Code" =: "=foo(bar)=" =?> para (code "foo(bar)") @@ -123,6 +152,8 @@        , "Verbatim tag" =: "*<verbatim>*</verbatim>*" =?> para (emph "*") +      , "Verbatim inside code" =: "<code><verbatim>foo</verbatim></code>" =?> para (code "<verbatim>foo</verbatim>")+       , testGroup "Links"         [ "Link without description" =:           "[[https://amusewiki.org/]]" =?>@@ -149,10 +180,20 @@         , "No implicit links" =: "http://example.org/index.php?action=view&id=1"                =?> para "http://example.org/index.php?action=view&id=1"         ]++      , testGroup "Literal"+        [ test emacsMuse "Inline literal"+          ("Foo<literal style=\"html\">lit</literal>bar" =?>+          para (text "Foo" <> rawInline "html" "lit" <> text "bar"))+        , "No literal in Text::Amuse" =:+          "Foo<literal style=\"html\">lit</literal>bar" =?>+          para "Foo<literal style=\"html\">lit</literal>bar"+        ]       ]    , testGroup "Blocks"-      [ "Block elements end paragraphs" =:+      [ -- testProperty "Round trip" roundTrip,+        "Block elements end paragraphs" =:         T.unlines [ "First paragraph"                   , "----"                   , "Second paragraph"@@ -302,7 +343,71 @@                     , "</example>"                     ] =?>           codeBlock "Example line\n"+        , "Example inside list" =:+          T.unlines [ " - <example>"+                    , "   foo"+                    , "   </example>"+                    ] =?>+          bulletList [ codeBlock "foo" ]+        , "Example inside list with empty lines" =:+          T.unlines [ " - <example>"+                    , "   foo"+                    , "   </example>"+                    , ""+                    , "   bar"+                    , ""+                    , "   <example>"+                    , "   baz"+                    , "   </example>"+                    ] =?>+          bulletList [ codeBlock "foo" <> para "bar" <> codeBlock "baz" ]+        , "Indented example inside list" =:+          T.unlines [ " -  <example>"+                    , "    foo"+                    , "    </example>"+                    ] =?>+          bulletList [ codeBlock "foo" ]+        , "Example inside definition list" =:+          T.unlines [ " foo :: <example>"+                    , "        bar"+                    , "        </example>"+                    ] =?>+          definitionList [ ("foo", [codeBlock "bar"]) ]+        , "Example inside list definition with empty lines" =:+          T.unlines [ " term :: <example>"+                    , "         foo"+                    , "         </example>"+                    , ""+                    , "         bar"+                    , ""+                    , "         <example>"+                    , "         baz"+                    , "         </example>"+                    ] =?>+          definitionList [ ("term", [codeBlock "foo" <> para "bar" <> codeBlock "baz"]) ]+        , "Example inside note" =:+          T.unlines [ "Foo[1]"+                    , ""+                    , "[1] <example>"+                    , "    bar"+                    , "    </example>"+                    ] =?>+          para ("Foo" <> note (codeBlock "bar"))         ]+      , testGroup "Literal blocks"+        [ test emacsMuse "Literal block"+          (T.unlines [ "<literal style=\"latex\">"+                    , "\\newpage"+                    , "</literal>"+                    ] =?>+          rawBlock "latex" "\\newpage")+        , "No literal blocks in Text::Amuse" =:+          T.unlines [ "<literal style=\"latex\">"+                    , "\\newpage"+                    , "</literal>"+                    ] =?>+          para "<literal style=\"latex\">\n\\newpage\n</literal>"+        ]       , "Center" =: "<center>Hello, world</center>" =?> para (text "Hello, world")       , "Right" =: "<right>Hello, world</right>" =?> para (text "Hello, world")       , testGroup "Comments"@@ -510,23 +615,56 @@         ]     , testGroup "Lists"       [ "Bullet list" =:-         T.unlines+        T.unlines            [ " - Item1"            , ""            , " - Item2"            ] =?>-         bulletList [ para "Item1"-                    , para "Item2"-                    ]+        bulletList [ para "Item1"+                   , para "Item2"+                   ]       , "Ordered list" =:-         T.unlines-           [ " 1. Item1"-           , ""-           , " 2. Item2"-           ] =?>-         orderedListWith (1, Decimal, Period) [ para "Item1"-                                              , para "Item2"-                                              ]+        T.unlines+          [ " 1. Item1"+          , ""+          , " 2. Item2"+          ] =?>+        orderedListWith (1, Decimal, Period) [ para "Item1"+                                             , para "Item2"+                                             ]+      , "Ordered list with implicit numbers" =:+        T.unlines+          [ " 1. Item1"+          , ""+          , " 1. Item2"+          , ""+          , " 1. Item3"+          ] =?>+        orderedListWith (1, Decimal, Period) [ para "Item1"+                                             , para "Item2"+                                             , para "Item3"+                                             ]+      , "Bullet list with empty items" =:+        T.unlines+          [ " -"+          , ""+          , " - Item2"+          ] =?>+        bulletList [ mempty+                   , para "Item2"+                   ]+      , "Ordered list with empty items" =:+        T.unlines+          [ " 1."+          , ""+          , " 2."+          , ""+          , " 3. Item3"+          ] =?>+        orderedListWith (1, Decimal, Period) [ mempty+                                             , mempty+                                             , para "Item3"+                                             ]       , testGroup "Nested lists"         [ "Nested list" =:           T.unlines@@ -696,6 +834,10 @@           ] =?>         para "Foo" <>         definitionList [ ("Bar", [ para "baz" ]) ]+      , "One-line definition list" =: " foo :: bar" =?>+        definitionList [ ("foo", [ para "bar" ]) ]+      , "Definition list term with emphasis" =: " *Foo* :: bar\n" =?>+        definitionList [ (emph "Foo", [ para "bar" ]) ]       , "Multi-line definition lists" =:         T.unlines           [ " First term :: Definition of first term"@@ -705,6 +847,31 @@         definitionList [ ("First term", [ para "Definition of first term\nand its continuation." ])                        , ("Second term", [ para "Definition of second term." ])                        ]+      , test emacsMuse "Multi-line definition lists from Emacs Muse manual"+        (T.unlines+          [ "Term1 ::"+          , "  This is a first definition"+          , "  And it has two lines;"+          , "no, make that three."+          , ""+          , "Term2 :: This is a second definition"+          ] =?>+         definitionList [ ("Term1", [ para "This is a first definition\nAnd it has two lines;\nno, make that three."])+                        , ("Term2", [ para "This is a second definition"])+                        ])+      -- Text::Amuse requires indentation with one space+      , "Multi-line definition lists from Emacs Muse manual with initial space" =:+        (T.unlines+          [ " Term1 ::"+          , "  This is a first definition"+          , "  And it has two lines;"+          , "no, make that three."+          , ""+          , " Term2 :: This is a second definition"+          ] =?>+         definitionList [ ("Term1", [ para "This is a first definition\nAnd it has two lines;\nno, make that three."])+                        , ("Term2", [ para "This is a second definition"])+                        ])       -- Emacs Muse creates two separate lists when indentation of items is different.       -- We follow Amusewiki and allow different indentation within one list.       , "Changing indentation" =:
test/Tests/Readers/Org.hs view
@@ -1262,6 +1262,12 @@                   , headerWith ("notvalidlistitem", [], []) 1 "NotValidListItem"                   ] +      , "Empty bullet points" =:+          T.unlines [ "-"+                    , "- "+                    ] =?>+          bulletList [ plain "", plain "" ]+       , "Simple Ordered List" =:           ("1. Item1\n" <>            "2. Item2\n") =?>@@ -1288,6 +1294,12 @@                               , plain "Item2"                               ]           in orderedListWith listStyle listStructure++      , "Empty ordered list item" =:+          T.unlines [ "1."+                    , "3. "+                    ] =?>+          orderedList [ plain "", plain "" ]        , "Nested Ordered Lists" =:           ("1. One\n" <>
test/Tests/Writers/Muse.hs view
@@ -236,6 +236,7 @@                       ]             ]           , "horizontal rule" =: horizontalRule =?> "----"+          , "escape horizontal rule" =: para (text "----") =?> "<verbatim>----</verbatim>"           , testGroup "tables"             [ "table without header" =:               let rows = [[para $ text "Para 1.1", para $ text "Para 1.2"]@@ -278,6 +279,8 @@                =?> "<verbatim>foo<</verbatim><verbatim>/verbatim>bar</verbatim>"             , "escape pipe to avoid accidental tables" =: str "foo | bar"                =?> "<verbatim>foo | bar</verbatim>"+            , "escape hash to avoid accidental anchors" =: text "#foo bar"+              =?> "<verbatim>#foo</verbatim> bar"             , "escape definition list markers" =: str "::" =?> "<verbatim>::</verbatim>"             -- We don't want colons to be escaped if they can't be confused             -- with definition list item markers.@@ -296,8 +299,8 @@           -- Cite is trivial           , testGroup "code"             [ "simple" =: code "foo" =?> "<code>foo</code>"-            , "escape lightweight markup" =: code "foo = bar" =?> "<code><verbatim>foo = bar</verbatim></code>"-            , "escape tag" =: code "<code>foo = bar</code> baz" =?> "<code><verbatim><code>foo = bar</code> baz</verbatim></code>"+            , "escape tag" =: code "<code>foo = bar</code> baz" =?> "<code><code>foo = bar<</code><code>/code> baz</code>"+            , "normalization" =: code "</co" <> code "de>" =?> "<code><</code><code>/code></code>"             ]           , testGroup "spaces"             [ "space" =: text "a" <> space <> text "b" =?> "a b"@@ -310,6 +313,7 @@           , testGroup "math"             [ "inline math" =: math "2^3" =?> "2<sup>3</sup>"             , "display math" =: displayMath "2^3" =?> "<verse>2<sup>3</sup></verse>"+            , "multiple letters in inline math" =: math "abc" =?> "<em>abc</em>"             ]           , "raw inline"             =: rawInline "html" "<mark>marked text</mark>"
test/command/3450.md view
@@ -8,5 +8,5 @@ % pandoc -fmarkdown-implicit_figures -t latex ![image](lalune.jpg){height=2em} ^D-\includegraphics[height=2em]{lalune.jpg}+\includegraphics[width=\textwidth,height=2em]{lalune.jpg} ```
+ test/command/4091.md view
@@ -0,0 +1,6 @@+```+% pandoc -f latex+\alert<3>{foo}+^D+<p><span class="alert">foo</span></p>+```
+ test/command/4113.md view
@@ -0,0 +1,12 @@+```+% pandoc -t gfm+::::{.bug}+I am a [bug]{#bug}.+::::+^D+<div class="bug">++I am a <span id="bug">bug</span>.++</div>+```
test/docx/0_level_headers.native view
@@ -1,15 +1,15 @@ [Table [] [AlignDefault] [0.0]  [[]]- [[[]]+ [[[Plain []]]  ,[[Plain [Str "User\8217s",Space,Str "Guide"]]]- ,[[]]- ,[[]]- ,[[]]+ ,[[Plain []]]+ ,[[Plain []]]+ ,[[Plain []]]  ,[[Plain [Str "11",Space,Str "August",Space,Str "2017"]]]- ,[[]]- ,[[]]- ,[[]]- ,[[]]]+ ,[[Plain []]]+ ,[[Plain []]]+ ,[[Plain []]]+ ,[[Plain []]]] ,Para [Str "CONTENTS"] ,Para [Strong [Str "Section",Space,Str "Page"]] ,Para [Str "FIGURES",Space,Str "iv"]
test/docx/comments.native view
@@ -1,4 +1,4 @@ [Para [Str "I",Space,Str "want",Space,Span ("",["comment-start"],[("id","0"),("author","Jesse Rosenthal"),("date","2016-05-09T16:13:00Z")]) [Str "I",Space,Str "left",Space,Str "a",Space,Str "comment."],Str "some",Space,Str "text",Space,Str "to",Space,Str "have",Space,Str "a",Space,Str "comment",Space,Span ("",["comment-end"],[("id","0")]) [],Str "on",Space,Str "it."] ,Para [Str "This",Space,Str "is",Space,Span ("",["comment-start"],[("id","1"),("author","Jesse Rosenthal"),("date","2016-05-09T16:13:00Z")]) [Str "A",Space,Str "comment",Space,Str "across",Space,Str "paragraphs."],Str "a",Space,Str "new",Space,Str "paragraph."] ,Para [Str "And",Space,Str "so",Span ("",["comment-end"],[("id","1")]) [],Space,Str "is",Space,Str "this."]-,Para [Str "One",Space,Span ("",["comment-start"],[("id","2"),("author","Jesse Rosenthal"),("date","2016-05-09T16:14:00Z")]) [Str "This",Space,Str "one",Space,Str "has",Space,Str "multiple",Space,Str "paragraphs.",Space,Str "\182",Space,Str "See?"],Str "more",Span ("",["comment-end"],[("id","2")]) [],Str ".",Space,Str "And",Space,Str "this",Space,Str "is",Space,Str "one",Space,Str "with",Space,Str "a",Space,Span ("",["comment-start"],[("id","3"),("author","Jesse Rosenthal"),("date","2016-06-22T14:35:00Z")]) [Str "Do",Space,Str "something."],Span ("",["comment-start"],[("id","4"),("author","Jesse Rosenthal"),("date","2016-06-22T14:36:00Z")]) [Str "Do",Space,Str "something",Space,Str "else."],Str "comment",Space,Str "in",Space,Str "a",Space,Str "comment",Span ("",["comment-end"],[("id","3")]) [Span ("",["comment-end"],[("id","4")]) []],Str "."]]+,Para [Str "One",Space,Span ("",["comment-start"],[("id","2"),("author","Jesse Rosenthal"),("date","2016-05-09T16:14:00Z")]) [Str "This",Space,Str "one",Space,Str "has",Space,Str "multiple",Space,Str "paragraphs.",Space,Str "\182",Space,Str "\182",Space,Str "See?"],Str "more",Span ("",["comment-end"],[("id","2")]) [],Str ".",Space,Str "And",Space,Str "this",Space,Str "is",Space,Str "one",Space,Str "with",Space,Str "a",Space,Span ("",["comment-start"],[("id","3"),("author","Jesse Rosenthal"),("date","2016-06-22T14:35:00Z")]) [Str "Do",Space,Str "something."],Span ("",["comment-start"],[("id","4"),("author","Jesse Rosenthal"),("date","2016-06-22T14:36:00Z")]) [Str "Do",Space,Str "something",Space,Str "else."],Str "comment",Space,Str "in",Space,Str "a",Space,Str "comment",Span ("",["comment-end"],[("id","3")]) [Span ("",["comment-end"],[("id","4")]) []],Str "."]]
+ test/docx/drop_cap_nostrip.native view
@@ -0,0 +1,9 @@+[Para [Str "Drop",Space,Str "cap."]+,Para []+,Para [Str "Next",Space,Str "paragraph."]+,Para []+,Para [Str "Drop",Space,Str "cap",Space,Str "in",Space,Str "margin."]+,Para []+,Para []+,Para []+,Para [Str "Drop",Space,Str "cap",Space,Str "(not",Space,Str "really)."]]
test/lhs-test.html view
@@ -8,29 +8,32 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;}   </style>   <style type="text/css">-div.sourceLine, a.sourceLine { display: inline-block; min-height: 1.25em; }+a.sourceLine { display: inline-block; min-height: 1.25em; } a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; } .sourceCode { overflow: visible; } code.sourceCode { white-space: pre; } @media print { code.sourceCode { white-space: pre-wrap; }-div.sourceLine, a.sourceLine { text-indent: -1em; padding-left: 1em; }+a.sourceLine { text-indent: -1em; padding-left: 1em; } }-pre.numberSource div.sourceLine, .numberSource a.sourceLine+pre.numberSource a.sourceLine   { position: relative; }-pre.numberSource div.sourceLine::before, .numberSource a.sourceLine::before+pre.numberSource a.sourceLine::before   { content: attr(data-line-number);     position: absolute; left: -5em; text-align: right; vertical-align: baseline;     border: none; pointer-events: all;     -webkit-touch-callout: none; -webkit-user-select: none;     -khtml-user-select: none; -moz-user-select: none;     -ms-user-select: none; user-select: none;-    padding: 0 4px; width: 4em; }-pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; color: #aaaaaa;  padding-left: 4px; }+    padding: 0 4px; width: 4em;+    color: #aaaaaa;+  }+pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; } @media screen { a.sourceLine::before { text-decoration: underline; color: initial; } }@@ -72,9 +75,9 @@ <h1 id="lhs-test">lhs test</h1> <p><code>unsplit</code> is an arrow that takes a pair of values and combines them to return a single value:</p>-<pre class="sourceCode literate haskell" id="cb1"><code class="sourceCode haskell"><div class="sourceLine" id="cb1-1" data-line-number="1"><span class="ot">unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d</div>-<div class="sourceLine" id="cb1-2" data-line-number="2">unsplit <span class="fu">=</span> arr <span class="fu">.</span> uncurry</div>-<div class="sourceLine" id="cb1-3" data-line-number="3">          <span class="co">-- arr (\op (x,y) -&gt; x `op` y)</span></div></code></pre>+<pre class="sourceCode literate haskell" id="cb1"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="ot">unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d</a>+<a class="sourceLine" id="cb1-2" data-line-number="2">unsplit <span class="fu">=</span> arr <span class="fu">.</span> uncurry</a>+<a class="sourceLine" id="cb1-3" data-line-number="3">          <span class="co">-- arr (\op (x,y) -&gt; x `op` y)</span></a></code></pre> <p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a pair of values (one arrow on the first item of the pair and one arrow on the second item of the pair).</p>
test/lhs-test.html+lhs view
@@ -8,29 +8,32 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;}   </style>   <style type="text/css">-div.sourceLine, a.sourceLine { display: inline-block; min-height: 1.25em; }+a.sourceLine { display: inline-block; min-height: 1.25em; } a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; } .sourceCode { overflow: visible; } code.sourceCode { white-space: pre; } @media print { code.sourceCode { white-space: pre-wrap; }-div.sourceLine, a.sourceLine { text-indent: -1em; padding-left: 1em; }+a.sourceLine { text-indent: -1em; padding-left: 1em; } }-pre.numberSource div.sourceLine, .numberSource a.sourceLine+pre.numberSource a.sourceLine   { position: relative; }-pre.numberSource div.sourceLine::before, .numberSource a.sourceLine::before+pre.numberSource a.sourceLine::before   { content: attr(data-line-number);     position: absolute; left: -5em; text-align: right; vertical-align: baseline;     border: none; pointer-events: all;     -webkit-touch-callout: none; -webkit-user-select: none;     -khtml-user-select: none; -moz-user-select: none;     -ms-user-select: none; user-select: none;-    padding: 0 4px; width: 4em; }-pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; color: #aaaaaa;  padding-left: 4px; }+    padding: 0 4px; width: 4em;+    color: #aaaaaa;+  }+pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; } @media screen { a.sourceLine::before { text-decoration: underline; color: initial; } }@@ -72,9 +75,9 @@ <h1 id="lhs-test">lhs test</h1> <p><code>unsplit</code> is an arrow that takes a pair of values and combines them to return a single value:</p>-<pre class="sourceCode literate literatehaskell" id="cb1"><code class="sourceCode literatehaskell"><div class="sourceLine" id="cb1-1" data-line-number="1"><span class="ot">&gt; unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d</div>-<div class="sourceLine" id="cb1-2" data-line-number="2"><span class="ot">&gt;</span> unsplit <span class="fu">=</span> arr <span class="fu">.</span> uncurry</div>-<div class="sourceLine" id="cb1-3" data-line-number="3"><span class="ot">&gt;</span>           <span class="co">-- arr (\op (x,y) -&gt; x `op` y)</span></div></code></pre>+<pre class="sourceCode literate literatehaskell" id="cb1"><code class="sourceCode literatehaskell"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="ot">&gt; unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d</a>+<a class="sourceLine" id="cb1-2" data-line-number="2"><span class="ot">&gt;</span> unsplit <span class="fu">=</span> arr <span class="fu">.</span> uncurry</a>+<a class="sourceLine" id="cb1-3" data-line-number="3"><span class="ot">&gt;</span>           <span class="co">-- arr (\op (x,y) -&gt; x `op` y)</span></a></code></pre> <p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a pair of values (one arrow on the first item of the pair and one arrow on the second item of the pair).</p>
test/s5-basic.html view
@@ -13,6 +13,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;}   </style>
test/s5-fancy.html view
@@ -13,6 +13,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;}   </style>
test/s5-inserts.html view
@@ -11,6 +11,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;}   </style>
test/writer.html4 view
@@ -11,6 +11,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;}   </style>
test/writer.html5 view
@@ -11,6 +11,7 @@   <style type="text/css">       code{white-space: pre-wrap;}       span.smallcaps{font-variant: small-caps;}+      span.underline{text-decoration: underline;}       div.line-block{white-space: pre-line;}       div.column{display: inline-block; vertical-align: top; width: 50%;}   </style>
test/writer.muse view
@@ -478,8 +478,8 @@  So is <strong><em>this</em></strong> word. -This is code: <code><verbatim>></verbatim></code>, <code>$</code>,-<code>\</code>, <code>\$</code>, <code><verbatim><html></verbatim></code>.+This is code: <code>></code>, <code>$</code>, <code>\</code>, <code>\$</code>,+<code><html></code>.  <del>This is <em>strikeout</em>.</del> @@ -529,8 +529,7 @@  These shouldn’t be math: - - To get the famous equation, write-   <code><verbatim>$e = mc^2$</verbatim></code>.+ - To get the famous equation, write <code>$e = mc^2$</code>.  - $22,000 is a <em>lot</em> of money. So is $34,000. (It worked if "lot" is    emphasized.)  - Shoes ($20) and socks ($5).@@ -590,7 +589,7 @@  Greater-than: <verbatim>></verbatim> -Hash: #+Hash: <verbatim>#</verbatim>  Period: . @@ -673,8 +672,7 @@ Blockquoted: [[http://example.com/]] </quote> -Auto-links should not occur here:-<code><verbatim><http://example.com/></verbatim></code>+Auto-links should not occur here: <code><http://example.com/></code>  <example> or here: <http://example.com/>@@ -722,9 +720,8 @@     indent the first line of each block.  [3] This is <em>easier</em> to type. Inline notes may contain-    [[http://google.com][links]] and <code><verbatim>]</verbatim></code>-    verbatim characters, as well as <verbatim>[bracketed</verbatim>-    <verbatim>text].</verbatim>+    [[http://google.com][links]] and <code>]</code> verbatim characters, as+    well as <verbatim>[bracketed</verbatim> <verbatim>text].</verbatim>  [4] In quote.