From 1f1a30bbf6aa6d1c1dc60ac9d97560346066d02f Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Thu, 22 Jul 2021 23:05:43 -0700 Subject: LaTeX writer: Use ulem for underline. ulem is conditionally included already when the `strikeout` variable is set, so we set this when there is underlined text, and use `\uline` instead of `\underline`. This fixes wrapping for underlined text. Closes #7351. --- data/templates/default.latex | 1 + 1 file changed, 1 insertion(+) (limited to 'data/templates') diff --git a/data/templates/default.latex b/data/templates/default.latex index d06701675..d6a6208a9 100644 --- a/data/templates/default.latex +++ b/data/templates/default.latex @@ -315,6 +315,7 @@ $if(links-as-notes)$ \DeclareRobustCommand{\href}[2]{#2\footnote{\url{#1}}} $endif$ $if(strikeout)$ +$-- also used for underline \usepackage[normalem]{ulem} % Avoid problems with \sout in headers with hyperref \pdfstringdefDisableCommands{\renewcommand{\sout}{}} -- cgit v1.2.3 From ca12e198ba4b1addf2f0e3f9990491175998a199 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Sun, 1 Aug 2021 09:45:09 -0600 Subject: RTF template: specify font family for fixed-width font f1. According to the spec, this is mandatory. --- data/templates/default.rtf | 2 +- test/writer.rtf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'data/templates') diff --git a/data/templates/default.rtf b/data/templates/default.rtf index a7f79376d..10f596518 100644 --- a/data/templates/default.rtf +++ b/data/templates/default.rtf @@ -1,4 +1,4 @@ -{\rtf1\ansi\deff0{\fonttbl{\f0 \fswiss Helvetica;}{\f1 Courier;}} +{\rtf1\ansi\deff0{\fonttbl{\f0 \fswiss Helvetica;}{\f1 \fmodern Courier;}} {\colortbl;\red255\green0\blue0;\red0\green0\blue255;} \widowctrl\hyphauto $for(header-includes)$ diff --git a/test/writer.rtf b/test/writer.rtf index 4f3751b36..46529bfc3 100644 --- a/test/writer.rtf +++ b/test/writer.rtf @@ -1,4 +1,4 @@ -{\rtf1\ansi\deff0{\fonttbl{\f0 \fswiss Helvetica;}{\f1 Courier;}} +{\rtf1\ansi\deff0{\fonttbl{\f0 \fswiss Helvetica;}{\f1 \fmodern Courier;}} {\colortbl;\red255\green0\blue0;\red0\green0\blue255;} \widowctrl\hyphauto -- cgit v1.2.3 From dd7b83ac9111b63786c1042c4849d7cea79c668b Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Thu, 9 Sep 2021 18:32:37 -0700 Subject: Use babel, not polyglossia, with xelatex. Previously polyglossia worked better with xelatex, but that is no longer the case, so we simplify the code so that babel is used with all latex engines. This involves a change to the default LaTeX template. --- MANUAL.txt | 10 +++---- data/templates/default.latex | 14 +--------- src/Text/Pandoc/Writers/LaTeX.hs | 52 +++++------------------------------ src/Text/Pandoc/Writers/LaTeX/Lang.hs | 51 +--------------------------------- src/Text/Pandoc/Writers/LaTeX/Util.hs | 12 ++++---- test/writers-lang-and-dir.latex | 43 ++++++++--------------------- 6 files changed, 31 insertions(+), 151 deletions(-) (limited to 'data/templates') diff --git a/MANUAL.txt b/MANUAL.txt index c2c46e05f..3551b2a32 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -142,11 +142,11 @@ When using LaTeX, the following packages need to be available contains images), [`hyperref`], [`xcolor`], [`ulem`], [`geometry`] (with the `geometry` variable set), [`setspace`] (with `linestretch`), and -[`babel`] (with `lang`). The use of `xelatex` or `lualatex` as +[`babel`] (with `lang`). If `CJKmainfont` is set, [`xeCJK`] +is needed. The use of `xelatex` or `lualatex` as the PDF engine requires [`fontspec`]. `lualatex` uses -[`selnolig`]. `xelatex` uses [`polyglossia`] (with `lang`), -[`xecjk`], and [`bidi`] (with the `dir` variable set). If the -`mathspec` variable is set, `xelatex` will use [`mathspec`] +[`selnolig`]. `xelatex` uses [`bidi`] (with the `dir` variable set). +If the `mathspec` variable is set, `xelatex` will use [`mathspec`] instead of [`unicode-math`]. The [`upquote`] and [`microtype`] packages are used if available, and [`csquotes`] will be used for [typography] if the `csquotes` variable or metadata field is @@ -197,7 +197,7 @@ footnotes in tables). [`weasyprint`]: https://weasyprint.org [`wkhtmltopdf`]: https://wkhtmltopdf.org [`xcolor`]: https://ctan.org/pkg/xcolor -[`xecjk`]: https://ctan.org/pkg/xecjk +[`xeCJK`]: https://ctan.org/pkg/xecjk [`xurl`]: https://ctan.org/pkg/xurl [`selnolig`]: https://ctan.org/pkg/selnolig diff --git a/data/templates/default.latex b/data/templates/default.latex index d6a6208a9..27a3fc877 100644 --- a/data/templates/default.latex +++ b/data/templates/default.latex @@ -374,22 +374,10 @@ $for(header-includes)$ $header-includes$ $endfor$ $if(lang)$ -\ifXeTeX - % Load polyglossia as late as possible: uses bidi with RTL langages (e.g. Hebrew, Arabic) - \usepackage{polyglossia} - \setmainlanguage[$for(polyglossia-lang.options)$$polyglossia-lang.options$$sep$,$endfor$]{$polyglossia-lang.name$} -$for(polyglossia-otherlangs)$ - \setotherlanguage[$for(polyglossia-otherlangs.options)$$polyglossia-otherlangs.options$$sep$,$endfor$]{$polyglossia-otherlangs.name$} -$endfor$ -\else - \usepackage[$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} +\usepackage[$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} % get rid of language-specific shorthands (see #6817): \let\LanguageShortHands\languageshorthands \def\languageshorthands#1{} -$if(babel-newcommands)$ - $babel-newcommands$ -$endif$ -\fi $endif$ \ifLuaTeX \usepackage{selnolig} % disable illegal ligatures diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs index c365aebf5..8c45c8db5 100644 --- a/src/Text/Pandoc/Writers/LaTeX.hs +++ b/src/Text/Pandoc/Writers/LaTeX.hs @@ -21,15 +21,13 @@ module Text.Pandoc.Writers.LaTeX ( ) where import Control.Monad.State.Strict import Data.Char (isDigit) -import Data.List (intersperse, nubBy, (\\)) +import Data.List (intersperse, (\\)) import Data.Maybe (catMaybes, fromMaybe, isJust, mapMaybe, isNothing) -import qualified Data.Map as M import Data.Text (Text) import qualified Data.Text as T import Network.URI (unEscapeString) -import Text.DocTemplates (FromContext(lookupContext), renderTemplate, - Val(..), Context(..)) -import Text.Collate.Lang (Lang (..), renderLang) +import Text.DocTemplates (FromContext(lookupContext), renderTemplate) +import Text.Collate.Lang (renderLang) import Text.Pandoc.Class.PandocMonad (PandocMonad, report, toLang) import Text.Pandoc.Definition import Text.Pandoc.Highlighting (formatLaTeXBlock, formatLaTeXInline, highlight, @@ -46,7 +44,7 @@ import Text.Pandoc.Writers.LaTeX.Table (tableToLaTeX) import Text.Pandoc.Writers.LaTeX.Citation (citationsToNatbib, citationsToBiblatex) import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState (..), startingState) -import Text.Pandoc.Writers.LaTeX.Lang (toPolyglossia, toBabel) +import Text.Pandoc.Writers.LaTeX.Lang (toBabel) import Text.Pandoc.Writers.LaTeX.Util (stringToLaTeX, StringContext(..), toLabel, inCmd, wrapDiv, hypertarget, labelFor, @@ -132,12 +130,6 @@ pandocToLaTeX options (Pandoc meta blocks) = do ,("tmargin","margin-top") ,("bmargin","margin-bottom") ] - let toPolyObj :: Lang -> Val Text - toPolyObj lang = MapVal $ Context $ - M.fromList [ ("name" , SimpleVal $ literal name) - , ("options" , SimpleVal $ literal opts) ] - where - (name, opts) = toPolyglossia lang mblang <- toLang $ case getLang options meta of Just l -> Just l Nothing | null docLangs -> Nothing @@ -216,36 +208,7 @@ pandocToLaTeX options (Pandoc meta blocks) = do (literal $ toBabel l)) mblang $ defField "babel-otherlangs" (map (literal . toBabel) docLangs) - $ defField "babel-newcommands" (vcat $ - map (\(poly, babel) -> literal $ - -- \textspanish and \textgalician are already used by babel - -- save them as \oritext... and let babel use that - if poly `elem` ["spanish", "galician"] - then "\\let\\oritext" <> poly <> "\\text" <> poly <> "\n" <> - "\\AddBabelHook{" <> poly <> "}{beforeextras}" <> - "{\\renewcommand{\\text" <> poly <> "}{\\oritext" - <> poly <> "}}\n" <> - "\\AddBabelHook{" <> poly <> "}{afterextras}" <> - "{\\renewcommand{\\text" <> poly <> "}[2][]{\\foreignlanguage{" - <> poly <> "}{##2}}}" - else (if poly == "latin" -- see #4161 - then "\\providecommand{\\textlatin}{}\n\\renewcommand" - else "\\newcommand") <> "{\\text" <> poly <> - "}[2][]{\\foreignlanguage{" <> babel <> "}{#2}}\n" <> - "\\newenvironment{" <> poly <> - "}[2][]{\\begin{otherlanguage}{" <> - babel <> "}}{\\end{otherlanguage}}" - ) - -- eliminate duplicates that have same polyglossia name - $ nubBy (\a b -> fst a == fst b) - -- find polyglossia and babel names of languages used in the document - $ map (\l -> (fst $ toPolyglossia l, toBabel l)) docLangs - ) - $ maybe id (defField "polyglossia-lang" . toPolyObj) mblang - $ defField "polyglossia-otherlangs" - (ListVal (map toPolyObj docLangs :: [Val Text])) - $ - defField "latex-dir-rtl" + $ defField "latex-dir-rtl" ((render Nothing <$> getField "dir" context) == Just ("rtl" :: Text)) context return $ render colwidth $ @@ -771,9 +734,8 @@ inlineToLaTeX (Span (id',classes,kvs) ils) = do kvToCmd _ = Nothing langCmds = case lang of - Just lng -> let (l, o) = toPolyglossia lng - ops = if T.null o then "" else "[" <> o <> "]" - in ["text" <> l <> ops] + Just lng -> let l = toBabel lng + in ["foreignlanguage{" <> l <> "}"] Nothing -> [] let cmds = mapMaybe classToCmd classes ++ mapMaybe kvToCmd kvs ++ langCmds contents <- inlineListToLaTeX ils diff --git a/src/Text/Pandoc/Writers/LaTeX/Lang.hs b/src/Text/Pandoc/Writers/LaTeX/Lang.hs index 0ba68b74e..f6fa8d187 100644 --- a/src/Text/Pandoc/Writers/LaTeX/Lang.hs +++ b/src/Text/Pandoc/Writers/LaTeX/Lang.hs @@ -10,61 +10,12 @@ Portability : portable -} module Text.Pandoc.Writers.LaTeX.Lang - ( toPolyglossiaEnv, - toPolyglossia, - toBabel + ( toBabel ) where import Data.Text (Text) import Text.Collate.Lang (Lang(..)) --- In environments \Arabic instead of \arabic is used -toPolyglossiaEnv :: Lang -> (Text, Text) -toPolyglossiaEnv l = - case toPolyglossia l of - ("arabic", o) -> ("Arabic", o) - x -> x - --- Takes a list of the constituents of a BCP47 language code and --- converts it to a Polyglossia (language, options) tuple --- http://mirrors.ctan.org/macros/latex/contrib/polyglossia/polyglossia.pdf -toPolyglossia :: Lang -> (Text, Text) -toPolyglossia (Lang "ar" _ (Just "DZ") _ _ _) = ("arabic", "locale=algeria") -toPolyglossia (Lang "ar" _ (Just "IQ") _ _ _) = ("arabic", "locale=mashriq") -toPolyglossia (Lang "ar" _ (Just "JO") _ _ _) = ("arabic", "locale=mashriq") -toPolyglossia (Lang "ar" _ (Just "LB") _ _ _) = ("arabic", "locale=mashriq") -toPolyglossia (Lang "ar" _ (Just "LY") _ _ _) = ("arabic", "locale=libya") -toPolyglossia (Lang "ar" _ (Just "MA") _ _ _) = ("arabic", "locale=morocco") -toPolyglossia (Lang "ar" _ (Just "MR") _ _ _) = ("arabic", "locale=mauritania") -toPolyglossia (Lang "ar" _ (Just "PS") _ _ _) = ("arabic", "locale=mashriq") -toPolyglossia (Lang "ar" _ (Just "SY") _ _ _) = ("arabic", "locale=mashriq") -toPolyglossia (Lang "ar" _ (Just "TN") _ _ _) = ("arabic", "locale=tunisia") -toPolyglossia (Lang "de" _ _ vars _ _) - | "1901" `elem` vars = ("german", "spelling=old") -toPolyglossia (Lang "de" _ (Just "AT") vars _ _) - | "1901" `elem` vars = ("german", "variant=austrian, spelling=old") -toPolyglossia (Lang "de" _ (Just "AT") _ _ _) = ("german", "variant=austrian") -toPolyglossia (Lang "de" _ (Just "CH") vars _ _) - | "1901" `elem` vars = ("german", "variant=swiss, spelling=old") -toPolyglossia (Lang "de" _ (Just "CH") _ _ _) = ("german", "variant=swiss") -toPolyglossia (Lang "de" _ _ _ _ _) = ("german", "") -toPolyglossia (Lang "dsb" _ _ _ _ _) = ("lsorbian", "") -toPolyglossia (Lang "el" _ _ vars _ _) - | "polyton" `elem` vars = ("greek", "variant=poly") -toPolyglossia (Lang "en" _ (Just "AU") _ _ _) = ("english", "variant=australian") -toPolyglossia (Lang "en" _ (Just "CA") _ _ _) = ("english", "variant=canadian") -toPolyglossia (Lang "en" _ (Just "GB") _ _ _) = ("english", "variant=british") -toPolyglossia (Lang "en" _ (Just "NZ") _ _ _) = ("english", "variant=newzealand") -toPolyglossia (Lang "en" _ (Just "UK") _ _ _) = ("english", "variant=british") -toPolyglossia (Lang "en" _ (Just "US") _ _ _) = ("english", "variant=american") -toPolyglossia (Lang "grc" _ _ _ _ _) = ("greek", "variant=ancient") -toPolyglossia (Lang "hsb" _ _ _ _ _) = ("usorbian", "") -toPolyglossia (Lang "la" _ _ vars _ _) - | "x-classic" `elem` vars = ("latin", "variant=classic") -toPolyglossia (Lang "pt" _ (Just "BR") _ _ _) = ("portuguese", "variant=brazilian") -toPolyglossia (Lang "sl" _ _ _ _ _) = ("slovenian", "") -toPolyglossia x = (commonFromBcp47 x, "") - -- Takes a list of the constituents of a BCP47 language code and -- converts it to a Babel language string. -- http://mirrors.ctan.org/macros/latex/required/babel/base/babel.pdf diff --git a/src/Text/Pandoc/Writers/LaTeX/Util.hs b/src/Text/Pandoc/Writers/LaTeX/Util.hs index c34338121..d79326e0d 100644 --- a/src/Text/Pandoc/Writers/LaTeX/Util.hs +++ b/src/Text/Pandoc/Writers/LaTeX/Util.hs @@ -26,7 +26,7 @@ import Control.Monad (when) import Text.Pandoc.Class (PandocMonad, toLang) import Text.Pandoc.Options (WriterOptions(..), isEnabled) import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState(..)) -import Text.Pandoc.Writers.LaTeX.Lang (toPolyglossiaEnv) +import Text.Pandoc.Writers.LaTeX.Lang (toBabel) import Text.Pandoc.Highlighting (toListingsLanguage) import Text.DocLayout import Text.Pandoc.Definition @@ -238,13 +238,11 @@ wrapDiv (_,classes,kvs) t = do Just "ltr" -> align "LTR" _ -> id wrapLang txt = case lang of - Just lng -> let (l, o) = toPolyglossiaEnv lng - ops = if T.null o - then "" - else brackets $ literal o - in inCmd "begin" (literal l) <> ops + Just lng -> let l = toBabel lng + in inCmd "begin" "otherlanguage" + <> (braces (literal l)) $$ blankline <> txt <> blankline - $$ inCmd "end" (literal l) + $$ inCmd "end" "otherlanguage" Nothing -> txt return $ wrapColumns . wrapColumn . wrapDir . wrapLang $ t diff --git a/test/writers-lang-and-dir.latex b/test/writers-lang-and-dir.latex index d91f77325..e7e5aa876 100644 --- a/test/writers-lang-and-dir.latex +++ b/test/writers-lang-and-dir.latex @@ -45,30 +45,10 @@ \providecommand{\tightlist}{% \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} \setcounter{secnumdepth}{-\maxdimen} % remove section numbering -\ifXeTeX - % Load polyglossia as late as possible: uses bidi with RTL langages (e.g. Hebrew, Arabic) - \usepackage{polyglossia} - \setmainlanguage[]{english} - \setotherlanguage[]{german} - \setotherlanguage[variant=british]{english} - \setotherlanguage[variant=swiss]{german} - \setotherlanguage[]{spanish} - \setotherlanguage[]{french} -\else - \usepackage[ngerman,british,nswissgerman,spanish,french,main=english]{babel} +\usepackage[ngerman,british,nswissgerman,spanish,french,main=english]{babel} % get rid of language-specific shorthands (see #6817): \let\LanguageShortHands\languageshorthands \def\languageshorthands#1{} - \newcommand{\textgerman}[2][]{\foreignlanguage{ngerman}{#2}} - \newenvironment{german}[2][]{\begin{otherlanguage}{ngerman}}{\end{otherlanguage}} - \newcommand{\textenglish}[2][]{\foreignlanguage{british}{#2}} - \newenvironment{english}[2][]{\begin{otherlanguage}{british}}{\end{otherlanguage}} - \let\oritextspanish\textspanish - \AddBabelHook{spanish}{beforeextras}{\renewcommand{\textspanish}{\oritextspanish}} - \AddBabelHook{spanish}{afterextras}{\renewcommand{\textspanish}[2][]{\foreignlanguage{spanish}{##2}}} - \newcommand{\textfrench}[2][]{\foreignlanguage{french}{#2}} - \newenvironment{french}[2][]{\begin{otherlanguage}{french}}{\end{otherlanguage}} -\fi \ifLuaTeX \usepackage{selnolig} % disable illegal ligatures \fi @@ -123,18 +103,19 @@ word-that-includesa\LR{ltrspan}right? Some text and -\begin{german} +\begin{otherlanguage}{ngerman} German div contents -\end{german} +\end{otherlanguage} and more text. -Next paragraph with a \textenglish[variant=british]{British span} and a -word-that-includesa\textgerman[variant=swiss]{Swiss German span}right? +Next paragraph with a \foreignlanguage{british}{British span} and a +word-that-includesa\foreignlanguage{nswissgerman}{Swiss German +span}right? -Some \textspanish{Spanish text}. +Some \foreignlanguage{spanish}{Spanish text}. \hypertarget{combined}{% \section{Combined}\label{combined}} @@ -142,17 +123,17 @@ Some \textspanish{Spanish text}. Some text and \begin{RTL} -\begin{french} +\begin{otherlanguage}{french} French rtl div contents -\end{french} +\end{otherlanguage} \end{RTL} and more text. -Next paragraph with a \LR{\textenglish[variant=british]{British ltr -span}} and a word-that-includesa\LR{\textgerman[variant=swiss]{Swiss -German ltr span}}right? +Next paragraph with a \LR{\foreignlanguage{british}{British ltr span}} +and a word-that-includesa\LR{\foreignlanguage{nswissgerman}{Swiss German +ltr span}}right? \end{document} -- cgit v1.2.3 From da8bcb783b1f5fc99be86617762eca42ab2db6ad Mon Sep 17 00:00:00 2001 From: hseg Date: Mon, 4 Oct 2021 02:34:59 +0300 Subject: Make babel use more idiomatic * Use `babel`'s bidi implementation * Remove global `lang` option -- it broke eg hebrew * Import babel languages individually instead of as package options -- was broken for greek, hebrew * Move `header-includes` to after `babel` setup Closes #7604 --- data/templates/default.latex | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'data/templates') diff --git a/data/templates/default.latex b/data/templates/default.latex index 27a3fc877..10377f2cd 100644 --- a/data/templates/default.latex +++ b/data/templates/default.latex @@ -4,11 +4,6 @@ $if(colorlinks)$ \PassOptionsToPackage{dvipsnames,svgnames,x11names}{xcolor} $endif$ -$if(dir)$ -$if(latex-dir-rtl)$ -\PassOptionsToPackage{RTLdocument}{bidi} -$endif$ -$endif$ $if(CJKmainfont)$ \PassOptionsToPackage{space}{xeCJK} $endif$ @@ -17,9 +12,6 @@ $endif$ $if(fontsize)$ $fontsize$, $endif$ -$if(lang)$ - $babel-lang$, -$endif$ $if(papersize)$ $papersize$paper, $endif$ @@ -370,23 +362,28 @@ $if(csl-refs)$ \newcommand{\CSLRightInline}[1]{\parbox[t]{\linewidth - \csllabelwidth}{#1}\break} \newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1} $endif$ -$for(header-includes)$ -$header-includes$ -$endfor$ $if(lang)$ -\usepackage[$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} +\ifXeTeX +\usepackage[bidi=default]{babel} +\fi +\ifLuaTeX +\usepackage[bidi=basic]{babel} +\fi +\babelprovide[main,import]{$babel-lang$} +$for(babel-otherlangs)$ +\babelprovide[import]{$babel-otherlangs$} +$endfor$ % get rid of language-specific shorthands (see #6817): \let\LanguageShortHands\languageshorthands \def\languageshorthands#1{} $endif$ +$for(header-includes)$ +$header-includes$ +$endfor$ \ifLuaTeX \usepackage{selnolig} % disable illegal ligatures \fi $if(dir)$ -\ifXeTeX - % Load bidi as late as possible as it modifies e.g. graphicx - \usepackage{bidi} -\fi \ifPDFTeX \TeXXeTstate=1 \newcommand{\RL}[1]{\beginR #1\endR} -- cgit v1.2.3 From 3f489bcb5897898d453bef549d6eba5f5d2120bf Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Sat, 16 Oct 2021 23:34:53 -0700 Subject: Ensure that babel is loaded also with pdflatex. This fixes a regression in #7604, which modernized babel usage but omitted to load babel for pdflatex, with the result that even simple documents could no longer be produced. Closes #7627. --- data/templates/default.latex | 5 ++--- test/writers-lang-and-dir.latex | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'data/templates') diff --git a/data/templates/default.latex b/data/templates/default.latex index 10377f2cd..3874813c7 100644 --- a/data/templates/default.latex +++ b/data/templates/default.latex @@ -363,11 +363,10 @@ $if(csl-refs)$ \newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1} $endif$ $if(lang)$ -\ifXeTeX -\usepackage[bidi=default]{babel} -\fi \ifLuaTeX \usepackage[bidi=basic]{babel} +\else +\usepackage[bidi=default]{babel} \fi \babelprovide[main,import]{$babel-lang$} $for(babel-otherlangs)$ diff --git a/test/writers-lang-and-dir.latex b/test/writers-lang-and-dir.latex index c8a1c0338..1f7ce262b 100644 --- a/test/writers-lang-and-dir.latex +++ b/test/writers-lang-and-dir.latex @@ -44,11 +44,10 @@ \providecommand{\tightlist}{% \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} \setcounter{secnumdepth}{-\maxdimen} % remove section numbering -\ifXeTeX -\usepackage[bidi=default]{babel} -\fi \ifLuaTeX \usepackage[bidi=basic]{babel} +\else +\usepackage[bidi=default]{babel} \fi \babelprovide[main,import]{english} \babelprovide[import]{ngerman} -- cgit v1.2.3 From fcd3384f9f058cf199f4fd10a25b6c700fd12a44 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Thu, 21 Oct 2021 08:57:00 -0700 Subject: Fix line numbers in source code with reveal.js We need "overflow: visible" for these to work, and reveal's default css disables this. So this modifies the default template to add this. Closes #7634. Thanks to @cderv for diagnosing the issue. --- data/templates/default.revealjs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'data/templates') diff --git a/data/templates/default.revealjs b/data/templates/default.revealjs index 203983522..45727e2d2 100644 --- a/data/templates/default.revealjs +++ b/data/templates/default.revealjs @@ -19,6 +19,9 @@ $endif$ $if(theme)$ -- cgit v1.2.3 From 19eb5c6d6ae5b660b309d7a9704a3352ffb3cc5f Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Fri, 5 Nov 2021 12:39:10 +0100 Subject: Add disableLayout variable in revealjs template This allows to modify it using Pandoc variable. Default value is correctly set to false by Pandoc. --- data/templates/default.revealjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'data/templates') diff --git a/data/templates/default.revealjs b/data/templates/default.revealjs index 45727e2d2..e1ca8b824 100644 --- a/data/templates/default.revealjs +++ b/data/templates/default.revealjs @@ -137,7 +137,7 @@ $endif$ // Disables the default reveal.js slide layout (scaling and centering) // so that you can use custom CSS layout - disableLayout: false, + disableLayout: $disableLayout$, // Vertical centering of slides center: $center$, -- cgit v1.2.3 From b116022de46cc3969eb91a0035e8da8f9135cbb4 Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Thu, 11 Nov 2021 09:38:07 +0100 Subject: JATS template: fix equal-contrib attribute The standard requires the value to be either `yes` or `no`, but is was set to `true` for authors who contributed equally. --- data/templates/article.jats_publishing | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'data/templates') diff --git a/data/templates/article.jats_publishing b/data/templates/article.jats_publishing index 9bedff6af..7ea53d5b3 100644 --- a/data/templates/article.jats_publishing +++ b/data/templates/article.jats_publishing @@ -86,7 +86,7 @@ $endif$ $if(author)$ $for(author)$ - + $if(author.orcid)$ $author.orcid$ $endif$ @@ -208,4 +208,3 @@ $back$ $endif$ - -- cgit v1.2.3 From fe113dd5fac4b05d74391bc47122f3d24b88b1dd Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Thu, 11 Nov 2021 09:44:49 +0100 Subject: JATS template: fix incomplete previous commit --- data/templates/article.jats_publishing | 1 + data/templates/default.jats_articleauthoring | 2 +- doc/jats.md | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'data/templates') diff --git a/data/templates/article.jats_publishing b/data/templates/article.jats_publishing index 7ea53d5b3..11902cae8 100644 --- a/data/templates/article.jats_publishing +++ b/data/templates/article.jats_publishing @@ -208,3 +208,4 @@ $back$ $endif$ + diff --git a/data/templates/default.jats_articleauthoring b/data/templates/default.jats_articleauthoring index 60b2ca559..66a4157d7 100644 --- a/data/templates/default.jats_articleauthoring +++ b/data/templates/default.jats_articleauthoring @@ -19,7 +19,7 @@ $endif$ $if(author)$ $for(author)$ - + $if(author.orcid)$ $author.orcid$ $endif$ diff --git a/doc/jats.md b/doc/jats.md index c099e0a04..bebb2536a 100644 --- a/doc/jats.md +++ b/doc/jats.md @@ -53,9 +53,9 @@ Metadata Values `equal-contrib` : boolean attribute used to mark authors who contributed equally to the work. The - [`equal-contrib`][attr:equal-contrib] attribute is added - to the author's [``] element if this is set to a - truthy value. + [`equal-contrib`][attr:equal-contrib] attribute, set to + `yes`, is added to the author's [``] element if + this is set to a truthy value. `cor-id` : identifier linking to the contributor's correspondence -- cgit v1.2.3 From 0610f16f7f684b320325b6c0b501725138d10a52 Mon Sep 17 00:00:00 2001 From: binaarinen <53334195+binaarinen@users.noreply.github.com> Date: Sun, 19 Dec 2021 21:10:41 +0100 Subject: Add a writer for Markua 0.10 (#7729) Markua is a markdown variant used by Leanpub. More information about Markua can be found at https://leanpub.com/markua/read. Adds a new exported function `writeMarkua` from T.P.Writers.Markdown. [API change] Closes #1871. Co-authored by Tim Wisotzki and Samuel Lemmenmeier. --- MANUAL.txt | 2 + data/templates/default.markua | 21 + pandoc.cabal | 2 + src/Text/Pandoc/App/FormatHeuristics.hs | 1 + src/Text/Pandoc/Extensions.hs | 2 + src/Text/Pandoc/Shared.hs | 5 + src/Text/Pandoc/Writers.hs | 2 + src/Text/Pandoc/Writers/Markdown.hs | 102 ++++- src/Text/Pandoc/Writers/Markdown/Inline.hs | 172 +++++-- src/Text/Pandoc/Writers/Markdown/Types.hs | 3 +- test/Tests/Old.hs | 1 + test/Tests/Writers/Markua.hs | 40 ++ test/tables.markua | 58 +++ test/test-pandoc.hs | 2 + test/writer.markua | 700 +++++++++++++++++++++++++++++ 15 files changed, 1043 insertions(+), 70 deletions(-) create mode 100644 data/templates/default.markua create mode 100644 test/Tests/Writers/Markua.hs create mode 100644 test/tables.markua create mode 100644 test/writer.markua (limited to 'data/templates') diff --git a/MANUAL.txt b/MANUAL.txt index fe551bbce..2e6d53ca6 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -316,6 +316,7 @@ header when requesting a document from a URL: - `markdown_mmd` ([MultiMarkdown]) - `markdown_phpextra` ([PHP Markdown Extra]) - `markdown_strict` (original unextended [Markdown]) + - `markua` ([Markua]) - `mediawiki` ([MediaWiki markup]) - `ms` ([roff ms]) - `muse` ([Muse]), @@ -502,6 +503,7 @@ header when requesting a document from a URL: [CSL JSON]: https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html [BibTeX]: https://ctan.org/pkg/bibtex [BibLaTeX]: https://ctan.org/pkg/biblatex +[Markua]: https://leanpub.com/markua/read ## Reader options {.options} diff --git a/data/templates/default.markua b/data/templates/default.markua new file mode 100644 index 000000000..9f6ca96de --- /dev/null +++ b/data/templates/default.markua @@ -0,0 +1,21 @@ +$if(titleblock)$ +$titleblock$ + +$endif$ +$for(header-includes)$ +$header-includes$ + +$endfor$ +$for(include-before)$ +$include-before$ + +$endfor$ +$if(toc)$ +$table-of-contents$ + +$endif$ +$body$ +$for(include-after)$ + +$include-after$ +$endfor$ diff --git a/pandoc.cabal b/pandoc.cabal index b09b19144..3cad5bce7 100644 --- a/pandoc.cabal +++ b/pandoc.cabal @@ -90,6 +90,7 @@ data-files: data/templates/default.epub3 data/templates/article.jats_publishing data/templates/affiliations.jats + data/templates/default.markua -- translations data/translations/*.yaml -- source files for reference.docx @@ -825,6 +826,7 @@ test-suite test-pandoc Tests.Writers.Docx Tests.Writers.RST Tests.Writers.TEI + Tests.Writers.Markua Tests.Writers.Muse Tests.Writers.FB2 Tests.Writers.Powerpoint diff --git a/src/Text/Pandoc/App/FormatHeuristics.hs b/src/Text/Pandoc/App/FormatHeuristics.hs index a2acfc6d6..e5fe7ad81 100644 --- a/src/Text/Pandoc/App/FormatHeuristics.hs +++ b/src/Text/Pandoc/App/FormatHeuristics.hs @@ -54,6 +54,7 @@ formatFromFilePath x = ".lhs" -> Just "markdown+lhs" ".ltx" -> Just "latex" ".markdown" -> Just "markdown" + ".markua" -> Just "markua" ".mkdn" -> Just "markdown" ".mkd" -> Just "markdown" ".mdwn" -> Just "markdown" diff --git a/src/Text/Pandoc/Extensions.hs b/src/Text/Pandoc/Extensions.hs index ce6a95458..33f615740 100644 --- a/src/Text/Pandoc/Extensions.hs +++ b/src/Text/Pandoc/Extensions.hs @@ -432,6 +432,8 @@ getDefaultExtensions "jats_archiving" = getDefaultExtensions "jats" getDefaultExtensions "jats_publishing" = getDefaultExtensions "jats" getDefaultExtensions "jats_articleauthoring" = getDefaultExtensions "jats" getDefaultExtensions "opml" = pandocExtensions -- affects notes +getDefaultExtensions "markua" = extensionsFromList + [] getDefaultExtensions _ = extensionsFromList [Ext_auto_identifiers] diff --git a/src/Text/Pandoc/Shared.hs b/src/Text/Pandoc/Shared.hs index eb0b4acbf..50abe6937 100644 --- a/src/Text/Pandoc/Shared.hs +++ b/src/Text/Pandoc/Shared.hs @@ -25,6 +25,7 @@ module Text.Pandoc.Shared ( ordNub, findM, -- * Text processing + inquotes, tshow, elemText, notElemText, @@ -186,6 +187,10 @@ findM p = foldr go (pure Nothing) -- Text processing -- +-- | Wrap double quotes around a Text +inquotes :: T.Text -> T.Text +inquotes txt = T.cons '\"' (T.snoc txt '\"') + tshow :: Show a => a -> T.Text tshow = T.pack . show diff --git a/src/Text/Pandoc/Writers.hs b/src/Text/Pandoc/Writers.hs index c348477c2..960b9074c 100644 --- a/src/Text/Pandoc/Writers.hs +++ b/src/Text/Pandoc/Writers.hs @@ -51,6 +51,7 @@ module Text.Pandoc.Writers , writeLaTeX , writeMan , writeMarkdown + , writeMarkua , writeMediaWiki , writeMs , writeMuse @@ -190,6 +191,7 @@ writers = [ ,("csljson" , TextWriter writeCslJson) ,("bibtex" , TextWriter writeBibTeX) ,("biblatex" , TextWriter writeBibLaTeX) + ,("markua" , TextWriter writeMarkua) ] -- | Retrieve writer, extensions based on formatSpec (format+extensions). diff --git a/src/Text/Pandoc/Writers/Markdown.hs b/src/Text/Pandoc/Writers/Markdown.hs index 022dbc24f..bb68d9fee 100644 --- a/src/Text/Pandoc/Writers/Markdown.hs +++ b/src/Text/Pandoc/Writers/Markdown.hs @@ -18,6 +18,7 @@ Markdown: module Text.Pandoc.Writers.Markdown ( writeMarkdown, writeCommonMark, + writeMarkua, writePlain) where import Control.Monad.Reader import Control.Monad.State.Strict @@ -42,7 +43,10 @@ import Text.Pandoc.Templates (renderTemplate) import Text.DocTemplates (Val(..), Context(..), FromContext(..)) import Text.Pandoc.Walk import Text.Pandoc.Writers.HTML (writeHtml5String) -import Text.Pandoc.Writers.Markdown.Inline (inlineListToMarkdown, linkAttributes, attrsToMarkdown) +import Text.Pandoc.Writers.Markdown.Inline (inlineListToMarkdown, + linkAttributes, + attrsToMarkdown, + attrsToMarkua) import Text.Pandoc.Writers.Markdown.Types (MarkdownVariant(..), WriterState(..), WriterEnv(..), @@ -77,6 +81,26 @@ writeCommonMark opts document = enableExtension Ext_intraword_underscores $ writerExtensions opts } +-- | Convert Pandoc to Markua. +writeMarkua :: PandocMonad m => WriterOptions -> Pandoc -> m Text +writeMarkua opts document = + evalMD (pandocToMarkdown opts' document) def{ envVariant = Markua } def + where + opts' = opts{ writerExtensions = + enableExtension Ext_hard_line_breaks $ + enableExtension Ext_pipe_tables $ + -- required for fancy list enumerators + enableExtension Ext_fancy_lists $ + enableExtension Ext_startnum $ + enableExtension Ext_strikeout $ + enableExtension Ext_subscript $ + enableExtension Ext_superscript $ + enableExtension Ext_definition_lists $ + enableExtension Ext_smart $ + enableExtension Ext_footnotes + mempty } + + pandocTitleBlock :: Doc Text -> [Doc Text] -> Doc Text -> Doc Text pandocTitleBlock tit auths dat = hang 2 (text "% ") tit <> cr <> @@ -327,8 +351,15 @@ blockToMarkdown' opts (Div attrs ils) = do contents <- blockListToMarkdown opts ils variant <- asks envVariant return $ - case () of - _ | isEnabled Ext_fenced_divs opts && + case () of + _ | variant == Markua -> + case () of + () | "blurb" `elem` classes' -> prefixed "B> " contents <> blankline + | "aside" `elem` classes' -> prefixed "A> " contents <> blankline + -- | necessary to enable option to create a bibliography + | (take 3 (T.unpack id')) == "ref" -> contents <> blankline + | otherwise -> contents <> blankline + | isEnabled Ext_fenced_divs opts && attrs /= nullAttr -> let attrsToMd = if variant == Commonmark then attrsToMarkdown @@ -408,6 +439,7 @@ blockToMarkdown' opts b@(RawBlock f str) = do | f `elem` ["markdown", "markdown_github", "markdown_phpextra", "markdown_mmd", "markdown_strict"] -> return $ literal str <> literal "\n" + Markua -> renderEmpty _ | isEnabled Ext_raw_attribute opts -> rawAttribBlock | f `elem` ["html", "html5", "html4"] , isEnabled Ext_markdown_attribute opts @@ -419,17 +451,19 @@ blockToMarkdown' opts b@(RawBlock f str) = do , isEnabled Ext_raw_tex opts -> return $ literal str <> literal "\n" _ -> renderEmpty -blockToMarkdown' opts HorizontalRule = - return $ blankline <> literal (T.replicate (writerColumns opts) "-") <> blankline +blockToMarkdown' opts HorizontalRule = do + variant <- asks envVariant + let indicator = case variant of + Markua -> "* * *" + _ -> T.replicate (writerColumns opts) "-" + return $ blankline <> literal indicator <> blankline blockToMarkdown' opts (Header level attr inlines) = do - -- first, if we're putting references at the end of a section, we -- put them here. blkLevel <- asks envBlockLevel refs <- if writerReferenceLocation opts == EndOfSection && blkLevel == 1 then notesAndRefs opts else return empty - variant <- asks envVariant -- we calculate the id that would be used by auto_identifiers -- so we know whether to print an explicit identifier @@ -442,7 +476,8 @@ blockToMarkdown' opts (Header level attr inlines) = do && id' == autoId -> empty (id',_,_) | isEnabled Ext_mmd_header_identifiers opts -> space <> brackets (literal id') - _ | isEnabled Ext_header_attributes opts || + _ | variant == Markua -> attrsToMarkua attr + | isEnabled Ext_header_attributes opts || isEnabled Ext_attributes opts -> space <> attrsToMarkdown attr | otherwise -> empty @@ -476,6 +511,8 @@ blockToMarkdown' opts (Header level attr inlines) = do -- ghc interprets '#' characters in column 1 as linenum specifiers. _ | variant == PlainText || isEnabled Ext_literate_haskell opts -> contents <> blankline + _ | variant == Markua -> attr' <> cr <> literal (T.replicate level "#") + <> space <> contents <> blankline _ -> literal (T.replicate level "#") <> space <> contents <> attr' <> blankline return $ refs <> hdr @@ -492,9 +529,11 @@ blockToMarkdown' opts (CodeBlock attribs str) = do backticks <> attrs <> cr <> literal str <> cr <> backticks <> blankline | isEnabled Ext_fenced_code_blocks opts -> tildes <> attrs <> cr <> literal str <> cr <> tildes <> blankline - _ -> nest (writerTabStop opts) (literal str) <> blankline + _ | variant == Markua -> blankline <> attrsToMarkua attribs <> cr <> backticks <> cr <> + literal str <> cr <> backticks <> cr <> blankline + | otherwise -> nest (writerTabStop opts) (literal str) <> blankline where - endlineLen c = maybe 3 ((+1) . maximum) $ nonEmpty $ + endlineLen c = maybe 3 ((+1) . maximum) $ nonEmpty [T.length ln | ln <- map trim (T.lines str) , T.pack [c,c,c] `T.isPrefixOf` ln @@ -581,24 +620,29 @@ blockToMarkdown' opts t@(Table _ blkCapt specs thead tbody tfoot) = do return $ nst (tbl $$ caption'') $$ blankline blockToMarkdown' opts (BulletList items) = do contents <- inList $ mapM (bulletListItemToMarkdown opts) items - return $ (if isTightList items then vcat else vsep) contents <> blankline + return $ (if isTightList items then vcat else vsep) + contents <> blankline blockToMarkdown' opts (OrderedList (start,sty,delim) items) = do variant <- asks envVariant let start' = if variant == Commonmark || isEnabled Ext_startnum opts then start else 1 let sty' = if isEnabled Ext_fancy_lists opts then sty else DefaultStyle - let delim' = if isEnabled Ext_fancy_lists opts - then delim - else if variant == Commonmark && - (delim == OneParen || delim == TwoParens) - then OneParen -- commonmark only supports one paren - else DefaultDelim + let delim' | isEnabled Ext_fancy_lists opts = + case variant of + -- Markua supports 'fancy' enumerators, but no TwoParens + Markua -> if delim == TwoParens then OneParen else delim + _ -> delim + | variant == Commonmark && --commonmark only supports one paren + (delim == OneParen || delim == TwoParens) = OneParen + | otherwise = DefaultDelim let attribs = (start', sty', delim') let markers = orderedListMarkers attribs - let markers' = map (\m -> if T.length m < 3 - then m <> T.replicate (3 - T.length m) " " - else m) markers + let markers' = case variant of + Markua -> markers + _ -> map (\m -> if T.length m < 3 + then m <> T.replicate (3 - T.length m) " " + else m) markers contents <- inList $ zipWithM (orderedListItemToMarkdown opts) markers' items return $ (if isTightList items then vcat else vsep) contents <> blankline @@ -712,10 +756,13 @@ itemEndsWithTightList bs = -- | Convert bullet list item (list of blocks) to markdown. bulletListItemToMarkdown :: PandocMonad m => WriterOptions -> [Block] -> MD m (Doc Text) bulletListItemToMarkdown opts bs = do + variant <- asks envVariant let exts = writerExtensions opts contents <- blockListToMarkdown opts $ taskListItemToAscii exts bs let sps = T.replicate (writerTabStop opts - 2) " " - let start = literal $ "- " <> sps + let start = case variant of + Markua -> literal "* " + _ -> literal $ "- " <> sps -- remove trailing blank line if item ends with a tight list let contents' = if itemEndsWithTightList bs then chomp contents <> cr @@ -725,19 +772,22 @@ bulletListItemToMarkdown opts bs = do -- | Convert ordered list item (a list of blocks) to markdown. orderedListItemToMarkdown :: PandocMonad m => WriterOptions -- ^ options - -> Text -- ^ list item marker + -> Text -- ^ list item marker -> [Block] -- ^ list item (list of blocks) -> MD m (Doc Text) orderedListItemToMarkdown opts marker bs = do let exts = writerExtensions opts contents <- blockListToMarkdown opts $ taskListItemToAscii exts bs + variant <- asks envVariant let sps = case writerTabStop opts - T.length marker of n | n > 0 -> literal $ T.replicate n " " _ -> literal " " let ind = if isEnabled Ext_four_space_rule opts then writerTabStop opts else max (writerTabStop opts) (T.length marker + 1) - let start = literal marker <> sps + let start = case variant of + Markua -> literal marker <> " " + _ -> literal marker <> sps -- remove trailing blank line if item ends with a tight list let contents' = if itemEndsWithTightList bs then chomp contents <> cr @@ -756,7 +806,10 @@ definitionListItemToMarkdown opts (label, defs) = do then do let tabStop = writerTabStop opts variant <- asks envVariant - let leader = if variant == PlainText then " " else ": " + let leader = case variant of + PlainText -> " " + Markua -> ":" + _ -> ": " let sps = case writerTabStop opts - 3 of n | n > 0 -> literal $ T.replicate n " " _ -> literal " " @@ -827,6 +880,7 @@ blockListToMarkdown opts blocks = do isListBlock _ = False commentSep | variant == PlainText = Null + | variant == Markua = Null | isEnabled Ext_raw_html opts = RawBlock "html" "\n" | otherwise = RawBlock "markdown" " \n" mconcat <$> mapM (blockToMarkdown opts) (fixBlocks blocks) diff --git a/src/Text/Pandoc/Writers/Markdown/Inline.hs b/src/Text/Pandoc/Writers/Markdown/Inline.hs index d299d31b2..0bf70e80e 100644 --- a/src/Text/Pandoc/Writers/Markdown/Inline.hs +++ b/src/Text/Pandoc/Writers/Markdown/Inline.hs @@ -13,7 +13,8 @@ module Text.Pandoc.Writers.Markdown.Inline ( inlineListToMarkdown, linkAttributes, - attrsToMarkdown + attrsToMarkdown, + attrsToMarkua ) where import Control.Monad.Reader import Control.Monad.State.Strict @@ -95,6 +96,11 @@ escapeText opts = T.pack . go' . T.unpack , isAlphaNum x -> c : '_' : x : go xs _ -> c : go cs +-- Escape the escape character, as well as formatting pairs +escapeMarkuaString :: Text -> Text +escapeMarkuaString s = foldr (uncurry T.replace) s [("--","~-~-"), + ("**","~*~*"),("//","~/~/"),("^^","~^~^"),(",,","~,~,")] + attrsToMarkdown :: Attr -> Doc Text attrsToMarkdown attribs = braces $ hsep [attribId, attribClasses, attribKeys] where attribId = case attribs of @@ -116,9 +122,56 @@ attrsToMarkdown attribs = braces $ hsep [attribId, attribClasses, attribKeys] escAttrChar '\\' = literal "\\\\" escAttrChar c = literal $ T.singleton c +attrsToMarkua:: Attr -> Doc Text +attrsToMarkua attributes + | null list = empty + | otherwise = braces $ intercalateDocText list + where attrId = case attributes of + ("",_,_) -> [] + (i,_,_) -> [literal $ "id: " <> i] + -- all non explicit (key,value) attributes besides id are getting + -- a default class key to be Markua conform + attrClasses = case attributes of + (_,[],_) -> [] + (_,classes,_) -> map (escAttr . ("class: " <>)) + classes + attrKeyValues = case attributes of + (_,_,[]) -> [] + (_,_,keyvalues) -> map ((\(k,v) -> escAttr k + <> ": " <> escAttr v) . + preprocessKeyValues) keyvalues + escAttr = mconcat . map escAttrChar . T.unpack + escAttrChar '"' = literal "\"" + escAttrChar c = literal $ T.singleton c + + list = concat [attrId, attrClasses, attrKeyValues] + + -- if attribute key is alt, caption, title then content + -- gets wrapped inside quotes + -- attribute gets removed + preprocessKeyValues :: (Text, Text) -> (Text, Text) + preprocessKeyValues (key,value) + | key == "alt" || + key == "caption" || + key == "title" = (key, inquotes value) + | otherwise = (key,value) + intercalateDocText :: [Doc Text] -> Doc Text + intercalateDocText [] = empty + intercalateDocText [x] = x + intercalateDocText (x:xs) = x <> ", " <> (intercalateDocText xs) + +-- | Add a (key, value) pair to Pandoc attr type +addKeyValueToAttr :: Attr -> (Text,Text) -> Attr +addKeyValueToAttr (ident,classes,kvs) (key,value) + | not (T.null key) && not (T.null value) = (ident, + classes, + (key,value): kvs) + | otherwise = (ident,classes,kvs) + linkAttributes :: WriterOptions -> Attr -> Doc Text linkAttributes opts attr = - if (isEnabled Ext_link_attributes opts || isEnabled Ext_attributes opts) && attr /= nullAttr + if (isEnabled Ext_link_attributes opts || + isEnabled Ext_attributes opts) && attr /= nullAttr then attrsToMarkdown attr else empty @@ -283,6 +336,7 @@ inlineToMarkdown opts (Span attrs ils) = do _ -> id $ case variant of PlainText -> contents + Markua -> "`" <> contents <> "`" <> attrsToMarkua attrs _ | attrs == nullAttr -> contents | isEnabled Ext_bracketed_spans opts -> let attrs' = if attrs /= nullAttr @@ -396,60 +450,75 @@ inlineToMarkdown opts (Quoted DoubleQuote lst) = do then "“" <> contents <> "”" else "“" <> contents <> "”" inlineToMarkdown opts (Code attr str) = do + variant <- asks envVariant let tickGroups = filter (T.any (== '`')) $ T.group str let longest = maybe 0 maximum $ nonEmpty $ map T.length tickGroups let marker = T.replicate (longest + 1) "`" let spacer = if longest == 0 then "" else " " let attrsEnabled = isEnabled Ext_inline_code_attributes opts || isEnabled Ext_attributes opts - let attrs = if attrsEnabled && attr /= nullAttr - then attrsToMarkdown attr - else empty - variant <- asks envVariant + let attrs = case variant of + Markua -> attrsToMarkua attr + _ -> if attrsEnabled && attr /= nullAttr + then attrsToMarkdown attr + else empty case variant of PlainText -> return $ literal str _ -> return $ literal (marker <> spacer <> str <> spacer <> marker) <> attrs inlineToMarkdown opts (Str str) = do variant <- asks envVariant - let str' = (if writerPreferAscii opts - then toHtml5Entities - else id) . - (if isEnabled Ext_smart opts - then unsmartify opts - else id) . - (if variant == PlainText - then id - else escapeText opts) $ str + let str' = case variant of + Markua -> escapeMarkuaString str + _ -> (if writerPreferAscii opts + then toHtml5Entities + else id) . + (if isEnabled Ext_smart opts + then unsmartify opts + else id) . + (if variant == PlainText + then id + else escapeText opts) $ str return $ literal str' -inlineToMarkdown opts (Math InlineMath str) = - case writerHTMLMathMethod opts of - WebTeX url -> inlineToMarkdown opts - (Image nullAttr [Str str] (url <> urlEncode str, str)) - _ | isEnabled Ext_tex_math_dollars opts -> - return $ "$" <> literal str <> "$" - | isEnabled Ext_tex_math_single_backslash opts -> - return $ "\\(" <> literal str <> "\\)" - | isEnabled Ext_tex_math_double_backslash opts -> - return $ "\\\\(" <> literal str <> "\\\\)" - | otherwise -> do - variant <- asks envVariant - texMathToInlines InlineMath str >>= - inlineListToMarkdown opts . - (if variant == PlainText then makeMathPlainer else id) -inlineToMarkdown opts (Math DisplayMath str) = - case writerHTMLMathMethod opts of - WebTeX url -> (\x -> blankline <> x <> blankline) `fmap` - inlineToMarkdown opts (Image nullAttr [Str str] - (url <> urlEncode str, str)) - _ | isEnabled Ext_tex_math_dollars opts -> - return $ "$$" <> literal str <> "$$" - | isEnabled Ext_tex_math_single_backslash opts -> - return $ "\\[" <> literal str <> "\\]" - | isEnabled Ext_tex_math_double_backslash opts -> - return $ "\\\\[" <> literal str <> "\\\\]" - | otherwise -> (\x -> cr <> x <> cr) `fmap` - (texMathToInlines DisplayMath str >>= inlineListToMarkdown opts) +inlineToMarkdown opts (Math InlineMath str) = do + variant <- asks envVariant + case () of + _ | variant == Markua -> return $ "`" <> literal str <> "`" <> "$" + | otherwise -> case writerHTMLMathMethod opts of + WebTeX url -> inlineToMarkdown opts + (Image nullAttr [Str str] (url <> urlEncode str, str)) + _ | isEnabled Ext_tex_math_dollars opts -> + return $ "$" <> literal str <> "$" + | isEnabled Ext_tex_math_single_backslash opts -> + return $ "\\(" <> literal str <> "\\)" + | isEnabled Ext_tex_math_double_backslash opts -> + return $ "\\\\(" <> literal str <> "\\\\)" + | otherwise -> + texMathToInlines InlineMath str >>= + inlineListToMarkdown opts . + (if variant == PlainText then makeMathPlainer else id) + +inlineToMarkdown opts (Math DisplayMath str) = do + variant <- asks envVariant + case () of + _ | variant == Markua -> do + let attributes = attrsToMarkua (addKeyValueToAttr ("",[],[]) + ("format", "latex")) + return $ blankline <> attributes <> cr <> literal "```" <> cr + <> literal str <> cr <> literal "```" <> blankline + | otherwise -> case writerHTMLMathMethod opts of + WebTeX url -> (\x -> blankline <> x <> blankline) `fmap` + inlineToMarkdown opts (Image nullAttr [Str str] + (url <> urlEncode str, str)) + _ | isEnabled Ext_tex_math_dollars opts -> + return $ "$$" <> literal str <> "$$" + | isEnabled Ext_tex_math_single_backslash opts -> + return $ "\\[" <> literal str <> "\\]" + | isEnabled Ext_tex_math_double_backslash opts -> + return $ "\\\\[" <> literal str <> "\\\\]" + | otherwise -> (\x -> cr <> x <> cr) `fmap` + (texMathToInlines DisplayMath str >>= inlineListToMarkdown opts) + inlineToMarkdown opts il@(RawInline f str) = do let tickGroups = filter (T.any (== '`')) $ T.group str let numticks = 1 + maybe 0 maximum (nonEmpty (map T.length tickGroups)) @@ -469,6 +538,7 @@ inlineToMarkdown opts il@(RawInline f str) = do | f `elem` ["markdown", "markdown_github", "markdown_phpextra", "markdown_mmd", "markdown_strict"] -> return $ literal str + Markua -> renderEmpty _ | isEnabled Ext_raw_attribute opts -> rawAttribInline | f `elem` ["html", "html5", "html4"] , isEnabled Ext_raw_html opts @@ -563,6 +633,11 @@ inlineToMarkdown opts lnk@(Link attr@(ident,classes,kvs) txt (src, tit)) = do PlainText | useAuto -> return $ literal srcSuffix | otherwise -> return linktext + Markua + | T.null tit -> return $ result <> attrsToMarkua attr + | otherwise -> return $ result <> attrsToMarkua attributes + where result = "[" <> linktext <> "](" <> (literal src) <> ")" + attributes = addKeyValueToAttr attr ("title", tit) _ | useAuto -> return $ "<" <> literal srcSuffix <> ">" | useRefLinks -> let first = "[" <> linktext <> "]" @@ -594,9 +669,16 @@ inlineToMarkdown opts img@(Image attr alternate (source, tit)) then [Str ""] else alternate linkPart <- inlineToMarkdown opts (Link attr txt (source, tit)) + alt <- inlineListToMarkdown opts alternate + let attributes | variant == Markua = attrsToMarkua $ + addKeyValueToAttr (addKeyValueToAttr attr ("title", tit)) + ("alt", render (Just (writerColumns opts)) alt) + | otherwise = empty return $ case variant of - PlainText -> "[" <> linkPart <> "]" - _ -> "!" <> linkPart + PlainText -> "[" <> linkPart <> "]" + Markua -> cr <> attributes <> cr <> literal "![](" <> + literal source <> ")" <> cr + _ -> "!" <> linkPart inlineToMarkdown opts (Note contents) = do modify (\st -> st{ stNotes = contents : stNotes st }) st <- get diff --git a/src/Text/Pandoc/Writers/Markdown/Types.hs b/src/Text/Pandoc/Writers/Markdown/Types.hs index a1d0d14e4..060446811 100644 --- a/src/Text/Pandoc/Writers/Markdown/Types.hs +++ b/src/Text/Pandoc/Writers/Markdown/Types.hs @@ -45,7 +45,8 @@ data WriterEnv = WriterEnv { envInList :: Bool } data MarkdownVariant = - PlainText + Markua + | PlainText | Commonmark | Markdown deriving (Show, Eq) diff --git a/test/Tests/Old.hs b/test/Tests/Old.hs index e03d94e85..450449946 100644 --- a/test/Tests/Old.hs +++ b/test/Tests/Old.hs @@ -228,6 +228,7 @@ tests pandocPath = , test' "reader" ["-f", "ipynb", "-t", "html"] "ipynb/rank.ipynb" "ipynb/rank.out.html" ] + , testGroup "markua" [ testGroup "writer" $ writerTests' "markua"] ] where test' = test pandocPath diff --git a/test/Tests/Writers/Markua.hs b/test/Tests/Writers/Markua.hs new file mode 100644 index 000000000..62239f3da --- /dev/null +++ b/test/Tests/Writers/Markua.hs @@ -0,0 +1,40 @@ +{-# LANGUAGE OverloadedStrings #-} +module Tests.Writers.Markua (tests) where + +import Test.Tasty +import Tests.Helpers +import Text.Pandoc +import Text.Pandoc.Arbitrary () +import Text.Pandoc.Builder + +{- + "my test" =: X =?> Y + +is shorthand for + + test html "my test" $ X =?> Y + +which is in turn shorthand for + + test html "my test" (X,Y) +-} + +infix 4 =: +(=:) :: (ToString a, ToPandoc a) + => String -> (a, String) -> TestTree +(=:) = test (purely (writeMarkua def) . toPandoc) + +tests :: [TestTree] +tests = [ testGroup "simple blurb/aside" + ["blurb" =: divWith ("",["blurb"],[]) (bulletList [para "blurb content"]) + =?> "B> * blurb content" + ,"aside" =: divWith ("",["aside"],[]) (bulletList [para "aside list"]) + =?> "A> * aside list" + ] + ,testGroup "multiclass blurb/aside" + ["blurb" =: divWith ("",["blurb", "otherclass"],[]) (bulletList [para "blurb content"]) + =?> "B> * blurb content" + ,"aside" =: divWith ("",["otherclass", "aside"],[]) (bulletList [para "aside list"]) + =?> "A> * aside list" + ] + ] diff --git a/test/tables.markua b/test/tables.markua new file mode 100644 index 000000000..b82264fd7 --- /dev/null +++ b/test/tables.markua @@ -0,0 +1,58 @@ +Simple table with caption: + +| Right | Left | Center | Default | +|------:|:-----|:------:|---------| +| 12 | 12 | 12 | 12 | +| 123 | 123 | 123 | 123 | +| 1 | 1 | 1 | 1 | + +Demonstration of simple table syntax. + +Simple table without caption: + +| Right | Left | Center | Default | +|------:|:-----|:------:|---------| +| 12 | 12 | 12 | 12 | +| 123 | 123 | 123 | 123 | +| 1 | 1 | 1 | 1 | + +Simple table indented two spaces: + +| Right | Left | Center | Default | +|------:|:-----|:------:|---------| +| 12 | 12 | 12 | 12 | +| 123 | 123 | 123 | 123 | +| 1 | 1 | 1 | 1 | + +Demonstration of simple table syntax. + +Multiline table with caption: + +| Centered Header | Left Aligned | Right Aligned | Default aligned | +|:---------------:|:-------------|--------------:|:------------------------------------------------------| +| First | row | 12.0 | Example of a row that spans multiple lines. | +| Second | row | 5.0 | Here’s another one. Note the blank line between rows. | + +Here’s the caption. It may span multiple lines. + +Multiline table without caption: + +| Centered Header | Left Aligned | Right Aligned | Default aligned | +|:---------------:|:-------------|--------------:|:------------------------------------------------------| +| First | row | 12.0 | Example of a row that spans multiple lines. | +| Second | row | 5.0 | Here’s another one. Note the blank line between rows. | + +Table without column headers: + +| | | | | +|----:|:----|:---:|----:| +| 12 | 12 | 12 | 12 | +| 123 | 123 | 123 | 123 | +| 1 | 1 | 1 | 1 | + +Multiline table without column headers: + +| | | | | +|:------:|:----|-----:|-------------------------------------------------------| +| First | row | 12.0 | Example of a row that spans multiple lines. | +| Second | row | 5.0 | Here’s another one. Note the blank line between rows. | diff --git a/test/test-pandoc.hs b/test/test-pandoc.hs index 476762aac..fcb157fb7 100644 --- a/test/test-pandoc.hs +++ b/test/test-pandoc.hs @@ -50,6 +50,7 @@ import qualified Tests.Writers.Powerpoint import qualified Tests.Writers.RST import qualified Tests.Writers.AnnotatedTable import qualified Tests.Writers.TEI +import qualified Tests.Writers.Markua import Text.Pandoc.Shared (inDirectory) tests :: FilePath -> TestTree @@ -72,6 +73,7 @@ tests pandocPath = testGroup "pandoc tests" , testGroup "Docx" Tests.Writers.Docx.tests , testGroup "RST" Tests.Writers.RST.tests , testGroup "TEI" Tests.Writers.TEI.tests + , testGroup "markua" Tests.Writers.Markua.tests , testGroup "Muse" Tests.Writers.Muse.tests , testGroup "FB2" Tests.Writers.FB2.tests , testGroup "PowerPoint" Tests.Writers.Powerpoint.tests diff --git a/test/writer.markua b/test/writer.markua new file mode 100644 index 000000000..1c5b44cc2 --- /dev/null +++ b/test/writer.markua @@ -0,0 +1,700 @@ +This is a set of tests for pandoc. Most of them are adapted from John Gruber’s +markdown test suite. + +* * * + +{id: headers} +# Headers + +{id: level-2-with-an-embedded-link} +## Level 2 with an [embedded link](/url) + +{id: level-3-with-emphasis} +### Level 3 with *emphasis* + +{id: level-4} +#### Level 4 + +{id: level-5} +##### Level 5 + +{id: level-1} +# Level 1 + +{id: level-2-with-emphasis} +## Level 2 with *emphasis* + +{id: level-3} +### Level 3 + +with no blank line + +{id: level-2} +## Level 2 + +with no blank line + +* * * + +{id: paragraphs} +# Paragraphs + +Here’s a regular paragraph. + +In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. +Because a hard-wrapped line in the middle of a paragraph looked like a list +item. + +Here’s one with a bullet. * criminey. + +There should be a hard line break +here. + +* * * + +{id: block-quotes} +# Block Quotes + +E-mail style: + +> This is a block quote. It is pretty short. + +> Code in a block quote: +> +> ``` +> sub status { +> print "working"; +> } +> ``` +> +> A list: +> +> 1. item one +> 2. item two +> +> Nested block quotes: +> +> > nested +> +> > nested + +This should not be a block quote: 2 > 1. + +And a following paragraph. + +* * * + +{id: code-blocks} +# Code Blocks + +Code: + +``` +---- (should be four hyphens) + +sub status { + print "working"; +} + +this code block is indented by one tab +``` + +And: + +``` + this code block is indented by two tabs + +These should not be escaped: \$ \\ \> \[ \{ +``` + +* * * + +{id: lists} +# Lists + +{id: unordered} +## Unordered + +Asterisks tight: + +* asterisk 1 +* asterisk 2 +* asterisk 3 + +Asterisks loose: + +* asterisk 1 + +* asterisk 2 + +* asterisk 3 + +Pluses tight: + +* Plus 1 +* Plus 2 +* Plus 3 + +Pluses loose: + +* Plus 1 + +* Plus 2 + +* Plus 3 + +Minuses tight: + +* Minus 1 +* Minus 2 +* Minus 3 + +Minuses loose: + +* Minus 1 + +* Minus 2 + +* Minus 3 + +{id: ordered} +## Ordered + +Tight: + +1. First +2. Second +3. Third + +and: + +1. One +2. Two +3. Three + +Loose using tabs: + +1. First + +2. Second + +3. Third + +and using spaces: + +1. One + +2. Two + +3. Three + +Multiple paragraphs: + +1. Item 1, graf one. + + Item 1. graf two. The quick brown fox jumped over the lazy dog’s back. + +2. Item 2. + +3. Item 3. + +{id: nested} +## Nested + +* Tab + * Tab + * Tab + +Here’s another: + +1. First +2. Second: + * Fee + * Fie + * Foe +3. Third + +Same thing but with paragraphs: + +1. First + +2. Second: + + * Fee + * Fie + * Foe + +3. Third + +{id: tabs-and-spaces} +## Tabs and spaces + +* this is a list item indented with tabs + +* this is a list item indented with spaces + + * this is an example list item indented with tabs + + * this is an example list item indented with spaces + +{id: fancy-list-markers} +## Fancy list markers + +2) begins with 2 + +3) and now 3 + + with a continuation + + iv. sublist with roman numerals, starting with 4 + v. more items + A) a subsublist + B) a subsublist + +Nesting: + +A. Upper Alpha + I. Upper Roman. + 6) Decimal start with 6 + c) Lower alpha with paren + +Autonumbering: + +1. Autonumber. +2. More. + 1. Nested. + +Should not be a list item: + +M.A. 2007 + +B. Williams + +* * * + +{id: definition-lists} +# Definition Lists + +Tight using spaces: + +apple +: red fruit + +orange +: orange fruit + +banana +: yellow fruit + +Tight using tabs: + +apple +: red fruit + +orange +: orange fruit + +banana +: yellow fruit + +Loose: + +apple + +: red fruit + +orange + +: orange fruit + +banana + +: yellow fruit + +Multiple blocks with italics: + +*apple* + +: red fruit + + contains seeds, crisp, pleasant to taste + +*orange* + +: orange fruit + + ``` + { orange code block } + ``` + + > orange block quote + +Multiple definitions, tight: + +apple +: red fruit +: computer + +orange +: orange fruit +: bank + +Multiple definitions, loose: + +apple + +: red fruit + +: computer + +orange + +: orange fruit + +: bank + +Blank line after term, indented marker, alternate markers: + +apple + +: red fruit + +: computer + +orange + +: orange fruit + + 1. sublist + 2. sublist + +{id: html-blocks} +# HTML Blocks + +Simple block on one line: + +foo + +And nested without indentation: + +foo + +bar + +Interpreted markdown in a table: + +This is *emphasized* +And this is **strong** +Here’s a simple block: + +foo + +This should be a code block, though: + +``` +
+ foo +
+``` + +As should this: + +``` +
foo
+``` + +Now, nested: + +foo + +This should just be an HTML comment: + +Multiline: + +Code block: + +``` + +``` + +Just plain comment, with trailing spaces on the line: + +Code: + +``` +
+``` + +Hr’s: + +* * * + +{id: inline-markup} +# Inline Markup + +This is *emphasized*, and so *is this*. + +This is **strong**, and so **is this**. + +An *[emphasized link](/url)*. + +***This is strong and em.*** + +So is ***this*** word. + +***This is strong and em.*** + +So is ***this*** word. + +This is code: `>`, `$`, `\`, `\$`, ``. + +~~This is *strikeout*.~~ + +Superscripts: a^bc^d a^*hello*^ a^hello there^. + +Subscripts: H~2~O, H~23~O, H~many of them~O. + +These should not be superscripts or subscripts, because of the unescaped spaces: +a^b c^d, a~b c~d. + +* * * + +{id: smart-quotes-ellipses-dashes} +# Smart quotes, ellipses, dashes + +"Hello," said the spider. "'Shelob' is my name." + +'A', 'B', and 'C' are letters. + +'Oak,' 'elm,' and 'beech' are names of trees. So is 'pine.' + +'He said, "I want to go."' Were you alive in the 70’s? + +Here is some quoted '`code`' and a "[quoted +link](http://example.com/?foo=1&bar=2)". + +Some dashes: one—two — three—four — five. + +Dashes between numbers: 5–7, 255–66, 1987–1999. + +Ellipses…and…and…. + +* * * + +{id: latex} +# LaTeX + +* +* `2+2=4`$ +* `x \in y`$ +* `\alpha \wedge \omega`$ +* `223`$ +* `p`$-Tree +* Here’s some display math: + + {format: latex} + ``` + \frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h} + ``` +* Here’s one that has a line break in it: `\alpha + \omega \times x^2`$. + +These shouldn’t be math: + +* To get the famous equation, write `$e = mc^2$`. +* $22,000 is a *lot* of money. So is $34,000. (It worked if "lot" is + emphasized.) +* Shoes ($20) and socks ($5). +* Escaped `$`: $73 *this should be emphasized* 23$. + +Here’s a LaTeX table: + +* * * + +{id: special-characters} +# Special Characters + +Here is some unicode: + +* I hat: Î +* o umlaut: ö +* section: § +* set membership: ∈ +* copyright: © + +AT&T has an ampersand in their name. + +AT&T is another way to write it. + +This & that. + +4 < 5. + +6 > 5. + +Backslash: \ + +Backtick: ` + +Asterisk: * + +Underscore: _ + +Left brace: { + +Right brace: } + +Left bracket: [ + +Right bracket: ] + +Left paren: ( + +Right paren: ) + +Greater-than: > + +Hash: # + +Period: . + +Bang: ! + +Plus: + + +Minus: - + +* * * + +{id: links} +# Links + +{id: explicit} +## Explicit + +Just a [URL](/url/). + +[URL and title](/url/){title: "title"}. + +[URL and title](/url/){title: "title preceded by two spaces"}. + +[URL and title](/url/){title: "title preceded by a tab"}. + +[URL and title](/url/){title: "title with "quotes" in it"} + +[URL and title](/url/){title: "title with single quotes"} + +[with_underscore](/url/with_underscore) + +[Email link](mailto:nobody@nowhere.net) + +[Empty](). + +{id: reference} +## Reference + +Foo [bar](/url/). + +With [embedded [brackets]](/url/). + +[b](/url/) by itself should be a link. + +Indented [once](/url). + +Indented [twice](/url). + +Indented [thrice](/url). + +This should [not][] be a link. + +``` +[not]: /url +``` + +Foo [bar](/url/){title: "Title with "quotes" inside"}. + +Foo [biz](/url/){title: "Title with "quote" inside"}. + +{id: with-ampersands} +## With ampersands + +Here’s a [link with an ampersand in the URL](http://example.com/?foo=1&bar=2). + +Here’s a link with an amersand in the link text: +[AT&T](http://att.com/){title: "AT&T"}. + +Here’s an [inline link](/script?foo=1&bar=2). + +Here’s an [inline link in pointy braces](/script?foo=1&bar=2). + +{id: autolinks} +## Autolinks + +With an ampersand: +[http:~/~/example.com/?foo=1&bar=2](http://example.com/?foo=1&bar=2){class: uri} + +* In a list? +* [http:~/~/example.com/](http://example.com/){class: uri} +* It should. + +An e-mail address: [nobody@nowhere.net](mailto:nobody@nowhere.net){class: email} + +> Blockquoted: [http:~/~/example.com/](http://example.com/){class: uri} + +Auto-links should not occur here: `` + +``` +or here: +``` + +* * * + +{id: images} +# Images + +From "Voyage dans la Lune" by Georges Melies (1902): + +{alt: "lalune", title: "Voyage dans la Lune"} +![](lalune.jpg) + +Here is a movie +{alt: "movie"} +![](movie.jpg) +icon. + +* * * + +{id: footnotes} +# Footnotes + +Here is a footnote reference,[^1] and another.[^2] This should *not* be a +footnote reference, because it contains a space.[^my note] Here is an inline +note.[^3] + +> Notes can go in quotes.[^4] + +1. And in list items.[^5] + +This paragraph should not be part of the note, as it is not indented. + +[^1]: Here is the footnote. It can go anywhere after the footnote reference. It + need not be placed at the end of the document. + +[^2]: Here’s the long note. This one contains multiple blocks. + + Subsequent blocks are indented to show that they belong to the footnote (as + with list items). + + ``` + { } + ``` + + If you want, you can indent every line, but you can also be lazy and just + indent the first line of each block. + +[^3]: This is *easier* to type. Inline notes may contain + [links](http://google.com) and `]` verbatim characters, as well as + [bracketed text]. + +[^4]: In quote. + +[^5]: In list. -- cgit v1.2.3 From 7954070b0141700e17b6bc986d134fed90de7a02 Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Wed, 22 Dec 2021 22:51:53 +0100 Subject: JATS templates: add support for article subtitles --- data/templates/article.jats_publishing | 3 +++ data/templates/default.jats_articleauthoring | 3 +++ doc/jats.md | 11 +++++++++++ 3 files changed, 17 insertions(+) (limited to 'data/templates') diff --git a/data/templates/article.jats_publishing b/data/templates/article.jats_publishing index 11902cae8..bb69404c2 100644 --- a/data/templates/article.jats_publishing +++ b/data/templates/article.jats_publishing @@ -81,6 +81,9 @@ $endif$ $if(title)$ $title$ +$if(subtitle)$ +${subtitle} +$endif$ $endif$ $if(author)$ diff --git a/data/templates/default.jats_articleauthoring b/data/templates/default.jats_articleauthoring index 66a4157d7..8cf89fa68 100644 --- a/data/templates/default.jats_articleauthoring +++ b/data/templates/default.jats_articleauthoring @@ -14,6 +14,9 @@ $endif$ $if(title)$ $title$ +$if(subtitle)$ +${subtitle} +$endif$ $endif$ $if(author)$ diff --git a/doc/jats.md b/doc/jats.md index bebb2536a..7eca75c8e 100644 --- a/doc/jats.md +++ b/doc/jats.md @@ -336,12 +336,21 @@ Metadata Values : Additional notes concerning the whole article. Added to the article's frontmatter via the [``][elem:notes] element. +`subtitle` +: Subordinate part of the document title. Added to the + document's front matter as a + [``][elem:article-title] element. + `tags` : list of keywords. Items are used as contents of the [``][elem:kwd] element; the elements are grouped in a [``][elem:kwd-group] with the [`kwd-group-type`][attr:kwd-group-type] value `author`. +`title` +: The article title. Added to the document's front matter via the + [``][elem:article-title] element. + Required Metadata ----------------- @@ -378,6 +387,7 @@ Required metadata values: [elem:abstract]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/abstract.html [elem:article-id]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/article-id.html [elem:article-meta]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/article-meta.html +[elem:article-title]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/article-title.html [elem:copyright-holder]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/copyright-holder.html [elem:copyright-statement]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/copyright-statement.html [elem:copyright-year]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/copyright-year.html @@ -400,6 +410,7 @@ Required metadata values: [elem:string-name]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/string-name.html [elem:subj-group]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/subj-group.html [elem:subject]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/subject.html +[elem:subtitle]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/subtitle.html [elem:surname]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/surname.html [elem:xref]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/xref.html -- cgit v1.2.3 From ddd1b856087b7620d9b314026a76dd53d52d65b6 Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Thu, 23 Dec 2021 08:45:39 +0100 Subject: JATS templates: fix affiliation tagging in articleauthoring output Affiliations were `xlink`ed even in the articleauthoring tag set, but `` are not allowed as children of `contrib-group` elements in that tag set. Each affiliation must be listed directly in the contrib element. --- data/templates/affiliations.jats | 42 +++++++++++++--------------- data/templates/article.jats_publishing | 12 +++++++- data/templates/default.jats_articleauthoring | 3 +- doc/jats.md | 19 ++++++++++--- 4 files changed, 47 insertions(+), 29 deletions(-) (limited to 'data/templates') diff --git a/data/templates/affiliations.jats b/data/templates/affiliations.jats index 93238d22e..2df99d75e 100644 --- a/data/templates/affiliations.jats +++ b/data/templates/affiliations.jats @@ -1,38 +1,36 @@ $-- $-- Affiliations $-- -$for(affiliation)$ $-- wrap affiliation if it has a known institution identifier -$if(affiliation.group)$ -$affiliation.group$ +$if(it.group)$ +${it.group} $endif$ -$if(affiliation.department)$ -$affiliation.department$ +$if(it.department)$ +${it.department} $endif$ -$if(affiliation.organization)$ -$affiliation.organization$ +$if(it.organization)$ +${it.organization} $else$ -$affiliation.name$ +${it.name} $endif$ -$if(affiliation.isni)$ -$affiliation.isni$ +$if(it.isni)$ +${it.isni} $endif$ -$if(affiliation.ringgold)$ -$affiliation.ringgold$ +$if(it.ringgold)$ +${it.ringgold} $endif$ -$if(affiliation.ror)$ -$affiliation.ror$ +$if(it.ror)$ +${it.ror} $endif$ -$for(affiliation.pid)$ -$affiliation.pid.id$ +$for(it.pid)$ +${it.id} $endfor$ -$if(affiliation.street-address)$, -$for(affiliation.street-address)$ -$affiliation.street-address$$sep$, +$if(it.street-address)$, +$for(it.street-address)$ +${it}$sep$, $endfor$ -$else$$if(affiliation.city)$, $affiliation.city$$endif$$endif$$if(affiliation.country)$, -$affiliation.country$$endif$ +$else$$if(it.city)$, $it.city$$endif$$endif$$if(it.country)$, +$it.country$$endif$ -$endfor$ diff --git a/data/templates/article.jats_publishing b/data/templates/article.jats_publishing index bb69404c2..47ab8f197 100644 --- a/data/templates/article.jats_publishing +++ b/data/templates/article.jats_publishing @@ -106,15 +106,25 @@ $endif$ $if(author.email)$ $author.email$ $endif$ +$-- if affiliations are listed separately, then create links. Otherwise +$-- include them here. +$if(affiliation)$ $for(author.affiliation)$ $endfor$ +$else$ +$for(author.affiliation)$ +${ it:affiliations.jats() } +$endfor$ +$endif$ $if(author.cor-id)$ * $endif$
$endfor$ -${ affiliations.jats() } +$for(affiliation)$ +${ it:affiliations.jats() } +$endfor$
$endif$ $if(article.author-notes)$ diff --git a/data/templates/default.jats_articleauthoring b/data/templates/default.jats_articleauthoring index 8cf89fa68..29abe86c5 100644 --- a/data/templates/default.jats_articleauthoring +++ b/data/templates/default.jats_articleauthoring @@ -40,14 +40,13 @@ $if(author.email)$ $author.email$ $endif$ $for(author.affiliation)$ - +${ it:affiliations.jats() } $endfor$ $if(author.cor-id)$ * $endif$
$endfor$ -${ affiliations.jats() }
$endif$ $if(copyright)$ diff --git a/doc/jats.md b/doc/jats.md index 7eca75c8e..9b8351840 100644 --- a/doc/jats.md +++ b/doc/jats.md @@ -45,10 +45,21 @@ Metadata Values element. `affiliation` - : list of affiliation identifiers; marks the organizations - with which an author is affiliated. Each identifier in this - list must also occur as the `id` of an affiliation listed in - the top-level `affiliation` list. + : either full affiliation entries as described in field + `affiliation`, or a list of affiliation identifiers. + + The identifiers link to the organizations with which an + author is affiliated. Each identifier in this list must + also occur as the `id` of an affiliation listed in the + top-level `affiliation` list. + + If the top-level `affiliation` field is set, then this + entry assumed to be a list of identifiers, and a list of + full entries if that field is unset. + + Full entries must be given if the articleauthoring tag + set it used, as affiliation links are not allowed in that + schema. `equal-contrib` : boolean attribute used to mark authors who contributed -- cgit v1.2.3 From e54f6dcd7a6367d6d6408a4a5151b703aef3c533 Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Thu, 23 Dec 2021 18:45:20 +0100 Subject: JATS template: fix position of contrib affiliations in authoring set Any `` element must come before any `` element. --- data/templates/affiliations.jats | 2 +- data/templates/default.jats_articleauthoring | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'data/templates') diff --git a/data/templates/affiliations.jats b/data/templates/affiliations.jats index 2df99d75e..17c3cf164 100644 --- a/data/templates/affiliations.jats +++ b/data/templates/affiliations.jats @@ -1,7 +1,7 @@ $-- $-- Affiliations $-- - + $-- wrap affiliation if it has a known institution identifier $if(it.group)$ ${it.group} diff --git a/data/templates/default.jats_articleauthoring b/data/templates/default.jats_articleauthoring index 29abe86c5..01042b001 100644 --- a/data/templates/default.jats_articleauthoring +++ b/data/templates/default.jats_articleauthoring @@ -36,12 +36,12 @@ $elseif(author.name)$ $else$ $author$ $endif$ -$if(author.email)$ -$author.email$ -$endif$ $for(author.affiliation)$ ${ it:affiliations.jats() } $endfor$ +$if(author.email)$ +$author.email$ +$endif$ $if(author.cor-id)$ * $endif$ -- cgit v1.2.3