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.
This commit is contained in:
John MacFarlane
2024-02-12 19:59:53 -08:00
parent 758ff050b2
commit aa00714ba4
2 changed files with 52 additions and 12 deletions
+33 -12
View File
@@ -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
+19
View File
@@ -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");.
```