aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <[email protected]>2024-02-12 19:59:53 -0800
committerJohn MacFarlane <[email protected]>2024-02-12 20:01:44 -0800
commitaa00714ba476c8558eb897003fe69009a02b0171 (patch)
treef6215364b9a7246942b3423779ca0b4866b77241
parent758ff050b28d18c3830c85f34c1538897fd7af9b (diff)
Typst writer: improve citation support.
Emit `form: "prose"` or `form: "year"` qualifiers if the citation is author-in-text or suppress-author. Strip initial comma from suffix, since typst will add an extra one. Closes #9452.
-rw-r--r--src/Text/Pandoc/Writers/Typst.hs45
-rw-r--r--test/command/9452.md19
2 files changed, 52 insertions, 12 deletions
diff --git a/src/Text/Pandoc/Writers/Typst.hs b/src/Text/Pandoc/Writers/Typst.hs
index 66d92fa9e..daa286dbf 100644
--- a/src/Text/Pandoc/Writers/Typst.hs
+++ b/src/Text/Pandoc/Writers/Typst.hs
@@ -271,11 +271,6 @@ inlineToTypst inline =
return $ q <> contents <> q
Cite citations inlines -> do
opts <- gets stOptions
- let toCite cite = do
- suppl <- case citationSuffix cite of
- [] -> pure mempty
- suff -> brackets <$> inlinesToTypst suff
- pure $ toLabel CiteLabel (citationId cite) <> suppl <> endCode
if isEnabled Ext_citations opts
-- Note: this loses prefix
then mconcat <$> mapM toCite citations
@@ -364,25 +359,51 @@ escapeTypst context t =
needsEscapeAtLineStart _ = False
data LabelType =
- FreestandingLabel | ArgumentLabel | CiteLabel
+ FreestandingLabel
+ | ArgumentLabel
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' <> ">"
+ = "<" <> literal ident' <> ">"
| otherwise
= case labelType of
- CiteLabel -> "#cite" <>
- parens ("label" <> parens (doubleQuoted ident'))
FreestandingLabel -> "#label" <> parens (doubleQuoted ident')
ArgumentLabel -> "label" <> parens (doubleQuoted ident')
where
ident' = T.pack $ unEscapeString $ T.unpack ident
- isIdentChar c = isAlphaNum c || c == '_' || c == '-' || c == '.' || c == ':'
+
+isIdentChar :: Char -> Bool
+isIdentChar c = isAlphaNum c || c == '_' || c == '-' || c == '.' || c == ':'
+
+toCite :: PandocMonad m => Citation -> TW m (Doc Text)
+toCite cite = do
+ let ident' = T.pack $ unEscapeString $ T.unpack $ citationId cite
+ -- typst inserts comma and we get a doubled one if supplement contains it:
+ let eatComma (Str "," : Space : xs) = xs
+ eatComma xs = xs
+ if citationMode cite == NormalCitation && T.all isIdentChar ident'
+ then do
+ suppl <- case citationSuffix cite of
+ [] -> pure mempty
+ suff -> (<> endCode) . brackets
+ <$> inlinesToTypst (eatComma suff)
+ pure $ "@" <> literal ident' <> suppl
+ else do
+ let label = if T.all isIdentChar ident'
+ then "<" <> literal ident' <> ">"
+ else "label" <> parens (doubleQuoted ident')
+ let form = case citationMode cite of
+ NormalCitation -> mempty
+ SuppressAuthor -> ", form: \"year\""
+ AuthorInText -> ", form: \"prose\""
+ suppl <- case citationSuffix cite of
+ [] -> pure mempty
+ suff -> (", supplement: " <>) . brackets
+ <$> inlinesToTypst (eatComma suff)
+ pure $ "#cite" <> parens (label <> form <> suppl) <> endCode
doubleQuoted :: Text -> Doc Text
doubleQuoted = doubleQuotes . literal . escape
diff --git a/test/command/9452.md b/test/command/9452.md
new file mode 100644
index 000000000..2d89921b9
--- /dev/null
+++ b/test/command/9452.md
@@ -0,0 +1,19 @@
+```
+% pandoc -t typst
+@something2024 says blah.
+
+Here is a sentence [@something2024].
+
+With supplement [@something2024, p. 3].
+
+And just the year [-@something2024].
+^D
+#cite(<something2024>, form: "prose") says blah.
+
+Here is a sentence @something2024.
+
+With supplement @something2024[p.~3];.
+
+And just the year #cite(<something2024>, form: "year");.
+
+```