Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions src/Text/Pandoc/Writers/Typst.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import Control.Monad.State ( StateT, evalStateT, gets, modify )
import Text.Pandoc.Writers.Shared ( lookupMetaInlines, lookupMetaString,
metaToContext, defField, resetField,
setupTranslations )
import Text.Pandoc.Shared (isTightList, orderedListMarkers, tshow)
import Text.Pandoc.Shared (isTightList, orderedListMarkers, stringify, tshow)
import Text.Pandoc.Highlighting (highlight, formatTypstBlock, formatTypstInline,
styleToTypst)
import Text.Pandoc.Translations (Term(Abstract), translateTerm)
Expand Down Expand Up @@ -365,10 +365,12 @@ blockToTypst block =
opts <- gets stOptions
contents <- case blocks of
-- don't need #box around block-level image
[Para [Image attr _ (src, _)]]
[Para [Image attr altInlines (src, _)]]
-> pure $ mkImage opts False src attr
[Plain [Image attr _ (src, _)]]
(imageAltText attr altInlines)
[Plain [Image attr altInlines (src, _)]]
-> pure $ mkImage opts False src attr
(imageAltText attr altInlines)
_ -> brackets <$> blocksToTypst blocks
let lab = toLabel FreestandingLabel ident
return $ "#figure(" <> nest 2 ((contents <> ",")
Expand Down Expand Up @@ -529,16 +531,21 @@ inlineToTypst inline =
(if inlines == [Str src]
then mempty
else nowrap $ brackets contents)
Image attr _inlines (src,_tit) -> do
Image attr inlines (src,_tit) -> do
opts <- gets stOptions
pure $ mkImage opts True src attr
pure $ mkImage opts True src attr (imageAltText attr inlines)
Note blocks -> do
contents <- blocksToTypst blocks
return $ "#footnote" <> brackets (chomp contents)

-- Extract alt text: prefer explicit alt attribute, fall back to caption
imageAltText :: Attr -> [Inline] -> Text
imageAltText (_, _, kvs) caption =
fromMaybe (stringify caption) (lookup "alt" kvs)

-- see #9104; need box or image is treated as block-level
mkImage :: WriterOptions -> Bool -> Text -> Attr -> Doc Text
mkImage opts useBox src attr
mkImage :: WriterOptions -> Bool -> Text -> Attr -> Text -> Doc Text
mkImage opts useBox src attr altText
| useBox = "#box" <> parens coreImage
| otherwise = coreImage
where
Expand All @@ -552,11 +559,14 @@ mkImage opts useBox src attr
(case dimension Width attr of
Nothing -> mempty
Just dim -> ", width: " <> showDim dim)
altAttr
| T.null altText = mempty
| otherwise = ", alt: " <> doubleQuoted altText
isData = "data:" `T.isPrefixOf` src'
dataSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><image xlink:href=\"" <> src' <> "\" /></svg>"
coreImage
| isData = "image.decode" <> parens(doubleQuoted dataSvg <> dimAttrs)
| otherwise = "image" <> parens (doubleQuoted src' <> dimAttrs)
| isData = "image.decode" <> parens(doubleQuoted dataSvg <> dimAttrs <> altAttr)
| otherwise = "image" <> parens (doubleQuoted src' <> dimAttrs <> altAttr)

textstyle :: PandocMonad m => Doc Text -> [Inline] -> TW m (Doc Text)
textstyle s inlines = do
Expand Down
83 changes: 83 additions & 0 deletions test/command/typst-image-alt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
Typst writer: image alt text support

```
% pandoc -f markdown -t typst
![A cat sleeping on a couch](cat.png)
^D
#figure(image("cat.png", alt: "A cat sleeping on a couch"),
caption: [
A cat sleeping on a couch
]
)

```

Inline image with alt text:

```
% pandoc -f markdown -t typst
Here is an icon ![small logo](icon.png) in the text.
^D
Here is an icon #box(image("icon.png", alt: "small logo")) in the text.

```

Image with explicit alt attribute (different from caption):

```
% pandoc -f markdown -t typst
![Figure caption](diagram.png){alt="Detailed description for accessibility"}
^D
#figure(image("diagram.png", alt: "Detailed description for accessibility"),
caption: [
Figure caption
]
)

```

Image with no alt text (should omit alt parameter):

```
% pandoc -f markdown -t typst
![](empty.png)
^D
#box(image("empty.png"))

```

Inline image with dimensions should preserve alt:

```
% pandoc -f markdown -t typst
Here is ![small icon](icon.png){width=20px height=20px} inline.
^D
Here is
#box(image("icon.png", height: 0.20833in, width: 0.20833in, alt: "small icon"))
inline.

```

Alt text with special characters (quotes and backslashes):

```
% pandoc -f markdown -t typst
![Caption](test.png){alt="A \"quoted\" phrase and C:\\path\\file"}
^D
#figure(image("test.png", alt: "A \"quoted\" phrase and C:\\path\\file"),
caption: [
Caption
]
)

```

Data URI image with alt text:

```
% pandoc -f html -t typst
<img src="data:image/png;base64,iVBORw0KGgo=" alt="A small red dot">
^D
#box(image.decode("<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><image xlink:href=\"data:image/png;base64,iVBORw0KGgo=\" /></svg>", alt: "A small red dot"))

```
4 changes: 2 additions & 2 deletions test/writer.typst
Original file line number Diff line number Diff line change
Expand Up @@ -837,13 +837,13 @@ or here: <http://example.com/>
<images>
From "Voyage dans la Lune" by Georges Melies (1902):

#figure(image("lalune.jpg"),
#figure(image("lalune.jpg", alt: "lalune"),
caption: [
lalune
]
)

Here is a movie #box(image("movie.jpg")) icon.
Here is a movie #box(image("movie.jpg", alt: "movie")) icon.

#horizontalrule

Expand Down
Loading