From a157e1a6e029166a090544d23501db5e68e0bbe9 Mon Sep 17 00:00:00 2001
From: John MacFarlane <jgm@berkeley.edu>
Date: Wed, 2 Sep 2020 17:00:09 -0700
Subject: [PATCH] Support numrange, numlist for siunitx.

See #6658.
---
 src/Text/Pandoc/Readers/LaTeX.hs         |  4 ++-
 src/Text/Pandoc/Readers/LaTeX/SIunitx.hs | 32 ++++++++++++++++++------
 2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs
index 772f7a498..6b25e4028 100644
--- a/src/Text/Pandoc/Readers/LaTeX.hs
+++ b/src/Text/Pandoc/Readers/LaTeX.hs
@@ -879,7 +879,9 @@ inlineCommands = M.union inlineLanguageCommands $ M.fromList
   -- siuntix
   , ("si", skipopts *> dosi tok)
   , ("SI", doSI tok)
-  , ("SIrange", doSIrange tok)
+  , ("SIrange", doSIrange True tok)
+  , ("numrange", doSIrange False tok)
+  , ("numlist", doSInumlist)
   , ("num", doSInum)
   , ("ang", doSIang)
   -- hyphenat
diff --git a/src/Text/Pandoc/Readers/LaTeX/SIunitx.hs b/src/Text/Pandoc/Readers/LaTeX/SIunitx.hs
index b87cc3ac2..052a9d82e 100644
--- a/src/Text/Pandoc/Readers/LaTeX/SIunitx.hs
+++ b/src/Text/Pandoc/Readers/LaTeX/SIunitx.hs
@@ -4,6 +4,7 @@ module Text.Pandoc.Readers.LaTeX.SIunitx
   , doSI
   , doSIrange
   , doSInum
+  , doSInumlist
   , doSIang
   )
 where
@@ -18,6 +19,7 @@ import qualified Data.Map as M
 import Data.Char (isDigit)
 import Data.Text (Text)
 import qualified Data.Text as T
+import Data.List (intersperse)
 
 dosi :: PandocMonad m => LP m Inlines -> LP m Inlines
 dosi tok = grouped (siUnit tok) <|> siUnit tok
@@ -36,12 +38,24 @@ doSI tok = do
                       unit]
 
 doSInum :: PandocMonad m => LP m Inlines
-doSInum = do
-  skipopts
-  value <- untokenize <$> braced
+doSInum = skipopts *> (tonum . untokenize <$> braced)
+
+tonum :: Text -> Inlines
+tonum value =
   case runParser parseNum () "" value of
-    Left _    -> return $ text value
-    Right num -> return num
+    Left _    -> text value
+    Right num -> num
+
+doSInumlist :: PandocMonad m => LP m Inlines
+doSInumlist = do
+  skipopts
+  xs <- map tonum . T.splitOn ";" . untokenize <$> braced
+  case xs of
+    []  -> return mempty
+    [x] -> return x
+    _   -> return $
+             mconcat (intersperse (str "," <> space) (init xs)) <>
+             text ", & " <> last xs
 
 parseNum :: Parser Text () Inlines
 parseNum = mconcat <$> many parseNumPart
@@ -78,14 +92,16 @@ doSIang = do
     _ -> return mempty
 
 -- converts e.g. \SIrange{100}{200}{\ms} to "100 ms--200 ms"
-doSIrange :: PandocMonad m => LP m Inlines -> LP m Inlines
-doSIrange tok = do
+doSIrange :: PandocMonad m => Bool -> LP m Inlines -> LP m Inlines
+doSIrange includeUnits tok = do
   skipopts
   startvalue <- doSInum
   startvalueprefix <- option "" $ bracketed tok
   stopvalue <- doSInum
   stopvalueprefix <- option "" $ bracketed tok
-  unit <- dosi tok
+  unit <- if includeUnits
+             then dosi tok
+             else return mempty
   return . mconcat $ [startvalueprefix,
                       emptyOr160 startvalueprefix,
                       startvalue,