git.iko.soy/typeable/pandoc
on master help sign in
Merge pull request #2458 from mb21/lang-inlines
b49ab06John MacFarlane
README+11−6
@@ -1047,12 +1047,21 @@ Language variables
1047 format stored in the additional variables `babel-lang`,
1047 format stored in the additional variables `babel-lang`,
1048 `polyglossia-lang` (LaTeX) and `context-lang` (ConTeXt).
1048 `polyglossia-lang` (LaTeX) and `context-lang` (ConTeXt).
1049
1049
1050+ Native pandoc `span`s and `div`s with the lang attribute
1051+ (value in BCP 47) can be used to switch the language in
1052+ that range.
1053+
1050`otherlangs`
1054`otherlangs`
1051: a list of other languages used in the document
1055: a list of other languages used in the document
1052 in the YAML metadata, according to [BCP 47]. For example:
1056 in the YAML metadata, according to [BCP 47]. For example:
1053 `otherlangs: [en-GB, fr]`.
1057 `otherlangs: [en-GB, fr]`.
1058+ This is automatically generated from the `lang` attributes
1059+ in all `span`s and `div`s but can be overriden.
1054− Currently only used by `xelatex` through the generated
1060+ Currently only used by LaTeX through the generated
1055− `polyglossia-otherlangs` variable.
1061+ `babel-otherlangs` and `polyglossia-otherlangs` variables.
1062+ The LaTeX writer outputs polyglossia commands in the text but
1063+ the `babel-newcommands` variable contains mappings for them
1064+ to the corresponding babel.
1056
1065
1057`dir`
1066`dir`
1058: the base direction of the document, either `rtl` (right-to-left)
1067: the base direction of the document, either `rtl` (right-to-left)
@@ -1065,10 +1074,6 @@ Language variables
1065 (e.g. the browser, when generating HTML) supports the
1074 (e.g. the browser, when generating HTML) supports the
1066 [Unicode Bidirectional Algorithm].
1075 [Unicode Bidirectional Algorithm].
1067
1076
1068− LaTeX and ConTeXt assume by default that all text is left-to-right.
1069− Setting `dir: ltr` enables bidirectional text handling in a document
1070− whose base direction is left-to-right but contains some right-to-left script.
1071−
1072 When using LaTeX for bidirectional documents, only the `xelatex` engine
1077 When using LaTeX for bidirectional documents, only the `xelatex` engine
1073 is fully supported (use `--latex-engine=xelatex`).
1078 is fully supported (use `--latex-engine=xelatex`).
1074
1079
src/Text/Pandoc/Writers/ConTeXt.hs+27−16
@@ -157,17 +157,21 @@ blockToConTeXt (CodeBlock _ str) =
157blockToConTeXt (RawBlock "context" str) = return $ text str <> blankline
157blockToConTeXt (RawBlock "context" str) = return $ text str <> blankline
158blockToConTeXt (RawBlock _ _ ) = return empty
158blockToConTeXt (RawBlock _ _ ) = return empty
159blockToConTeXt (Div (ident,_,kvs) bs) = do
159blockToConTeXt (Div (ident,_,kvs) bs) = do
160− contents <- blockListToConTeXt bs
160+ let align dir txt = "\\startalignment[" <> dir <> "]" $$ txt $$ "\\stopalignment"
161− let contents' = if null ident
161+ let wrapRef txt = if null ident
162− then contents
162+ then txt
163− else ("\\reference" <> brackets (text $ toLabel ident) <>
163+ else ("\\reference" <> brackets (text $ toLabel ident) <>
164− braces empty <> "%") $$ contents
164+ braces empty <> "%") $$ txt
165− let align dir = blankline <> "\\startalignment[" <> dir <> "]"
166− $$ contents' $$ "\\stopalignment" <> blankline
167− return $ case lookup "dir" kvs of
165+ wrapDir = case lookup "dir" kvs of
168− Just "rtl" -> align "righttoleft"
166+ Just "rtl" -> align "righttoleft"
169− Just "ltr" -> align "lefttoright"
167+ Just "ltr" -> align "lefttoright"
170− _ -> contents'
168+ _ -> id
169+ wrapLang txt = case lookup "lang" kvs of
170+ Just lng -> "\\start\\language["
171+ <> text (fromBcp47' lng) <> "]" $$ txt $$ "\\stop"
172+ Nothing -> txt
173+ wrapBlank txt = blankline <> txt <> blankline
174+ fmap (wrapBlank . wrapLang . wrapDir . wrapRef) $ blockListToConTeXt bs
171blockToConTeXt (BulletList lst) = do
175blockToConTeXt (BulletList lst) = do
172 contents <- mapM listItemToConTeXt lst
176 contents <- mapM listItemToConTeXt lst
173 return $ ("\\startitemize" <> if isTightList lst
177 return $ ("\\startitemize" <> if isTightList lst
@@ -346,11 +350,15 @@ inlineToConTeXt (Note contents) = do
346 else text "\\startbuffer " <> nest 2 contents' <>
350 else text "\\startbuffer " <> nest 2 contents' <>
347 text "\\stopbuffer\\footnote{\\getbuffer}"
351 text "\\stopbuffer\\footnote{\\getbuffer}"
348inlineToConTeXt (Span (_,_,kvs) ils) = do
352inlineToConTeXt (Span (_,_,kvs) ils) = do
349− contents <- inlineListToConTeXt ils
350− return $ case lookup "dir" kvs of
353+ let wrapDir txt = case lookup "dir" kvs of
351− Just "rtl" -> braces $ "\\righttoleft " <> contents
354+ Just "rtl" -> braces $ "\\righttoleft " <> txt
352− Just "ltr" -> braces $ "\\lefttoright " <> contents
355+ Just "ltr" -> braces $ "\\lefttoright " <> txt
353− _ -> contents
356+ _ -> txt
357+ wrapLang txt = case lookup "lang" kvs of
358+ Just lng -> "\\start\\language[" <> text (fromBcp47' lng)
359+ <> "]" <> txt <> "\\stop "
360+ Nothing -> txt
361+ fmap (wrapLang . wrapDir) $ inlineListToConTeXt ils
354
362
355-- | Craft the section header, inserting the secton reference, if supplied.
363-- | Craft the section header, inserting the secton reference, if supplied.
356sectionHeader :: Attr
364sectionHeader :: Attr
@@ -377,6 +385,9 @@ sectionHeader (ident,classes,_) hdrLevel lst = do
377 then char '\\' <> chapter <> braces contents
385 then char '\\' <> chapter <> braces contents
378 else contents <> blankline
386 else contents <> blankline
379
387
388+fromBcp47' :: String -> String
389+fromBcp47' = fromBcp47 . splitBy (=='-')
390+
380-- Takes a list of the constituents of a BCP 47 language code
391-- Takes a list of the constituents of a BCP 47 language code
381-- and irons out ConTeXt's exceptions
392-- and irons out ConTeXt's exceptions
382-- https://tools.ietf.org/html/bcp47#section-2.1
393-- https://tools.ietf.org/html/bcp47#section-2.1
src/Text/Pandoc/Writers/LaTeX.hs+83−16
@@ -39,7 +39,7 @@ import Text.Pandoc.Templates
39import Text.Printf ( printf )
39import Text.Printf ( printf )
40import Network.URI ( isURI, unEscapeString )
40import Network.URI ( isURI, unEscapeString )
41import Data.Aeson (object, (.=))
41import Data.Aeson (object, (.=))
42−import Data.List ( (\\), isInfixOf, stripPrefix, intercalate, intersperse )
42+import Data.List ( (\\), isInfixOf, stripPrefix, intercalate, intersperse, nub, nubBy )
43import Data.Char ( toLower, isPunctuation, isAscii, isLetter, isDigit, ord )
43import Data.Char ( toLower, isPunctuation, isAscii, isLetter, isDigit, ord )
44import Data.Maybe ( fromMaybe )
44import Data.Maybe ( fromMaybe )
45import qualified Data.Text as T
45import qualified Data.Text as T
@@ -145,6 +145,7 @@ pandocToLaTeX options (Pandoc meta blocks) = do
145 st <- get
145 st <- get
146 titleMeta <- stringToLaTeX TextString $ stringify $ docTitle meta
146 titleMeta <- stringToLaTeX TextString $ stringify $ docTitle meta
147 authorsMeta <- mapM (stringToLaTeX TextString . stringify) $ docAuthors meta
147 authorsMeta <- mapM (stringToLaTeX TextString . stringify) $ docAuthors meta
148+ let docLangs = nub $ query (extract "lang") blocks
148 let context = defField "toc" (writerTableOfContents options) $
149 let context = defField "toc" (writerTableOfContents options) $
149 defField "toc-depth" (show (writerTOCDepth options -
150 defField "toc-depth" (show (writerTOCDepth options -
150 if stBook st
151 if stBook st
@@ -179,18 +180,48 @@ pandocToLaTeX options (Pandoc meta blocks) = do
179 Biblatex -> defField "biblio-title" biblioTitle .
180 Biblatex -> defField "biblio-title" biblioTitle .
180 defField "biblatex" True
181 defField "biblatex" True
181 _ -> id) $
182 _ -> id) $
183+ -- set lang to something so polyglossia/babel is included
184+ defField "lang" (if null docLangs then ""::String else "en") $
185+ defField "otherlangs" docLangs $
186+ defField "dir" (if (null $ query (extract "dir") blocks)
187+ then ""::String
188+ else "ltr") $
182 metadata
189 metadata
183 let toPolyObj lang = object [ "name" .= T.pack name
190 let toPolyObj lang = object [ "name" .= T.pack name
184 , "options" .= T.pack opts ]
191 , "options" .= T.pack opts ]
185 where
192 where
186 (name, opts) = toPolyglossia lang
193 (name, opts) = toPolyglossia lang
187 let lang = maybe [] (splitBy (=='-')) $ getField "lang" context
194 let lang = maybe [] (splitBy (=='-')) $ getField "lang" context
195+ otherlangs = maybe [] (map $ splitBy (=='-')) $ getField "otherlangs" context
188 let context' =
196 let context' =
189 defField "babel-lang" (toBabel lang)
197 defField "babel-lang" (toBabel lang)
198+ $ defField "babel-otherlangs" (map toBabel otherlangs)
199+ $ defField "babel-newcommands" (concatMap (\(poly, babel) ->
200+ -- \textspanish and \textgalician are already used by babel
201+ -- save them as \oritext... and let babel use that
202+ if poly `elem` ["spanish", "galician"]
203+ then "\\let\\oritext" ++ poly ++ "\\text" ++ poly ++ "\n" ++
204+ "\\AddBabelHook{" ++ poly ++ "}{beforeextras}" ++
205+ "{\\renewcommand{\\text" ++ poly ++ "}{\\oritext"
206+ ++ poly ++ "}}\n" ++
207+ "\\AddBabelHook{" ++ poly ++ "}{afterextras}" ++
208+ "{\\renewcommand{\\text" ++ poly ++ "}[2][]{\\foreignlanguage{"
209+ ++ poly ++ "}{##2}}}\n"
210+ else "\\newcommand{\\text" ++ poly ++ "}[2][]{\\foreignlanguage{"
211+ ++ babel ++ "}{#2}}\n" ++
212+ "\\newenvironment{" ++ poly ++ "}[1]{\\begin{otherlanguage}{"
213+ ++ babel ++ "}}{\\end{otherlanguage}}\n"
214+ )
215+ -- eliminate duplicates that have same polyglossia name
216+ $ nubBy (\a b -> fst a == fst b)
217+ -- find polyglossia and babel names of languages used in the document
218+ $ map (\l ->
219+ let lng = splitBy (=='-') l
220+ in (fst $ toPolyglossia lng, toBabel lng)
221+ )
222+ docLangs )
190 $ defField "polyglossia-lang" (toPolyObj lang)
223 $ defField "polyglossia-lang" (toPolyObj lang)
191− $ defField "polyglossia-otherlangs"
224+ $ defField "polyglossia-otherlangs" (map toPolyObj otherlangs)
192− (maybe [] (map $ toPolyObj . splitBy (=='-')) $
193− getField "otherlangs" context)
194 $ defField "latex-dir-rtl" (case (getField "dir" context)::Maybe String of
225 $ defField "latex-dir-rtl" (case (getField "dir" context)::Maybe String of
195 Just "rtl" -> True
226 Just "rtl" -> True
196 _ -> False)
227 _ -> False)
@@ -340,15 +371,24 @@ blockToLaTeX (Div (identifier,classes,kvs) bs) = do
340 then empty
371 then empty
341 else "\\hyperdef{}" <> braces (text ref) <>
372 else "\\hyperdef{}" <> braces (text ref) <>
342 braces ("\\label" <> braces (text ref))
373 braces ("\\label" <> braces (text ref))
343− contents' <- blockListToLaTeX bs
344− let align dir = inCmd "begin" dir $$ contents' $$ inCmd "end" dir
374+ let align dir txt = inCmd "begin" dir $$ txt $$ inCmd "end" dir
345− let contents = case lookup "dir" kvs of
375+ let wrapDir = case lookup "dir" kvs of
346− Just "rtl" -> align "RTL"
376+ Just "rtl" -> align "RTL"
347− Just "ltr" -> align "LTR"
377+ Just "ltr" -> align "LTR"
348− _ -> contents'
378+ _ -> id
379+ wrapLang txt = case lookup "lang" kvs of
380+ Just lng -> let (l, o) = toPolyglossiaEnv lng
381+ ops = if null o
382+ then ""
383+ else brackets $ text o
384+ in inCmd "begin" (text l) <> ops
385+ $$ blankline <> txt <> blankline
386+ $$ inCmd "end" (text l)
387+ Nothing -> txt
349− if beamer && "notes" `elem` classes -- speaker notes
388+ wrapNotes txt = if beamer && "notes" `elem` classes
350− then return $ "\\note" <> braces contents
389+ then "\\note" <> braces txt -- speaker notes
351− else return (linkAnchor $$ contents)
390+ else linkAnchor $$ txt
391+ fmap (wrapDir . wrapLang . wrapNotes) $ blockListToLaTeX bs
352blockToLaTeX (Plain lst) =
392blockToLaTeX (Plain lst) =
353 inlineListToLaTeX $ dropWhile isLineBreakOrSpace lst
393 inlineListToLaTeX $ dropWhile isLineBreakOrSpace lst
354-- title beginning with fig: indicates that the image is a figure
394-- title beginning with fig: indicates that the image is a figure
@@ -759,9 +799,12 @@ inlineToLaTeX (Span (id',classes,kvs) ils) = do
759 (if noSmallCaps then inCmd "textnormal" else id) .
799 (if noSmallCaps then inCmd "textnormal" else id) .
760 (if rtl then inCmd "RL" else id) .
800 (if rtl then inCmd "RL" else id) .
761 (if ltr then inCmd "LR" else id) .
801 (if ltr then inCmd "LR" else id) .
762− (if not (noEmph || noStrong || noSmallCaps || rtl || ltr)
802+ (case lookup "lang" kvs of
763− then braces
803+ Just lng -> let (l, o) = toPolyglossiaEnv lng
804+ ops = if null o then "" else brackets (text o)
805+ in \c -> char '\\' <> "text" <> text l <> ops <> braces c
806+ Nothing -> id)
764− else id)) `fmap` inlineListToLaTeX ils
807+ ) `fmap` inlineListToLaTeX ils
765inlineToLaTeX (Emph lst) =
808inlineToLaTeX (Emph lst) =
766 inlineListToLaTeX lst >>= return . inCmd "emph"
809 inlineListToLaTeX lst >>= return . inCmd "emph"
767inlineToLaTeX (Strong lst) =
810inlineToLaTeX (Strong lst) =
@@ -1002,6 +1045,30 @@ getListingsLanguage :: [String] -> Maybe String
1002getListingsLanguage [] = Nothing
1045getListingsLanguage [] = Nothing
1003getListingsLanguage (x:xs) = toListingsLanguage x <|> getListingsLanguage xs
1046getListingsLanguage (x:xs) = toListingsLanguage x <|> getListingsLanguage xs
1004
1047
1048+-- Extract a key from divs and spans
1049+extract :: String -> Block -> [String]
1050+extract key (Div attr _) = lookKey key attr
1051+extract key (Plain ils) = concatMap (extractInline key) ils
1052+extract key (Para ils) = concatMap (extractInline key) ils
1053+extract key (Header _ _ ils) = concatMap (extractInline key) ils
1054+extract _ _ = []
1055+
1056+-- Extract a key from spans
1057+extractInline :: String -> Inline -> [String]
1058+extractInline key (Span attr _) = lookKey key attr
1059+extractInline _ _ = []
1060+
1061+-- Look up a key in an attribute and give a list of its values
1062+lookKey :: String -> Attr -> [String]
1063+lookKey key (_,_,kvs) = maybe [] words $ lookup key kvs
1064+
1065+-- In environments \Arabic instead of \arabic is used
1066+toPolyglossiaEnv :: String -> (String, String)
1067+toPolyglossiaEnv l =
1068+ case toPolyglossia $ (splitBy (=='-')) l of
1069+ ("arabic", o) -> ("Arabic", o)
1070+ x -> x
1071+
1005-- Takes a list of the constituents of a BCP 47 language code and
1072-- Takes a list of the constituents of a BCP 47 language code and
1006-- converts it to a Polyglossia (language, options) tuple
1073-- converts it to a Polyglossia (language, options) tuple
1007-- http://mirrors.concertpass.com/tex-archive/macros/latex/contrib/polyglossia/polyglossia.pdf
1074-- http://mirrors.concertpass.com/tex-archive/macros/latex/contrib/polyglossia/polyglossia.pdf
tests/Tests/Old.hs+6
@@ -165,6 +165,12 @@ tests = [ testGroup "markdown"
165 [ "opendocument" , "context" , "texinfo", "icml"
165 [ "opendocument" , "context" , "texinfo", "icml"
166 , "man" , "plain" , "rtf", "org", "asciidoc"
166 , "man" , "plain" , "rtf", "org", "asciidoc"
167 ]
167 ]
168+ , testGroup "writers-lang-and-dir"
169+ [ test "latex" ["-f", "native", "-t", "latex", "-s"]
170+ "writers-lang-and-dir.native" "writers-lang-and-dir.latex"
171+ , test "context" ["-f", "native", "-t", "context", "-s"]
172+ "writers-lang-and-dir.native" "writers-lang-and-dir.context"
173+ ]
168 ]
174 ]
169
175
170-- makes sure file is fully closed after reading
176-- makes sure file is fully closed after reading
tests/writer.context+3
@@ -545,11 +545,13 @@ Blank line after term, indented marker, alternate markers:
545Simple block on one line:
545Simple block on one line:
546
546
547foo
547foo
548+
548And nested without indentation:
549And nested without indentation:
549
550
550foo
551foo
551
552
552bar
553bar
554+
553Interpreted markdown in a table:
555Interpreted markdown in a table:
554
556
555This is {\em emphasized}
557This is {\em emphasized}
@@ -575,6 +577,7 @@ As should this:
575Now, nested:
577Now, nested:
576
578
577foo
579foo
580+
578This should just be an HTML comment:
581This should just be an HTML comment:
579
582
580Multiline:
583Multiline:
tests/writers-lang-and-dir.contextnew file+111
@@ -0,0 +1,111 @@
1+\startmode[*mkii]
2+ \enableregime[utf-8]
3+ \setupcolors[state=start]
4+\stopmode
5+
6+% Enable hyperlinks
7+\setupinteraction[state=start, color=middleblue]
8+
9+\setuppapersize [letter][letter]
10+\setuplayout [width=middle, backspace=1.5in, cutspace=1.5in,
11+ height=middle, topspace=0.75in, bottomspace=0.75in]
12+
13+\setuppagenumbering[location={footer,center}]
14+
15+\setupbodyfont[11pt]
16+
17+\setupwhitespace[medium]
18+
19+\setuphead[chapter] [style=\tfd]
20+\setuphead[section] [style=\tfc]
21+\setuphead[subsection] [style=\tfb]
22+\setuphead[subsubsection][style=\bf]
23+
24+\setuphead[chapter, section, subsection, subsubsection][number=no]
25+
26+\definedescription
27+ [description]
28+ [headstyle=bold, style=normal, location=hanging, width=broad, margin=1cm, alternative=hanging]
29+
30+\setupitemize[autointro] % prevent orphan list intro
31+\setupitemize[indentnext=no]
32+
33+\setupfloat[figure][default={here,nonumber}]
34+\setupfloat[table][default={here,nonumber}]
35+
36+\setupthinrules[width=15em] % width of horizontal rules
37+
38+\setupdelimitedtext
39+ [blockquote]
40+ [before={\blank[medium]},
41+ after={\blank[medium]},
42+ indentnext=no,
43+ ]
44+
45+
46+\starttext
47+
48+\section[empty-divs-and-spans]{Empty Divs and Spans}
49+
50+Some text and
51+
52+div contents
53+
54+and more text.
55+
56+Next paragraph with a span and a word-thatincludesaspanright?
57+
58+\section[directionality]{Directionality}
59+
60+Some text and
61+
62+\startalignment[righttoleft]
63+rtl div contents
64+
65+\stopalignment
66+
67+and more text.
68+
69+\startalignment[lefttoright]
70+and a ltr div. with a {\righttoleft rtl span}.
71+
72+\stopalignment
73+
74+Next paragraph with a {\righttoleft rtl span} and a
75+word-that-includesa{\lefttoright ltrspan}right?
76+
77+\section[languages]{Languages}
78+
79+Some text and
80+
81+\start\language[de]
82+German div contents
83+
84+\stop
85+
86+and more text.
87+
88+Next paragraph with a \start\language[en-gb]British span\stop and a
89+word-that-includesa\start\language[de-ch]Swiss German span\stop right?
90+
91+Some \start\language[es]Spanish text\stop .
92+
93+\section[combined]{Combined}
94+
95+Some text and
96+
97+\start\language[fr]
98+\startalignment[righttoleft]
99+French rtl div contents
100+
101+\stopalignment
102+\stop
103+
104+and more text.
105+
106+Next paragraph with a \start\language[en-gb]{\lefttoright British ltr
107+span}\stop and a
108+word-that-includesa\start\language[de-ch]{\lefttoright Swiss German ltr
109+span}\stop right?
110+
111+\stoptext
tests/writers-lang-and-dir.latexnew file+166
@@ -0,0 +1,166 @@
1+\documentclass[english,]{article}
2+\usepackage{lmodern}
3+\usepackage{amssymb,amsmath}
4+\usepackage{ifxetex,ifluatex}
5+\usepackage{fixltx2e} % provides \textsubscript
6+\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
7+ \usepackage[T1]{fontenc}
8+ \usepackage[utf8]{inputenc}
9+\else % if luatex or xelatex
10+ \ifxetex
11+ \usepackage{mathspec}
12+ \else
13+ \usepackage{fontspec}
14+ \fi
15+ \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
16+ \newcommand{\euro}{€}
17+\fi
18+% use upquote if available, for straight quotes in verbatim environments
19+\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
20+% use microtype if available
21+\IfFileExists{microtype.sty}{%
22+\usepackage{microtype}
23+\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
24+}{}
25+\makeatletter
26+\@ifpackageloaded{hyperref}{}{%
27+\ifxetex
28+ \usepackage[setpagesize=false, % page size defined by xetex
29+ unicode=false, % unicode breaks when used with xetex
30+ xetex]{hyperref}
31+\else
32+ \usepackage[unicode=true]{hyperref}
33+\fi
34+}
35+\@ifpackageloaded{color}{
36+ \PassOptionsToPackage{usenames,dvipsnames}{color}
37+}{%
38+ \usepackage[usenames,dvipsnames]{color}
39+}
40+\makeatother
41+\hypersetup{breaklinks=true,
42+ bookmarks=true,
43+ pdfauthor={},
44+ pdftitle={},
45+ colorlinks=true,
46+ citecolor=blue,
47+ urlcolor=blue,
48+ linkcolor=magenta,
49+ pdfborder={0 0 0}
50+ }
51+\urlstyle{same} % don't use monospace font for urls
52+\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
53+ \usepackage[shorthands=off,ngerman,british,ngerman,spanish,french,main=english]{babel}
54+ \newcommand{\textgerman}[2][]{\foreignlanguage{ngerman}{#2}}
55+ \newenvironment{german}[1]{\begin{otherlanguage}{ngerman}}{\end{otherlanguage}}
56+ \newcommand{\textenglish}[2][]{\foreignlanguage{british}{#2}}
57+ \newenvironment{english}[1]{\begin{otherlanguage}{british}}{\end{otherlanguage}}
58+ \let\oritextspanish\textspanish
59+ \AddBabelHook{spanish}{beforeextras}{\renewcommand{\textspanish}{\oritextspanish}}
60+ \AddBabelHook{spanish}{afterextras}{\renewcommand{\textspanish}[2][]{\foreignlanguage{spanish}{##2}}}
61+ \newcommand{\textfrench}[2][]{\foreignlanguage{french}{#2}}
62+ \newenvironment{french}[1]{\begin{otherlanguage}{french}}{\end{otherlanguage}}
63+\else
64+ \usepackage{polyglossia}
65+ \setmainlanguage[]{english}
66+ \setotherlanguage[]{german}
67+ \setotherlanguage[variant=british]{english}
68+ \setotherlanguage[variant=swiss]{german}
69+ \setotherlanguage[]{spanish}
70+ \setotherlanguage[]{french}
71+\fi
72+\setlength{\parindent}{0pt}
73+\setlength{\parskip}{6pt plus 2pt minus 1pt}
74+\setlength{\emergencystretch}{3em} % prevent overfull lines
75+\providecommand{\tightlist}{%
76+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
77+\setcounter{secnumdepth}{0}
78+\ifxetex
79+ % load bidi as late as possible as it modifies e.g. graphicx
80+ \usepackage{bidi}
81+ \fi
82+\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
83+ \TeXXeTstate=1
84+ \newcommand{\RL}[1]{\beginR #1\endR}
85+ \newcommand{\LR}[1]{\beginL #1\endL}
86+ \newenvironment{RTL}{\beginR}{\endR}
87+ \newenvironment{LTR}{\beginL}{\endL}
88+\fi
89+
90+\date{}
91+
92+% Redefines (sub)paragraphs to behave more like sections
93+\ifx\paragraph\undefined\else
94+\let\oldparagraph\paragraph
95+\renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}}
96+\fi
97+\ifx\subparagraph\undefined\else
98+\let\oldsubparagraph\subparagraph
99+\renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}}
100+\fi
101+
102+\begin{document}
103+
104+\section{Empty Divs and Spans}\label{empty-divs-and-spans}
105+
106+Some text and
107+
108+div contents
109+
110+and more text.
111+
112+Next paragraph with a span and a word-thatincludesaspanright?
113+
114+\section{Directionality}\label{directionality}
115+
116+Some text and
117+
118+\begin{RTL}
119+rtl div contents
120+\end{RTL}
121+
122+and more text.
123+
124+\begin{LTR}
125+and a ltr div. with a \RL{rtl span}.
126+\end{LTR}
127+
128+Next paragraph with a \RL{rtl span} and a
129+word-that-includesa\LR{ltrspan}right?
130+
131+\section{Languages}\label{languages}
132+
133+Some text and
134+
135+\begin{german}
136+
137+German div contents
138+
139+\end{german}
140+
141+and more text.
142+
143+Next paragraph with a \textenglish[variant=british]{British span} and a
144+word-that-includesa\textgerman[variant=swiss]{Swiss German span}right?
145+
146+Some \textspanish{Spanish text}.
147+
148+\section{Combined}\label{combined}
149+
150+Some text and
151+
152+\begin{RTL}
153+\begin{french}
154+
155+French rtl div contents
156+
157+\end{french}
158+\end{RTL}
159+
160+and more text.
161+
162+Next paragraph with a \LR{\textenglish[variant=british]{British ltr
163+span}} and a word-that-includesa\LR{\textgerman[variant=swiss]{Swiss
164+German ltr span}}right?
165+
166+\end{document}
tests/writers-lang-and-dir.nativenew file+23
@@ -0,0 +1,23 @@
1+Pandoc (Meta {unMeta = fromList []})
2+[Header 1 ("empty-divs-and-spans",[],[]) [Str "Empty",Space,Str "Divs",Space,Str "and",Space,Str "Spans"]
3+,Plain [Str "Some",Space,Str "text",Space,Str "and"]
4+,Div ("",[],[]) [Para [Str "div",Space,Str "contents"]]
5+,Para [Str "and",Space,Str "more",Space,Str "text."]
6+,Para [Str "Next",Space,Str "paragraph",Space,Str "with",Space,Str "a",Space,Span ("",[],[]) [Str "span"],Space,Str "and",Space,Str "a",Space,Str "word-thatincludesa",Span ("",[],[]) [Str "span"],Str "right?"]
7+,Header 1 ("directionality",[],[]) [Str "Directionality"]
8+,Plain [Str "Some",Space,Str "text",Space,Str "and"]
9+,Div ("",[],[("dir","rtl")]) [Para [Str "rtl",Space,Str "div",Space,Str "contents"]]
10+,Para [Str "and",Space,Str "more",Space,Str "text."]
11+,Div ("",[],[("dir","ltr")]) [Para [Str "and",Space,Str "a",Space,Str "ltr",Space,Str "div.",Space,Str "with",Space,Str "a",Space,Span ("",[],[("dir","rtl")]) [Str "rtl",Space,Str "span"],Str "."]]
12+,Para [Str "Next",Space,Str "paragraph",Space,Str "with",Space,Str "a",Space,Span ("",[],[("dir","rtl")]) [Str "rtl",Space,Str "span"],Space,Str "and",Space,Str "a",Space,Str "word-that-includesa",Span ("",[],[("dir","ltr")]) [Str "ltrspan"],Str "right?"]
13+,Header 1 ("languages",[],[]) [Str "Languages"]
14+,Plain [Str "Some",Space,Str "text",Space,Str "and"]
15+,Div ("",[],[("lang","de")]) [Para [Str "German",Space,Str "div",Space,Str "contents"]]
16+,Para [Str "and",Space,Str "more",Space,Str "text."]
17+,Para [Str "Next",Space,Str "paragraph",Space,Str "with",Space,Str "a",Space,Span ("",[],[("lang","en-GB")]) [Str "British",Space,Str "span"],Space,Str "and",Space,Str "a",Space,Str "word-that-includesa",Span ("",[],[("lang","de-CH")]) [Str "Swiss",Space,Str "German",Space,Str "span"],Str "right?"]
18+,Para [Str "Some",Space,Span ("",[],[("lang","es")]) [Str "Spanish",Space,Str "text"],Str "."]
19+,Header 1 ("combined",[],[]) [Str "Combined"]
20+,Plain [Str "Some",Space,Str "text",Space,Str "and"]
21+,Div ("",[],[("lang","fr"),("dir","rtl")]) [Para [Str "French",Space,Str "rtl",Space,Str "div",Space,Str "contents"]]
22+,Para [Str "and",Space,Str "more",Space,Str "text."]
23+,Para [Str "Next",Space,Str "paragraph",Space,Str "with",Space,Str "a",Space,Span ("",[],[("lang","en-GB"),("dir","ltr")]) [Str "British",Space,Str "ltr",Space,Str "span"],Space,Str "and",Space,Str "a",Space,Str "word-that-includesa",Span ("",[],[("lang","de-CH"),("dir","ltr")]) [Str "Swiss",Space,Str "German",Space,Str "ltr",Space,Str "span"],Str "right?"]]