diff options
31 files changed, 587 insertions, 230 deletions
diff --git a/.travis.yml b/.travis.yml index 17aa118a8..e014576dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,6 +47,10 @@ matrix: compiler: ": #GHC 8.2.1" addons: {apt: {packages: [cabal-install-1.24,ghc-8.2.1,happy-1.19.5], sources: [hvr-ghc]}} + - env: BUILD=cabal GHCVER=8.2.1 CABALVER=2.0 OPTS="-O0 -Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror" FLAGS="fast embed_data_files" + compiler: ": #GHC 8.2.1" + addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.1,happy-1.19.5], sources: [hvr-ghc]}} + # Build with the newest GHC and cabal-install. This is an accepted failure, # see below. # - env: BUILD=cabal GHCVER=head CABALVER=head @@ -105,7 +109,7 @@ install: case "$BUILD" in stack) ulimit -n 4096 - stack --no-terminal --install-ghc $ARGS test --flag 'aeson:fast' --only-dependencies --fast --flag pandoc:embed_data_files --test + stack --no-terminal --install-ghc $ARGS build --only-dependencies --fast --flag 'pandoc:embed_data_files' --flag 'aeson:fast' ;; cabal) cabal --version diff --git a/INSTALL.md b/INSTALL.md index e0f7eb344..bbe16fbe3 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -19,7 +19,7 @@ copy /y "%TEMP%\pandoc\pandoc-citeproc.exe" C:\Utils\Console\ rmdir /s /q "%TEMP%\pandoc\" -## MacOS +## macOS - There is a package installer at pandoc's [download page]. If you later want to uninstall the package, you can do so @@ -27,12 +27,12 @@ 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 + 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 ../pandoc-1.19.1-osx.pkg + xar -x ../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 @@ -180,7 +180,7 @@ The easiest way to build pandoc from source is to use [stack]: Note that this requires the `text-icu` library, which in turn depends on the C library `icu4c`. Installation directions - vary by platform. Here is how it might work on MacOS with homebrew: + vary by platform. Here is how it might work on macOS with homebrew: brew install icu4c cabal install --extra-lib-dirs=/usr/local/Cellar/icu4c/51.1/lib \ diff --git a/MANUAL.txt b/MANUAL.txt index 7e0bdfcdd..7f22023e7 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -336,7 +336,7 @@ General options : Specify the user data directory to search for pandoc data files. If this option is not specified, the default user data directory - will be used. This is, in Unix: + will be used. This is, in UNIX: $HOME/.pandoc @@ -608,7 +608,7 @@ General writer options `--eol=crlf`|`lf`|`native` : Manually specify line endings: `crlf` (Windows), `lf` - (MacOS/linux/unix), or `native` (line endings appropriate + (macOS/Linux/UNIX), or `native` (line endings appropriate to the OS on which pandoc is being run). The default is `native`. @@ -706,8 +706,8 @@ General writer options `--resource-path=`*SEARCHPATH* : List of paths to search for images and other resources. - The paths should be separated by `:` on linux, unix, and - MacOS systems, and by `;` on Windows. If `--resource-path` + The paths should be separated by `:` on Linux, UNIX, and + macOS systems, and by `;` on Windows. If `--resource-path` is not specified, the default resource path is the working directory. Note that, if `--resource-path` is specified, the working directory must be explicitly listed or it @@ -2518,6 +2518,18 @@ For headerless tables, the colons go on the top line instead: | Right | Left | Centered | +---------------+---------------+--------------------+ +##### Grid Table Limitations ##### + +Pandoc does not support grid tables with row spans or column spans. +This means that neither variable numbers of columns across rows nor +variable numbers of rows across columns are supported by Pandoc. +All grid tables must have the same number of columns in each row, +and the same number of rows in each column. For example, the +Docutils [sample grid tables] will not render as expected with +Pandoc. + +[sample grid tables]: http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#grid-tables + #### Extension: `pipe_tables` #### diff --git a/RELEASE-CHECKLIST b/RELEASE-CHECKLIST index b566cc4d8..07d8da4d9 100644 --- a/RELEASE-CHECKLIST +++ b/RELEASE-CHECKLIST @@ -1,4 +1,4 @@ -_ Test, on linux, windows, mac (inc. website demos) +_ Test, on Linux, Windows, macOS (inc. website demos) _ Finalize changelog git log --pretty='format:%n%n* %s (%an)%n%b%n%h%n' --reverse --name-only 1.17.0.3..HEAD > LOG @@ -12,7 +12,7 @@ _ Push templates: _ Generate Windows package (make winpkg) -_ Generate MacOS package (make macospkg) +_ Generate macOS package (make macospkg) _ Generate Ubuntu/Debian deb package (make debpkg) diff --git a/RELEASE-CHECKLIST.md b/RELEASE-CHECKLIST.md index d3fd70f23..07fbcb8bb 100644 --- a/RELEASE-CHECKLIST.md +++ b/RELEASE-CHECKLIST.md @@ -1,4 +1,4 @@ -- [ ] Test, on linux, windows, mac (inc. website demos) +- [ ] Test, on Linux, Windows, macOS (inc. website demos) - [ ] Finalize changelog: `git log --pretty='format:%n%n* %s (%an)%n%b%n%h%n' --reverse --name-only 1.17.0.3..HEAD > LOG` @@ -11,7 +11,7 @@ - [ ] Generate Windows package (`make winpkg`) -- [ ] Generate Mac OSX package (`make osxpkg`) +- [ ] Generate macOS package (`make macospkg`) - [ ] Generate Ubuntu/Debian deb package (`make debpkg`) diff --git a/data/templates/default.latex b/data/templates/default.latex index d86e62573..357549d98 100644 --- a/data/templates/default.latex +++ b/data/templates/default.latex @@ -64,8 +64,21 @@ $else$ $endif$ $endif$ $if(CJKmainfont)$ + \ifxetex \usepackage{xeCJK} \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} + \fi +$endif$ +$if(luatexjapresetoptions)$ + \ifluatex + \usepackage[$for(luatexjapresetoptions)$$luatexjapresetoptions$$sep$,$endfor$]{luatexja-preset} + \fi +$endif$ +$if(CJKmainfont)$ + \ifluatex + \usepackage[$for(luatexjafontspecoptions)$$luatexjafontspecoptions$$sep$,$endfor$]{luatexja-fontspec} + \setmainjfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} + \fi $endif$ \fi % use upquote if available, for straight quotes in verbatim environments diff --git a/linux/Dockerfile b/linux/Dockerfile index b725bbaa5..f75db2c89 100644 --- a/linux/Dockerfile +++ b/linux/Dockerfile @@ -5,7 +5,7 @@ ADD https://raw.githubusercontent.com/mitchty/alpine-ghc/master/mitch.tishmack%4 /etc/apk/keys/mitch.tishmack@gmail.com-55881c97.rsa.pub RUN apk update RUN apk add alpine-sdk git ca-certificates ghc cabal stack zlib-dev \ - dpkg fakeroot sed gawk grep + dpkg fakeroot sed gawk grep bash linux-headers RUN stack update RUN stack config set system-ghc --global true RUN mkdir -p /etc/stack @@ -16,13 +16,15 @@ RUN git clone https://github.com/jgm/pandoc WORKDIR /usr/src/pandoc RUN stack install --stack-yaml stack.pkg.yaml --only-dependencies \ --flag 'pandoc:embed_data_files' \ - --test --ghc-options '-O2 -optc-Os -optl-static -fPIC' \ + --ghc-options '-O2 -optc-Os -optl=-pthread -optl=-static -fPIC' \ pandoc pandoc-citeproc CMD git pull && \ git checkout -b work $TREE && \ stack install --stack-yaml stack.pkg.yaml \ - --local-bin-path /artifacts --flag 'pandoc:embed_data_files' \ - --test --ghc-options '-O2 -optc-Os -optl-static -fPIC' \ + --flag 'pandoc:static' \ + --flag 'pandoc:embed_data_files' \ + --ghc-options '-O2 -optc-Os -optl=-pthread -optl=-static -fPIC' \ + --local-bin-path /artifacts \ pandoc pandoc-citeproc && \ bash linux/make_deb.sh && \ bash linux/make_tarball.sh diff --git a/macos/make_macos_package.sh b/macos/make_macos_package.sh index f5262e1d5..5b66afd25 100755 --- a/macos/make_macos_package.sh +++ b/macos/make_macos_package.sh @@ -59,15 +59,15 @@ $PANDOC --data data -t html5 -s COPYING.md -Vpagetitle="License" -o $RESOURCES/l # make sure it's valid... returns nonzero exit code if it isn't: #spctl --assess --type execute $DEST/bin/pandoc -echo Creating MacOS package... +echo Creating macOS package... sed -e "s/PANDOCVERSION/$VERSION/" $MACOS/distribution.xml.in > $MACOS/distribution.xml pkgbuild --root $ROOT --identifier net.johnmacfarlane.pandoc --version $VERSION --ownership recommended $DIST/pandoc.pkg -productbuild --distribution $MACOS/distribution.xml --resources $DIST/Resources --package-path $DIST --version $VERSION --sign "${DEVELOPER_ID_INSTALLER}" $BASE-MacOS.pkg +productbuild --distribution $MACOS/distribution.xml --resources $DIST/Resources --package-path $DIST --version $VERSION --sign "${DEVELOPER_ID_INSTALLER}" $BASE-macOS.pkg # verify signature -spctl --assess --type install $BASE-MacOS.pkg +spctl --assess --type install $BASE-macOS.pkg # cleanup rm -r $DIST diff --git a/macos/uninstall-pandoc.pl b/macos/uninstall-pandoc.pl index a5194d9bd..c853727d9 100755 --- a/macos/uninstall-pandoc.pl +++ b/macos/uninstall-pandoc.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -# Script to remove all files installed by the OSX pandoc installer +# Script to remove all files installed by the macOS pandoc installer # and unregister the package. Modified from a script contributed # by Daniel T. Staal. diff --git a/man/pandoc.1 b/man/pandoc.1 index 574fc3b8e..6f870d784 100644 --- a/man/pandoc.1 +++ b/man/pandoc.1 @@ -304,7 +304,7 @@ If \f[I]FILE\f[] is \f[C]\-\f[], output will go to \f[I]stdout\f[]. Specify the user data directory to search for pandoc data files. If this option is not specified, the default user data directory will be used. -This is, in Unix: +This is, in UNIX: .RS .IP .nf @@ -638,7 +638,7 @@ Files in the user data directory are ignored. .TP .B \f[C]\-\-eol=crlf\f[]|\f[C]lf\f[]|\f[C]native\f[] Manually specify line endings: \f[C]crlf\f[] (Windows), \f[C]lf\f[] -(MacOS/linux/unix), or \f[C]native\f[] (line endings appropriate to the +(macOS/Linux/UNIX), or \f[C]native\f[] (line endings appropriate to the OS on which pandoc is being run). The default is \f[C]native\f[]. .RS @@ -760,7 +760,7 @@ Implies \f[C]\-\-standalone\f[]. .TP .B \f[C]\-\-resource\-path=\f[]\f[I]SEARCHPATH\f[] List of paths to search for images and other resources. -The paths should be separated by \f[C]:\f[] on linux, unix, and MacOS +The paths should be separated by \f[C]:\f[] on Linux, UNIX, and macOS systems, and by \f[C];\f[] on Windows. If \f[C]\-\-resource\-path\f[] is not specified, the default resource path is the working directory. diff --git a/pandoc.cabal b/pandoc.cabal index 0907ed82f..2f932e0a8 100644 --- a/pandoc.cabal +++ b/pandoc.cabal @@ -1,19 +1,19 @@ -Name: pandoc -Version: 2.0 -Cabal-Version: >= 1.10 -Build-Type: Custom -License: GPL -License-File: COPYING.md -Copyright: (c) 2006-2017 John MacFarlane -Author: John MacFarlane <jgm@berkeley.edu> -Maintainer: John MacFarlane <jgm@berkeley.edu> -Bug-Reports: https://github.com/jgm/pandoc/issues -Stability: alpha -Homepage: http://pandoc.org -Category: Text -Tested-With: GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2 -Synopsis: Conversion between markup formats -Description: Pandoc is a Haskell library for converting from one markup +name: pandoc +version: 2.0 +cabal-version: >= 1.10 +build-type: Custom +license: GPL +license-file: COPYING.md +copyright: (c) 2006-2017 John MacFarlane +author: John MacFarlane <jgm@berkeley.edu> +maintainer: John MacFarlane <jgm@berkeley.edu> +bug-reports: https://github.com/jgm/pandoc/issues +stability: alpha +homepage: http://pandoc.org +category: Text +tested-with: GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.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 this library. It can read several dialects of Markdown and (subsets of) HTML, reStructuredText, LaTeX, DocBook, @@ -35,7 +35,7 @@ Description: Pandoc is a Haskell library for converting from one markup which convert this native representation into a target format. Thus, adding an input or output format requires only adding a reader or writer. -Data-Files: +data-files: -- templates data/templates/default.html4 data/templates/default.html5 @@ -119,7 +119,7 @@ Data-Files: data/jats.csl -- documentation MANUAL.txt, COPYRIGHT -Extra-Source-Files: +extra-source-files: -- documentation INSTALL.md, BUGS, README.md, CONTRIBUTING.md, changelog man/pandoc.1 @@ -138,6 +138,7 @@ Extra-Source-Files: test/*.native test/command/*.md test/command/3533-rst-csv-tables.csv + test/command/3880.txt test/command/abbrevs test/command/SVG_logo-without-xml-declaration.svg test/command/SVG_logo.svg @@ -260,32 +261,39 @@ Extra-Source-Files: test/odt/markdown/*.md test/odt/native/*.native test/lua/*.lua -Source-repository head +source-repository head type: git location: git://github.com/jgm/pandoc.git -Flag embed_data_files +flag static + Description: Use static linking for pandoc executable. + Default: False + +flag embed_data_files Description: Embed data files in binary for relocatable executable. Default: False -Flag trypandoc +flag trypandoc Description: Build trypandoc cgi executable. Default: False -Flag weigh-pandoc +flag weigh-pandoc Description: Build weigh-pandoc to measure memory usage. Default: False -Flag network-uri +flag network-uri Description: Get Network.URI from the network-uri package Default: True -Flag old-locale +flag old-locale Description: Use old-locale and time < 1.5 Default: False -Library - Build-Depends: base >= 4.7 && < 5, +custom-setup + setup-depends: base, Cabal + +library + build-depends: base >= 4.7 && < 5, syb >= 0.1 && < 0.8, containers >= 0.4.2.1 && < 0.6, unordered-containers >= 0.2 && < 0.3, @@ -331,37 +339,37 @@ Library http-types >= 0.8 && < 0.10, csv-conduit >= 0.6 && < 0.7 if os(windows) - Cpp-options: -D_WINDOWS + cpp-options: -D_WINDOWS else - Build-Depends: unix >= 2.4 && < 2.8 + build-depends: unix >= 2.4 && < 2.8 if flag(old-locale) - Build-Depends: old-locale >= 1 && < 1.1, + build-depends: old-locale >= 1 && < 1.1, time >= 1.2 && < 1.5 else - Build-Depends: time >= 1.5 && < 1.9 + build-depends: time >= 1.5 && < 1.9 if flag(network-uri) - Build-Depends: network-uri >= 2.6 && < 2.7, network >= 2.6 + build-depends: network-uri >= 2.6 && < 2.7, network >= 2.6 else - Build-Depends: network >= 2 && < 2.6 + build-depends: network >= 2 && < 2.6 if flag(embed_data_files) cpp-options: -DEMBED_DATA_FILES build-depends: file-embed >= 0.0 && < 0.1 other-modules: Text.Pandoc.Data if os(windows) - Cpp-options: -D_WINDOWS - Ghc-Options: -Wall -fno-warn-unused-do-bind - Ghc-Prof-Options: -fprof-auto-exported - Default-Language: Haskell98 - Other-Extensions: PatternGuards, OverloadedStrings, + cpp-options: -D_WINDOWS + ghc-options: -Wall -fno-warn-unused-do-bind + ghc-prof-options: -fprof-auto-exported + default-language: Haskell98 + other-extensions: PatternGuards, OverloadedStrings, ScopedTypeVariables, GeneralizedNewtypeDeriving, RelaxedPolyRec, DeriveDataTypeable, TypeSynonymInstances, FlexibleInstances - Hs-Source-Dirs: src + hs-source-dirs: src if impl(ghc < 7.10) - Hs-Source-Dirs: prelude - Other-Modules: Prelude + hs-source-dirs: prelude + other-modules: Prelude - Exposed-Modules: Text.Pandoc, + exposed-modules: Text.Pandoc, Text.Pandoc.App, Text.Pandoc.Options, Text.Pandoc.Extensions, @@ -439,7 +447,7 @@ Library Text.Pandoc.Emoji, Text.Pandoc.ImageSize, Text.Pandoc.Class - Other-Modules: Text.Pandoc.Readers.Docx.Lists, + other-modules: Text.Pandoc.Readers.Docx.Lists, Text.Pandoc.Readers.Docx.Combine, Text.Pandoc.Readers.Docx.Parse, Text.Pandoc.Readers.Docx.Util, @@ -476,66 +484,67 @@ Library Text.Pandoc.Compat.Time, Paths_pandoc - Buildable: True - -Executable pandoc - Build-Depends: pandoc, base >= 4.7 && < 5 - Ghc-Options: -rtsopts -with-rtsopts=-K16m -Wall -fno-warn-unused-do-bind - Ghc-Prof-Options: -fprof-auto-exported -rtsopts -with-rtsopts=-K16m + buildable: True - Default-Language: Haskell98 - Other-Extensions: PatternGuards, OverloadedStrings, +executable pandoc + build-depends: pandoc, base >= 4.7 && < 5 + ghc-options: -rtsopts -with-rtsopts=-K16m -Wall -fno-warn-unused-do-bind + ghc-prof-options: -fprof-auto-exported -rtsopts -with-rtsopts=-K16m + if flag(static) + ld-options: -static + default-language: Haskell98 + other-extensions: PatternGuards, OverloadedStrings, ScopedTypeVariables, GeneralizedNewtypeDeriving, RelaxedPolyRec, DeriveDataTypeable, TypeSynonymInstances, FlexibleInstances - Hs-Source-Dirs: . + hs-source-dirs: . if impl(ghc < 7.10) - Hs-Source-Dirs: prelude - Other-Modules: Prelude - Main-Is: pandoc.hs - Buildable: True - Other-Modules: Paths_pandoc + hs-source-dirs: prelude + other-modules: Prelude + main-is: pandoc.hs + buildable: True + other-modules: Paths_pandoc -Executable trypandoc - Main-Is: trypandoc.hs - Hs-Source-Dirs: trypandoc +executable trypandoc + main-is: trypandoc.hs + hs-source-dirs: trypandoc if impl(ghc < 7.10) - Hs-Source-Dirs: prelude - Other-Modules: Prelude + hs-source-dirs: prelude + other-modules: Prelude default-language: Haskell2010 if flag(trypandoc) - Build-Depends: base, aeson, pandoc, + build-depends: base, aeson, pandoc, text, wai-extra, wai >= 0.3, http-types - Buildable: True + buildable: True else - Buildable: False + buildable: False -Executable weigh-pandoc - Main-Is: weigh-pandoc.hs - Hs-Source-Dirs: benchmark +executable weigh-pandoc + main-is: weigh-pandoc.hs + hs-source-dirs: benchmark if impl(ghc < 7.10) - Hs-Source-Dirs: prelude - Other-Modules: Prelude + hs-source-dirs: prelude + other-modules: Prelude if flag(weigh-pandoc) - Build-Depends: pandoc, + build-depends: pandoc, base >= 4.2 && < 5, text, weigh >= 0.0 && < 0.1, mtl >= 2.2 && < 2.3 - Buildable: True + buildable: True else - Buildable: False - Ghc-Options: -rtsopts -Wall -fno-warn-unused-do-bind - Default-Language: Haskell98 + buildable: False + ghc-options: -rtsopts -Wall -fno-warn-unused-do-bind + default-language: Haskell98 -Test-Suite test-pandoc - Type: exitcode-stdio-1.0 - Main-Is: test-pandoc.hs - Hs-Source-Dirs: test +test-suite test-pandoc + type: exitcode-stdio-1.0 + main-is: test-pandoc.hs + hs-source-dirs: test if impl(ghc < 7.10) - Hs-Source-Dirs: prelude - Other-Modules: Prelude - Build-Depends: base >= 4.2 && < 5, + hs-source-dirs: prelude + other-modules: Prelude + build-depends: base >= 4.2 && < 5, syb >= 0.1 && < 0.8, pandoc, pandoc-types >= 1.17.1 && < 1.18, @@ -557,7 +566,7 @@ Test-Suite test-pandoc executable-path >= 0.0 && < 0.1, zip-archive >= 0.2.3.4 && < 0.4, mtl >= 2.2 && < 2.3 - Other-Modules: Tests.Old + other-modules: Tests.Old Tests.Command Tests.Helpers Tests.Lua @@ -585,21 +594,21 @@ Test-Suite test-pandoc Tests.Writers.RST Tests.Writers.TEI Tests.Writers.Muse - Ghc-Options: -rtsopts -Wall -fno-warn-unused-do-bind -threaded - Default-Language: Haskell98 + ghc-options: -rtsopts -Wall -fno-warn-unused-do-bind -threaded + default-language: Haskell98 benchmark benchmark-pandoc - Type: exitcode-stdio-1.0 - Main-Is: benchmark-pandoc.hs - Hs-Source-Dirs: benchmark + type: exitcode-stdio-1.0 + main-is: benchmark-pandoc.hs + hs-source-dirs: benchmark if impl(ghc < 7.10) - Hs-Source-Dirs: prelude - Other-Modules: Prelude - Build-Depends: pandoc, + hs-source-dirs: prelude + other-modules: Prelude + build-depends: pandoc, time, bytestring, containers, base >= 4.2 && < 5, text >= 0.11 && < 1.3, syb >= 0.1 && < 0.8, criterion >= 1.0 && < 1.3 - Ghc-Options: -rtsopts -Wall -fno-warn-unused-do-bind - Default-Language: Haskell98 + ghc-options: -rtsopts -Wall -fno-warn-unused-do-bind + default-language: Haskell98 diff --git a/src/Text/Pandoc/Parsing.hs b/src/Text/Pandoc/Parsing.hs index 9ed18d4e0..2543f11f0 100644 --- a/src/Text/Pandoc/Parsing.hs +++ b/src/Text/Pandoc/Parsing.hs @@ -838,7 +838,7 @@ blankLineBlockLine = try (char '|' >> blankline) lineBlockLines :: Monad m => ParserT [Char] st m [String] lineBlockLines = try $ do lines' <- many1 (lineBlockLine <|> ((:[]) <$> blankLineBlockLine)) - skipMany1 $ blankline <|> blankLineBlockLine + skipMany $ blankline return lines' -- | Parse a table using 'headerParser', 'rowParser', diff --git a/src/Text/Pandoc/Readers/HTML.hs b/src/Text/Pandoc/Readers/HTML.hs index d85488478..2093be19c 100644 --- a/src/Text/Pandoc/Readers/HTML.hs +++ b/src/Text/Pandoc/Readers/HTML.hs @@ -58,7 +58,7 @@ import Data.Maybe ( fromMaybe, isJust, isNothing ) import Data.List.Split ( wordsBy ) import Data.List ( intercalate, isPrefixOf ) import Data.Char ( isDigit, isLetter, isAlphaNum ) -import Control.Monad ( guard, mzero, void, unless, mplus ) +import Control.Monad ( guard, mzero, void, unless, mplus, msum ) import Control.Arrow ((***)) import Control.Applicative ( (<|>) ) import Data.Monoid (First (..)) @@ -576,23 +576,23 @@ pPara = do return $ B.para contents pFigure :: PandocMonad m => TagParser m Blocks -pFigure = do +pFigure = try $ do TagOpen _ _ <- pSatisfy (matchTagOpen "figure" []) skipMany pBlank - let pImg = pOptInTag "p" pImage <* skipMany pBlank - pCapt = option mempty $ pInTags "figcaption" inline <* skipMany pBlank - pImgCapt = do - img <- pImg - cap <- pCapt - return (img, cap) - pCaptImg = do - cap <- pCapt - img <- pImg - return (img, cap) - (imgMany, caption) <- pImgCapt <|> pCaptImg + let pImg = (\x -> (Just x, Nothing)) <$> + (pOptInTag "p" pImage <* skipMany pBlank) + pCapt = (\x -> (Nothing, Just x)) <$> + (pInTags "figcaption" inline <* skipMany pBlank) + pSkip = (Nothing, Nothing) <$ pSatisfy (not . matchTagClose "figure") + res <- many (pImg <|> pCapt <|> pSkip) + let mbimg = msum $ map fst res + let mbcap = msum $ map snd res TagClose _ <- pSatisfy (matchTagClose "figure") - let (Image attr _ (url, tit)):_ = B.toList imgMany - return $ B.para $ B.imageWith attr url ("fig:" ++ tit) caption + let caption = fromMaybe mempty mbcap + case B.toList <$> mbimg of + Just [Image attr _ (url, tit)] -> + return $ B.para $ B.imageWith attr url ("fig:" ++ tit) caption + _ -> mzero pCodeBlock :: PandocMonad m => TagParser m Blocks pCodeBlock = try $ do @@ -961,7 +961,7 @@ blockHtmlTags = Set.fromList "dir", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", - "isindex", "main", "menu", "noframes", "ol", "output", "p", "pre", + "isindex", "main", "menu", "meta", "noframes", "ol", "output", "p", "pre", "section", "table", "tbody", "textarea", "thead", "tfoot", "ul", "dd", "dt", "frameset", "li", "tbody", "td", "tfoot", @@ -1048,7 +1048,7 @@ x `closes` "p" | x `elem` ["address", "article", "aside", "blockquote", "dir", "div", "dl", "fieldset", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hr", "main", "menu", "nav", "ol", "p", "pre", "section", "table", "ul"] = True -"meta" `closes` "meta" = True +_ `closes` "meta" = True "form" `closes` "form" = True "label" `closes` "label" = True "map" `closes` "map" = True diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs index 3292550b2..d0e95bd85 100644 --- a/src/Text/Pandoc/Readers/LaTeX.hs +++ b/src/Text/Pandoc/Readers/LaTeX.hs @@ -44,7 +44,7 @@ import Control.Applicative (many, optional, (<|>)) import Control.Monad import Control.Monad.Except (throwError) import Control.Monad.Trans (lift) -import Data.Char (chr, isAlphaNum, isLetter, ord, isDigit) +import Data.Char (chr, isAlphaNum, isLetter, ord, isDigit, toLower) import Data.Default import Data.Text (Text) import qualified Data.Text as T @@ -770,11 +770,13 @@ keyval = try $ do keyvals :: PandocMonad m => LP m [(String, String)] keyvals = try $ symbol '[' >> manyTill keyval (symbol ']') -accent :: (Char -> String) -> Inlines -> LP m Inlines -accent f ils = +accent :: PandocMonad m => Char -> (Char -> String) -> LP m Inlines +accent c f = try $ do + ils <- tok case toList ils of (Str (x:xs) : ys) -> return $ fromList (Str (f x ++ xs) : ys) - [] -> mzero + [Space] -> return $ str [c] + [] -> return $ str [c] _ -> return ils grave :: Char -> String @@ -961,6 +963,19 @@ hacek 'Z' = "Ž" hacek 'z' = "ž" hacek c = [c] +ogonek :: Char -> String +ogonek 'a' = "ą" +ogonek 'e' = "ę" +ogonek 'o' = "ǫ" +ogonek 'i' = "į" +ogonek 'u' = "ų" +ogonek 'A' = "Ą" +ogonek 'E' = "Ę" +ogonek 'I' = "Į" +ogonek 'O' = "Ǫ" +ogonek 'U' = "Ų" +ogonek c = [c] + breve :: Char -> String breve 'A' = "Ă" breve 'a' = "ă" @@ -1275,17 +1290,19 @@ inlineCommands = M.fromList $ , ("copyright", lit "©") , ("textasciicircum", lit "^") , ("textasciitilde", lit "~") - , ("H", try $ tok >>= accent hungarumlaut) - , ("`", option (str "`") $ try $ tok >>= accent grave) - , ("'", option (str "'") $ try $ tok >>= accent acute) - , ("^", option (str "^") $ try $ tok >>= accent circ) - , ("~", option (str "~") $ try $ tok >>= accent tilde) - , ("\"", option (str "\"") $ try $ tok >>= accent umlaut) - , (".", option (str ".") $ try $ tok >>= accent dot) - , ("=", option (str "=") $ try $ tok >>= accent macron) - , ("c", option (str "c") $ try $ tok >>= accent cedilla) - , ("v", option (str "v") $ try $ tok >>= accent hacek) - , ("u", option (str "u") $ try $ tok >>= accent breve) + , ("H", accent '\779' hungarumlaut) + , ("`", accent '`' grave) + , ("'", accent '\'' acute) + , ("^", accent '^' circ) + , ("~", accent '~' tilde) + , ("\"", accent '\776' umlaut) + , (".", accent '\775' dot) + , ("=", accent '\772' macron) + , ("c", accent '\807' cedilla) + , ("v", accent 'ˇ' hacek) + , ("u", accent '\774' breve) + , ("k", accent '\808' ogonek) + , ("textogonekcentered", accent '\808' ogonek) , ("i", lit "i") , ("\\", linebreak <$ (do inTableCell <- sInTableCell <$> getState guard $ not inTableCell @@ -1391,11 +1408,8 @@ inlineCommands = M.fromList $ <|> citation "citeauthor" AuthorInText False) , ("nocite", mempty <$ (citation "nocite" NormalCitation False >>= addMeta "nocite")) - -- hyperlink: for now, we just preserve contents. - -- we might add the actual links, but we need to avoid clashes - -- with ids produced by label. - , ("hypertarget", braced >> tok) - , ("hyperlink", braced >> tok) + , ("hyperlink", hyperlink) + , ("hypertarget", hypertargetInline) -- glossaries package , ("gls", doAcronym "short") , ("Gls", doAcronym "short") @@ -1445,8 +1459,56 @@ inlineCommands = M.fromList $ , ("toggletrue", braced >>= setToggle True) , ("togglefalse", braced >>= setToggle False) , ("iftoggle", try $ ifToggle >> inline) + -- biblatex misc + , ("RN", romanNumeralUpper) + , ("Rn", romanNumeralLower) ] +hyperlink :: PandocMonad m => LP m Inlines +hyperlink = try $ do + src <- toksToString <$> braced + lab <- tok + return $ link ('#':src) "" lab + +hypertargetBlock :: PandocMonad m => LP m Blocks +hypertargetBlock = try $ do + ref <- toksToString <$> braced + bs <- grouped block + case toList bs of + [Header 1 (ident,_,_) _] | ident == ref -> return bs + _ -> return $ divWith (ref, [], []) bs + +hypertargetInline :: PandocMonad m => LP m Inlines +hypertargetInline = try $ do + ref <- toksToString <$> braced + ils <- grouped inline + return $ spanWith (ref, [], []) ils + +romanNumeralUpper :: (PandocMonad m) => LP m Inlines +romanNumeralUpper = + str . toRomanNumeral <$> romanNumeralArg + +romanNumeralLower :: (PandocMonad m) => LP m Inlines +romanNumeralLower = + str . map toLower . toRomanNumeral <$> romanNumeralArg + +romanNumeralArg :: (PandocMonad m) => LP m Int +romanNumeralArg = spaces *> (parser <|> inBraces) + where + inBraces = do + symbol '{' + spaces + res <- parser + spaces + symbol '}' + return res + parser = do + Tok _ Word s <- satisfyTok isWordTok + let (digits, rest) = T.span isDigit s + unless (T.null rest) $ + fail "Non-digits in argument to \\Rn or \\RN" + safeRead $ T.unpack digits + newToggle :: (Monoid a, PandocMonad m) => [Tok] -> LP m a newToggle name = do updateState $ \st -> @@ -1944,7 +2006,7 @@ blockCommands = M.fromList $ , ("setdefaultlanguage", setDefaultLanguage) , ("setmainlanguage", setDefaultLanguage) -- hyperlink - , ("hypertarget", try $ braced >> grouped block) + , ("hypertarget", hypertargetBlock) -- LaTeX colors , ("textcolor", coloredBlock "color") , ("colorbox", coloredBlock "background-color") diff --git a/src/Text/Pandoc/Readers/Muse.hs b/src/Text/Pandoc/Readers/Muse.hs index 74622a639..2454057fa 100644 --- a/src/Text/Pandoc/Readers/Muse.hs +++ b/src/Text/Pandoc/Readers/Muse.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE FlexibleContexts #-} {- Copyright (C) 2017 Alexander Krotov <ilabdsf@gmail.com> @@ -32,7 +33,6 @@ TODO: - {{{ }}} syntax for <example> - Page breaks (five "*") - Headings with anchors (make it round trip with Muse writer) -- <verse> and ">" - Org tables - table.el tables - Images with attributes (floating and width) @@ -101,6 +101,9 @@ parseBlocks = do -- utility functions -- +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 @@ -180,6 +183,9 @@ blockElements = choice [ comment , centerTag , rightTag , quoteTag + , divTag + , verseTag + , lineBlock , bulletList , orderedList , definitionList @@ -193,7 +199,7 @@ comment = try $ do char ';' space many $ noneOf "\n" - void newline <|> eof + eol return mempty separator :: PandocMonad m => MuseParser m (F Blocks) @@ -201,7 +207,7 @@ separator = try $ do string "----" many $ char '-' many spaceChar - void newline <|> eof + eol return $ return B.horizontalRule header :: PandocMonad m => MuseParser m (F Blocks) @@ -211,8 +217,8 @@ header = try $ do getPosition >>= \pos -> guard (st == NullState && q == NoQuote && sourceColumn pos == 1) level <- liftM length $ many1 $ char '*' guard $ level <= 5 - skipSpaces - content <- trimInlinesF . mconcat <$> manyTill inline newline + spaceChar + content <- trimInlinesF . mconcat <$> manyTill inline eol attr <- registerHeader ("", [], []) (runF content defaultParserState) return $ B.headerWith attr level <$> content @@ -244,6 +250,30 @@ rightTag = blockTag id "right" quoteTag :: PandocMonad m => MuseParser m (F Blocks) quoteTag = withQuoteContext InDoubleQuote $ blockTag B.blockQuote "quote" +-- <div> tag is supported by Emacs Muse, but not Amusewiki 2.025 +divTag :: PandocMonad m => MuseParser m (F Blocks) +divTag = do + (attrs, content) <- parseHtmlContentWithAttrs "div" block + return $ (B.divWith attrs) <$> mconcat content + +verseLine :: PandocMonad m => MuseParser m String +verseLine = do + line <- anyLine <|> many1Till anyChar eof + let (white, rest) = span (== ' ') line + return $ replicate (length white) '\160' ++ rest + +verseLines :: PandocMonad m => MuseParser m (F Blocks) +verseLines = do + optionMaybe blankline -- Skip blankline after opening tag on separate line + lns <- many verseLine + lns' <- mapM (parseFromString' (trimInlinesF . mconcat <$> many inline)) lns + return $ B.lineBlock <$> sequence lns' + +verseTag :: PandocMonad m => MuseParser m (F Blocks) +verseTag = do + (_, content) <- htmlElement "verse" + parseFromString verseLines content + commentTag :: PandocMonad m => MuseParser m (F Blocks) commentTag = parseHtmlContent "comment" anyChar >> return mempty @@ -280,6 +310,26 @@ noteBlock = try $ do many1Till block (eof <|> () <$ lookAhead noteMarker) -- +-- Verse markup +-- + +lineVerseLine :: PandocMonad m => MuseParser m String +lineVerseLine = try $ do + char '>' + white <- many1 (char ' ' >> pure '\160') + rest <- anyLine + return $ tail white ++ rest + +blanklineVerseLine :: PandocMonad m => MuseParser m Char +blanklineVerseLine = try $ char '>' >> blankline + +lineBlock :: PandocMonad m => MuseParser m (F Blocks) +lineBlock = try $ do + lns <- many1 (pure <$> blanklineVerseLine <|> lineVerseLine) + lns' <- mapM (parseFromString' (trimInlinesF . mconcat <$> many inline)) lns + return $ B.lineBlock <$> sequence lns' + +-- -- lists -- @@ -359,8 +409,8 @@ definitionListItem = try $ do pure $ do lineContent' <- lineContent pure (B.text term, [lineContent']) where - termParser = (many1 spaceChar) >> -- Initial space as required by Amusewiki, but not Emacs Muse - (many1Till anyChar $ lookAhead (void (try (spaceChar >> string "::")) <|> void newline)) + termParser = many1 spaceChar >> -- Initial space as required by Amusewiki, but not Emacs Muse + many1Till anyChar (lookAhead (void (try (spaceChar >> string "::")) <|> void newline)) endOfInput = try $ skipMany blankline >> skipSpaces >> eof twoBlankLines = try $ blankline >> skipMany1 blankline newDefinitionListItem = try $ void termParser @@ -418,10 +468,10 @@ museAppendElement tbl element = tableCell :: PandocMonad m => MuseParser m (F Blocks) tableCell = try $ liftM B.plain . trimInlinesF . mconcat <$> manyTill inline (lookAhead cellEnd) - where cellEnd = try $ void (many1 spaceChar >> char '|') <|> void newline <|> eof + where cellEnd = try $ void (many1 spaceChar >> char '|') <|> eol tableElements :: PandocMonad m => MuseParser m [MuseTableElement] -tableElements = tableParseElement `sepEndBy1` (void newline <|> eof) +tableElements = tableParseElement `sepEndBy1` eol elementsToTable :: [MuseTableElement] -> F MuseTable elementsToTable = foldM museAppendElement emptyTable diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs index 190b065fb..daaeff2f0 100644 --- a/src/Text/Pandoc/Readers/RST.hs +++ b/src/Text/Pandoc/Readers/RST.hs @@ -219,7 +219,6 @@ block = choice [ codeBlock , directive , anchor , comment - , include , header , hrule , lineBlock -- must go before definitionList @@ -460,16 +459,16 @@ tab-width encoding -} -include :: PandocMonad m => RSTParser m Blocks -include = try $ do - string ".. include::" - skipMany spaceChar - f <- trim <$> anyLine - fields <- many $ rawFieldListItem 3 +includeDirective :: PandocMonad m + => String -> [(String, String)] -> String + -> RSTParser m Blocks +includeDirective top fields body = do + let f = trim top + guard $ not (null f) + guard $ null (trim body) -- options let (startLine :: Maybe Int) = lookup "start-line" fields >>= safeRead let (endLine :: Maybe Int) = lookup "end-line" fields >>= safeRead - guard $ not (null f) oldPos <- getPosition oldInput <- getInput containers <- stateContainers <$> getState @@ -501,7 +500,7 @@ include = try $ do Just patt -> drop 1 . dropWhile (not . (patt `isInfixOf`)) Nothing -> id) $ contentLines' - let contents' = unlines contentLines'' + let contents' = unlines contentLines'' ++ "\n" case lookup "code" fields of Just lang -> do let numberLines = lookup "number-lines" fields @@ -687,6 +686,7 @@ directive' = do $ lookup "height" fields >>= (lengthToDim . filter (not . isSpace)) case label of + "include" -> includeDirective top fields body' "table" -> tableDirective top fields body' "list-table" -> listTableDirective top fields body' "csv-table" -> csvTableDirective top fields body' diff --git a/src/Text/Pandoc/Writers/HTML.hs b/src/Text/Pandoc/Writers/HTML.hs index 9ac37a0ba..1641b991c 100644 --- a/src/Text/Pandoc/Writers/HTML.hs +++ b/src/Text/Pandoc/Writers/HTML.hs @@ -47,7 +47,7 @@ import Control.Monad.State.Strict import Data.Char (ord, toLower) import Data.Text (Text) import qualified Data.Text.Lazy as TL -import Data.List (intersperse, isPrefixOf) +import Data.List (intersperse, isPrefixOf, partition, intercalate) import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing) import Data.Monoid ((<>)) import qualified Data.Set as Set @@ -569,8 +569,15 @@ imgAttrsToHtml opts attr = do isNotDim _ = True dimensionsToAttrList :: Attr -> [(String, String)] -dimensionsToAttrList attr = (go Width) ++ (go Height) +dimensionsToAttrList attr = consolidateStyles $ go Width ++ go Height where + consolidateStyles :: [(String, String)] -> [(String, String)] + consolidateStyles xs = + case partition isStyle xs of + ([], _) -> xs + (ss, rest) -> ("style", intercalate ";" $ map snd ss) : rest + isStyle ("style", _) = True + isStyle _ = False go dir = case (dimension dir attr) of (Just (Pixel a)) -> [(show dir, show a)] (Just x) -> [("style", show dir ++ ":" ++ show x)] diff --git a/src/Text/Pandoc/Writers/Markdown.hs b/src/Text/Pandoc/Writers/Markdown.hs index 95977ce17..3dbfe3f11 100644 --- a/src/Text/Pandoc/Writers/Markdown.hs +++ b/src/Text/Pandoc/Writers/Markdown.hs @@ -787,6 +787,7 @@ blockListToMarkdown :: PandocMonad m -> MD m Doc blockListToMarkdown opts blocks = do inlist <- asks envInList + isPlain <- asks envPlain -- a) insert comment between list and indented code block, or the -- code block will be treated as a list continuation paragraph -- b) change Plain to Para unless it's followed by a RawBlock @@ -813,9 +814,11 @@ blockListToMarkdown opts blocks = do isListBlock (OrderedList _ _) = True isListBlock (DefinitionList _) = True isListBlock _ = False - commentSep = if isEnabled Ext_raw_html opts - then RawBlock "html" "<!-- -->\n" - else RawBlock "markdown" " \n" + commentSep = if isPlain + then Null + else if isEnabled Ext_raw_html opts + then RawBlock "html" "<!-- -->\n" + else RawBlock "markdown" " \n" mapM (blockToMarkdown opts) (fixBlocks blocks) >>= return . cat getKey :: Doc -> Key @@ -931,7 +934,7 @@ avoidBadWrapsInList (s:Str cs:[]) avoidBadWrapsInList (x:xs) = x : avoidBadWrapsInList xs isOrderedListMarker :: String -> Bool -isOrderedListMarker xs = (last xs `elem` ['.',')']) && +isOrderedListMarker xs = not (null xs) && (last xs `elem` ['.',')']) && isRight (runParser (anyOrderedListMarker >> eof) defaultParserState "" xs) @@ -946,11 +949,10 @@ inlineToMarkdown opts (Span attrs ils) = do contents <- inlineListToMarkdown opts ils return $ case plain of True -> contents - False | isEnabled Ext_bracketed_spans opts -> + False | attrs == nullAttr -> contents + | isEnabled Ext_bracketed_spans opts -> "[" <> contents <> "]" <> - if attrs == nullAttr - then "{}" - else linkAttributes opts attrs + linkAttributes opts attrs | isEnabled Ext_raw_html opts || isEnabled Ext_native_spans opts -> tagWithAttrs "span" attrs <> contents <> text "</span>" diff --git a/src/Text/Pandoc/Writers/Org.hs b/src/Text/Pandoc/Writers/Org.hs index 48f17c4fb..88f42acd4 100644 --- a/src/Text/Pandoc/Writers/Org.hs +++ b/src/Text/Pandoc/Writers/Org.hs @@ -129,36 +129,25 @@ blockToOrg (Div (_,classes@(cls:_),kvs) bs) | "drawer" `elem` classes = do blankline $$ contents $$ blankline $$ drawerEndTag $$ blankline -blockToOrg (Div attrs bs) = do +blockToOrg (Div (ident, classes, kv) bs) = do contents <- blockListToOrg bs + -- if one class looks like the name of a greater block then output as such: + -- The ID, if present, is added via the #+NAME keyword; other classes and + -- key-value pairs are kept as #+ATTR_HTML attributes. let isGreaterBlockClass = (`elem` ["center", "quote"]) . map toLower - return $ case attrs of - ("", [], []) -> - -- nullAttr, treat contents as if it wasn't wrapped - blankline $$ contents $$ blankline - (ident, [], []) -> - -- only an id: add id as an anchor, unwrap the rest - blankline $$ "<<" <> text ident <> ">>" $$ contents $$ blankline - (ident, classes, kv) -> - -- if one class looks like the name of a greater block then output as - -- such: The ID, if present, is added via the #+NAME keyword; other - -- classes and key-value pairs are kept as #+ATTR_HTML attributes. - let - (blockTypeCand, classes') = partition isGreaterBlockClass classes - in case blockTypeCand of - (blockType:classes'') -> - blankline $$ attrHtml (ident, classes'' <> classes', kv) $$ - "#+BEGIN_" <> text blockType $$ contents $$ - "#+END_" <> text blockType $$ blankline - _ -> - -- fallback: wrap in div tags - let - startTag = tagWithAttrs "div" attrs - endTag = text "</div>" - in blankline $$ "#+BEGIN_HTML" $$ - nest 2 startTag $$ "#+END_HTML" $$ blankline $$ - contents $$ blankline $$ "#+BEGIN_HTML" $$ - nest 2 endTag $$ "#+END_HTML" $$ blankline + (blockTypeCand, classes') = partition isGreaterBlockClass classes + return $ case blockTypeCand of + (blockType:classes'') -> + blankline $$ attrHtml (ident, classes'' <> classes', kv) $$ + "#+BEGIN_" <> text blockType $$ contents $$ + "#+END_" <> text blockType $$ blankline + _ -> + -- fallback with id: add id as an anchor if present, discard classes and + -- key-value pairs, unwrap the content. + let contents' = if not (null ident) + then "<<" <> text ident <> ">>" $$ contents + else contents + in blankline $$ contents' $$ blankline blockToOrg (Plain inlines) = inlineListToOrg inlines -- title beginning with fig: indicates that the image is a figure blockToOrg (Para [Image attr txt (src,'f':'i':'g':':':tit)]) = do @@ -173,7 +162,7 @@ blockToOrg (Para inlines) = do blockToOrg (LineBlock lns) = do let splitStanza [] = [] splitStanza xs = case break (== mempty) xs of - (l, []) -> l : [] + (l, []) -> [l] (l, _:r) -> l : splitStanza r let joinWithLinefeeds = nowrap . mconcat . intersperse cr let joinWithBlankLines = mconcat . intersperse blankline @@ -213,7 +202,7 @@ blockToOrg (Table caption' _ _ headers rows) = do caption'' <- inlineListToOrg caption' let caption = if null caption' then empty - else ("#+CAPTION: " <> caption'') + else "#+CAPTION: " <> caption'' headers' <- mapM blockListToOrg headers rawRows <- mapM (mapM blockListToOrg) rows let numChars = maximum . map offset @@ -289,8 +278,8 @@ propertiesDrawer (ident, classes, kv) = let drawerStart = text ":PROPERTIES:" drawerEnd = text ":END:" - kv' = if (classes == mempty) then kv else ("CLASS", unwords classes):kv - kv'' = if (ident == mempty) then kv' else ("CUSTOM_ID", ident):kv' + kv' = if classes == mempty then kv else ("CLASS", unwords classes):kv + kv'' = if ident == mempty then kv' else ("CUSTOM_ID", ident):kv' properties = vcat $ map kvToOrgProperty kv'' in drawerStart <> cr <> properties <> cr <> drawerEnd @@ -303,7 +292,7 @@ attrHtml :: Attr -> Doc attrHtml ("" , [] , []) = mempty attrHtml (ident, classes, kvs) = let - name = if (null ident) then mempty else "#+NAME: " <> text ident <> cr + name = if null ident then mempty else "#+NAME: " <> text ident <> cr keyword = "#+ATTR_HTML" classKv = ("class", unwords classes) kvStrings = map (\(k,v) -> ":" <> k <> " " <> v) (classKv:kvs) @@ -370,19 +359,19 @@ inlineToOrg SoftBreak = do WrapPreserve -> return cr WrapAuto -> return space WrapNone -> return space -inlineToOrg (Link _ txt (src, _)) = do +inlineToOrg (Link _ txt (src, _)) = case txt of [Str x] | escapeURI x == src -> -- autolink - do return $ "[[" <> text (orgPath x) <> "]]" + return $ "[[" <> text (orgPath x) <> "]]" _ -> do contents <- inlineListToOrg txt return $ "[[" <> text (orgPath src) <> "][" <> contents <> "]]" -inlineToOrg (Image _ _ (source, _)) = do +inlineToOrg (Image _ _ (source, _)) = return $ "[[" <> text (orgPath source) <> "]]" inlineToOrg (Note contents) = do -- add to notes in state notes <- gets stNotes modify $ \st -> st { stNotes = contents:notes } - let ref = show $ (length notes) + 1 + let ref = show $ length notes + 1 return $ "[fn:" <> text ref <> "]" orgPath :: String -> String diff --git a/stack.full.yaml b/stack.full.yaml index b331a9870..71bbbcb0f 100644 --- a/stack.full.yaml +++ b/stack.full.yaml @@ -9,7 +9,7 @@ flags: pandoc-citeproc: bibutils: true embed_data_files: true -# if you are on OSX, stack install cpphs and +# if you are on macOS, stack install cpphs and # uncomment the following three lines: ghc-options: pandoc-citeproc: '-pgmP cpphs -optP--cpp' diff --git a/stack.pkg.yaml b/stack.pkg.yaml index a5fe42d27..c93c9e920 100644 --- a/stack.pkg.yaml +++ b/stack.pkg.yaml @@ -14,7 +14,7 @@ packages: - '.' - location: git: https://github.com/jgm/pandoc-citeproc.git - commit: 71ca48b6e0044ea959d8e7882b03cceba9c7960c + commit: 5a7f26b61c8577916093851cdeb31fa9a198edcb extra-dep: false extra-deps: - hslua-0.8.0 @@ -24,4 +24,4 @@ extra-deps: - tasty-quickcheck-0.9.1 - haddock-library-1.4.3 - pandoc-types-1.17.1 -resolver: lts-9.0 +resolver: lts-9.1 diff --git a/stack.yaml b/stack.yaml index e348ce4c1..6e94971a8 100644 --- a/stack.yaml +++ b/stack.yaml @@ -14,4 +14,4 @@ extra-deps: - tasty-quickcheck-0.9.1 - haddock-library-1.4.3 - pandoc-types-1.17.1 -resolver: lts-9.0 +resolver: lts-9.1 diff --git a/test/Tests/Readers/LaTeX.hs b/test/Tests/Readers/LaTeX.hs index b07eb875a..4effe26e8 100644 --- a/test/Tests/Readers/LaTeX.hs +++ b/test/Tests/Readers/LaTeX.hs @@ -143,6 +143,29 @@ tests = [ testGroup "basic" "hello\\pfbreak*{}goodbye" =?> para (str "hello") <> horizontalRule <> para (str "goodbye") ] + , testGroup "biblatex roman numerals" + [ "upper" =: + "number \\RN{12}" =?> + para (str "number" <> space <> str "XII") + , "lower" =: + "number \\Rn{29}" =?> + para (str "number" <> space <> str "xxix") + , "leading zero" =: + "\\Rn{014}" =?> + para (str "xiv") + , "surrounding spaces" =: + "number \\Rn{ 41 }" =?> + para (str "number" <> space <> str "xli") + , "zero" =: + "\\RN{0}" =?> + para (str "") + , "space then unbraced argument" =: + "\\RN 7 ok" =?> + para (str "VII" <> space <> str "ok") + , "space before braced argument" =: + "\\Rn {13}ok" =?> + para (str "xiiiok") + ] ] baseCitation :: Citation diff --git a/test/Tests/Readers/Muse.hs b/test/Tests/Readers/Muse.hs index 8d4ad0b15..dac167a92 100644 --- a/test/Tests/Readers/Muse.hs +++ b/test/Tests/Readers/Muse.hs @@ -145,8 +145,61 @@ tests = , " with a continuation" ] =?> blockQuote (para "This is a quotation with a continuation") + , testGroup "Div" + [ "Div without id" =: + "<div>Foo bar</div>" =?> + divWith nullAttr (para "Foo bar") + , "Div with id" =: + "<div id=\"foo\">Foo bar</div>" =?> + divWith ("foo", [], []) (para "Foo bar") + ] + , "Verse" =: + T.unlines [ "> This is" + , "> First stanza" + , ">" -- Emacs produces verbatim ">" here, we follow Amusewiki + , "> And this is" + , "> Second stanza" + , ">" + , "" + , ">" + , "" + , "> Another verse" + , "> is here" + ] =?> + lineBlock [ "This is" + , "First stanza" + , "" + , "And this is" + , "\160\160Second stanza" + , "" + ] <> + lineBlock [ "" ] <> + lineBlock [ "Another verse" + , "\160\160\160is here" + ] ] , "Quote tag" =: "<quote>Hello, world</quote>" =?> blockQuote (para $ text "Hello, world") + , "Verse tag" =: + T.unlines [ "<verse>" + , "" + , "Foo bar baz" + , " One two three" + , "" + , "</verse>" + , "<verse>Foo bar</verse>" + , "<verse>" + , "Foo bar</verse>" + , "<verse>" + , " Foo</verse>" + ] =?> + lineBlock [ "" + , text "Foo bar baz" + , text "\160\160One two three" + , "" + ] <> + lineBlock [ "Foo bar" ] <> + lineBlock [ "Foo bar" ] <> + lineBlock [ "\160\160\160Foo" ] , "Center" =: "<center>Hello, world</center>" =?> para (text "Hello, world") , "Right" =: "<right>Hello, world</right>" =?> para (text "Hello, world") , testGroup "Comments" @@ -157,20 +210,21 @@ tests = ] , testGroup "Headers" [ "Part" =: - "* First level\n" =?> + "* First level" =?> header 1 "First level" , "Chapter" =: - "** Second level\n" =?> + "** Second level" =?> header 2 "Second level" , "Section" =: - "*** Third level\n" =?> + "*** Third level" =?> header 3 "Third level" , "Subsection" =: - "**** Fourth level\n" =?> + "**** Fourth level" =?> header 4 "Fourth level" , "Subsubsection" =: - "***** Fifth level\n" =?> + "***** Fifth level" =?> header 5 "Fifth level" + , "Whitespace is required after *" =: "**Not a header" =?> para "**Not a header" , "No headers in footnotes" =: T.unlines [ "Foo[1]" , "[1] * Bar" diff --git a/test/Tests/Readers/RST.hs b/test/Tests/Readers/RST.hs index 61a2673f5..928fc1a99 100644 --- a/test/Tests/Readers/RST.hs +++ b/test/Tests/Readers/RST.hs @@ -136,6 +136,19 @@ tests = [ "line block with blank line" =: para "but must stop here") , "line block with 3 lines" =: "| a\n| b\n| c" =?> lineBlock ["a", "b", "c"] + , "line blocks with blank lines" =: T.unlines + [ "|" + , "" + , "|" + , "| a" + , "| b" + , "|" + , "" + , "|" + ] =?> + lineBlock [""] <> + lineBlock ["", "a", "b", ""] <> + lineBlock [""] , "quoted literal block using >" =: "::\n\n> quoted\n> block\n\nOrdinary paragraph" =?> codeBlock "> quoted\n> block" <> para "Ordinary paragraph" , "quoted literal block using | (not a line block)" =: "::\n\n| quoted\n| block\n\nOrdinary paragraph" diff --git a/test/command/2549.md b/test/command/2549.md new file mode 100644 index 000000000..8f4aea852 --- /dev/null +++ b/test/command/2549.md @@ -0,0 +1,38 @@ +``` +% pandoc -f latex -t native +\hypertarget{foo}{% +\section{A section}\label{foo} +} +^D +[Header 1 ("foo",[],[]) [Str "A",Space,Str "section"]] +``` + +``` +% pandoc -f latex -t native +\hypertarget{bar}{% +\section{A section}\label{foo} +} +^D +[Div ("bar",[],[]) + [Header 1 ("foo",[],[]) [Str "A",Space,Str "section"]]] +``` + +``` +% pandoc -f latex -t native +Bar \hypertarget{foo}{Foo} +^D +[Para [Str "Bar",Space,Span ("foo",[],[]) [Str "Foo"]]] +``` + +``` +% pandoc -f latex -t native +\hypertarget{foo}{% +\begin{verbatim} +bar +\end{verbatim} +} +^D +[Div ("foo",[],[]) + [CodeBlock ("",[],[]) "bar"]] +``` + diff --git a/test/command/3771.md b/test/command/3771.md new file mode 100644 index 000000000..1d3a75ae1 --- /dev/null +++ b/test/command/3771.md @@ -0,0 +1,14 @@ +``` +% pandoc -f html -t org +<div class="Section1"> + Today is a nice day. +</div> +<div id="forecast"> + Tomorrow will be rainy. +</div> +^D +Today is a nice day. + +<<forecast>> +Tomorrow will be rainy. +``` diff --git a/test/command/3880.md b/test/command/3880.md new file mode 100644 index 000000000..b8edaf08f --- /dev/null +++ b/test/command/3880.md @@ -0,0 +1,6 @@ +``` +pandoc -f rst -t native +.. include:: command/3880.txt +^D +[Para [Str "hi"]] +``` diff --git a/test/command/3880.txt b/test/command/3880.txt new file mode 100644 index 000000000..45b983be3 --- /dev/null +++ b/test/command/3880.txt @@ -0,0 +1 @@ +hi diff --git a/tools/pandoc-template-mode.el b/tools/pandoc-template-mode.el new file mode 100644 index 000000000..7a6346458 --- /dev/null +++ b/tools/pandoc-template-mode.el @@ -0,0 +1,58 @@ + ;;; pandoc-template-mode.el --- Pandoc-Template major mode + +;; Copyright (C) 2017 + +;; Author: Václav Haisman +;; Keywords: extensions + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + + ;;; Commentary: + +;; + + ;;; Code: + +(defvar pandoc-template-font-lock-keywords + '(("\\(\\$\\)\\(if\\|for\\)(\\([^)]+\\))\\(\\$\\)" + (1 font-lock-preprocessor-face) + (2 font-lock-keyword-face) + (3 font-lock-variable-name-face) + (4 font-lock-preprocessor-face)) + ("\\(\\$\\)\\(endif\\|endfor\\|else\\)\\(\\$\\)" + (1 font-lock-preprocessor-face) + (2 font-lock-keyword-face) + (3 font-lock-preprocessor-face)) + ("\\(\\$\\)\\(sep\\)\\(\\$\\)" + (1 font-lock-preprocessor-face) + (2 font-lock-builtin-face) + (3 font-lock-preprocessor-face)) + ("\\(\\$\\)\\([^$]+\\)\\(\\$\\)" + (1 font-lock-preprocessor-face) + (2 font-lock-variable-name-face) + (3 font-lock-preprocessor-face)) + ) + "Keyword highlighting specification for `pandoc-template-mode'.") + + ;;;###autoload +(define-derived-mode pandoc-template-mode fundamental-mode "Pandoc-Template" + "A major mode for editing Pandoc-Template files." + :syntax-table nil + (setq-local font-lock-defaults + '(pandoc-template-font-lock-keywords))) + +(provide 'pandoc-template-mode) + ;;; pandoc-template.el ends here diff --git a/windows/Pandoc-en-us.wxl b/windows/Pandoc-en-us.wxl index 1981f24e8..f1acbb00e 100644 --- a/windows/Pandoc-en-us.wxl +++ b/windows/Pandoc-en-us.wxl @@ -9,6 +9,6 @@ [APPLICATIONFOLDER]. -You may need to restart Cmd/Powershell windows before using it.</String> +You may need to restart Cmd/Powershell Windows before using it.</String> </WixLocalization>
\ No newline at end of file |
