summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2024-01-29 12:25:09 -0800
committerJohn MacFarlane <jgm@berkeley.edu>2024-01-29 12:25:09 -0800
commitc1f87fdb37c904cb473d9747fd4141d4709c07d6 (patch)
treedcfe0064af908c2ddbb95bcd695d3f6a4779d478 /src
parent97eb9273398f141872d08e12c492167ad67628b6 (diff)
Typst writer: handle labels and citaiton ids with spaces...
and other special characters. In these cases, we produce an explicit `label()` rather than using `<>` or `@`. Cloess #9387.
Diffstat (limited to 'src')
-rw-r--r--src/Text/Pandoc/Writers/Typst.hs43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/Text/Pandoc/Writers/Typst.hs b/src/Text/Pandoc/Writers/Typst.hs
index f51e4019a..936155fb2 100644
--- a/src/Text/Pandoc/Writers/Typst.hs
+++ b/src/Text/Pandoc/Writers/Typst.hs
@@ -98,7 +98,7 @@ blockToTypst block =
Para inlines -> ($$ blankline) <$> inlinesToTypst inlines
Header level (ident,cls,_) inlines -> do
contents <- inlinesToTypst inlines
- let lab = toLabel ident
+ let lab = toLabel FreestandingLabel ident
return $
if "unlisted" `elem` cls
then literal "#heading(outlined: false)" <> brackets contents <>
@@ -169,7 +169,7 @@ blockToTypst block =
else do
captcontents <- inlinesToTypst caption
return $ ", caption: " <> brackets captcontents
- let lab = toLabel ident
+ let lab = toLabel FreestandingLabel ident
let formatalign AlignLeft = "left,"
formatalign AlignRight = "right,"
formatalign AlignCenter = "center,"
@@ -192,14 +192,14 @@ blockToTypst block =
Figure (ident,_,_) (Caption _mbshort capt) blocks -> do
caption <- blocksToTypst capt
contents <- blocksToTypst blocks
- let lab = toLabel ident
+ let lab = toLabel FreestandingLabel ident
return $ "#figure(" <> nest 2 (brackets contents <> "," <> cr <>
("caption: [" $$ nest 2 caption $$ "]"))
$$ ")" $$ lab $$ blankline
Div (ident,_,_) (Header lev ("",cls,kvs) ils:rest) ->
blocksToTypst (Header lev (ident,cls,kvs) ils:rest)
Div (ident,_,_) blocks -> do
- let lab = toLabel ident
+ let lab = toLabel FreestandingLabel ident
contents <- blocksToTypst blocks
return $ "#block[" $$ contents $$ ("]" <+> lab)
@@ -261,7 +261,7 @@ inlineToTypst inline =
Subscript inlines -> textstyle "#sub" inlines
SmallCaps inlines -> textstyle "#smallcaps" inlines
Span (ident,_,_) inlines -> do
- let lab = toLabel ident
+ let lab = toLabel FreestandingLabel ident
(lab $$) <$> inlinesToTypst inlines
Quoted quoteType inlines -> do
let q = case quoteType of
@@ -275,8 +275,7 @@ inlineToTypst inline =
suppl <- case citationSuffix cite of
[] -> pure mempty
suff -> brackets <$> inlinesToTypst suff
- pure $ literal ("@" <> citationId cite) <> suppl
- <> endCode
+ pure $ toLabel CiteLabel (citationId cite) <> suppl <> endCode
if isEnabled Ext_citations opts
-- Note: this loses prefix
then mconcat <$> mapM toCite citations
@@ -284,7 +283,7 @@ inlineToTypst inline =
Link _attrs inlines (src,_tit) -> do
contents <- inlinesToTypst inlines
let dest = case T.uncons src of
- Just ('#', ident) -> toLabel ident
+ Just ('#', ident) -> toLabel ArgumentLabel ident
_ -> doubleQuoted src
return $ "#link" <> parens dest <>
(if inlines == [Str src]
@@ -363,16 +362,26 @@ escapeTypst context t =
needsEscapeAtLineStart '=' = True
needsEscapeAtLineStart _ = False
-toLabel :: Text -> Doc Text
-toLabel ident =
- if T.null ident
- then mempty
- else "<" <> text (fixLabel (unEscapeString . T.unpack $ ident)) <> ">"
+data LabelType =
+ FreestandingLabel | ArgumentLabel | CiteLabel
+ deriving (Show, Eq)
+
+toLabel :: LabelType -> Text -> Doc Text
+toLabel labelType ident
+ | T.null ident = mempty
+ | T.all isIdentChar ident'
+ = case labelType of
+ CiteLabel -> "@" <> literal ident'
+ _ -> "<" <> literal ident' <> ">"
+ | otherwise
+ = case labelType of
+ CiteLabel -> "#cite" <>
+ parens ("label" <> parens (doubleQuoted ident'))
+ FreestandingLabel -> "#label" <> parens (doubleQuoted ident')
+ ArgumentLabel -> "label" <> parens (doubleQuoted ident')
where
- fixLabel = map (\c -> if isAlphaNum c ||
- c == '_' || c == '-' || c == '.' || c == ':'
- then c
- else '-')
+ ident' = T.pack $ unEscapeString $ T.unpack ident
+ isIdentChar c = isAlphaNum c || c == '_' || c == '-' || c == '.' || c == ':'
doubleQuoted :: Text -> Doc Text
doubleQuoted = doubleQuotes . literal . escape