Skip to content

Commit

Permalink
Make djot reader sensitive to sourcepos extension.
Browse files Browse the repository at this point in the history
  • Loading branch information
jgm committed Feb 12, 2024
1 parent e8446c9 commit 66bbdea
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 24 deletions.
1 change: 1 addition & 0 deletions src/Text/Pandoc/Extensions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -653,4 +653,5 @@ getAllExtensions f = universalExtensions <> getAll f
extensionsFromList
[ Ext_smart ]
getAll "typst" = extensionsFromList [Ext_citations]
getAll "djot" = extensionsFromList [Ext_sourcepos]
getAll _ = mempty
61 changes: 37 additions & 24 deletions src/Text/Pandoc/Readers/Djot.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import Text.Pandoc.Options
import Text.Pandoc.Definition
import Text.Pandoc.Shared (addPandocAttributes, tshow)
import qualified Text.Pandoc.UTF8 as UTF8
import Djot (ParseOptions(..), SourcePosOption(..), parseDoc)
import Djot (ParseOptions(..), SourcePosOption(..), parseDoc, Pos(..))
import qualified Djot.AST as D
import Text.Pandoc.Error (PandocError(..))
import Control.Monad.Except (throwError)
Expand All @@ -43,26 +43,31 @@ import Data.ByteString (ByteString)

-- | Read Djot from an input string and return a Pandoc document.
readDjot :: (PandocMonad m, ToSources a) => ReaderOptions -> a -> m Pandoc
readDjot _opts inp = do
readDjot opts inp = do
let sources = toSources inp
case parseDoc ParseOptions{ sourcePositions = NoSourcePos }
case parseDoc ParseOptions{ sourcePositions =
if isEnabled Ext_sourcepos opts
then AllSourcePos
else NoSourcePos }
(UTF8.fromText $ sourcesToText sources) of
Left e -> throwError $ PandocParseError $ T.pack $ show e
Right d ->
runReaderT (doc <$> convertBlocks (D.docBlocks d))
Env{ references = D.docReferences d <> D.docAutoReferences d
, footnotes = D.docFootnotes d }
, footnotes = D.docFootnotes d
}

data Env =
Env{ references :: D.ReferenceMap
, footnotes :: D.NoteMap }
, footnotes :: D.NoteMap
}
deriving (Show, Ord, Eq)

convertBlocks :: PandocMonad m => D.Blocks -> ReaderT Env m Blocks
convertBlocks = fmap mconcat . mapM convertBlock . F.toList . D.unMany

convertBlock :: PandocMonad m => D.Node D.Block -> ReaderT Env m Blocks
convertBlock (D.Node _pos attr bl) = addAttrToBlock attr <$>
convertBlock (D.Node pos attr bl) = addAttrToBlock pos attr <$>
case bl of
D.Para ils -> para <$> convertInlines ils
D.Section bls -> divWith ("",["section"],[]) <$> convertBlocks bls
Expand Down Expand Up @@ -151,19 +156,35 @@ convertBlock (D.Node _pos attr bl) = addAttrToBlock attr <$>
D.RawBlock (D.Format fmt) bs -> pure $
rawBlock (UTF8.toText fmt) (UTF8.toText bs)

addAttrToBlock :: D.Attr -> Blocks -> Blocks
addAttrToBlock attr =
case attr of
D.Attr [] -> id
D.Attr as -> addPandocAttributes
(map (\(k,v) -> (UTF8.toText k, UTF8.toText v))
(filter (not . internalAttribute) as))
addAttrToBlock :: Pos -> D.Attr -> Blocks -> Blocks
addAttrToBlock pos (D.Attr as) =
addPandocAttributes $
case pos of
NoPos -> textkvs
Pos sl sc el ec ->
("data-pos", tshow sl <> ":" <> tshow sc <>
"-" <> tshow el <> ":" <> tshow ec) : textkvs
where
textkvs = (map (\(k,v) -> (UTF8.toText k, UTF8.toText v))
(filter (not . internalAttribute) as))

addAttrToInline :: Pos -> D.Attr -> Inlines -> Inlines
addAttrToInline pos (D.Attr as) =
addPandocAttributes $
case pos of
NoPos -> textkvs
Pos sl sc el ec ->
("data-pos", tshow sl <> ":" <> tshow sc <>
"-" <> tshow el <> ":" <> tshow ec) : textkvs
where
textkvs = (map (\(k,v) -> (UTF8.toText k, UTF8.toText v))
(filter (not . internalAttribute) as))

convertInlines :: PandocMonad m => D.Inlines -> ReaderT Env m Inlines
convertInlines = fmap mconcat . mapM convertInline . F.toList . D.unMany

convertInline :: PandocMonad m => D.Node D.Inline -> ReaderT Env m Inlines
convertInline (D.Node _pos attr il) = addAttrToInline attr <$>
convertInline (D.Node pos attr il) = addAttrToInline pos attr <$>
case il of
D.Str bs -> pure $ str (UTF8.toText bs)
D.Emph ils -> emph <$> convertInlines ils
Expand Down Expand Up @@ -191,7 +212,7 @@ convertInline (D.Node _pos attr il) = addAttrToInline attr <$>
refs <- asks references
case D.lookupReference label refs of
Just (url, lattr) ->
addAttrToInline lattr .
addAttrToInline pos lattr .
link (UTF8.toText url) "" <$> convertInlines ils
Nothing -> do
report $ ReferenceNotFound (UTF8.toText label) (newPos "" 0 0)
Expand All @@ -203,7 +224,7 @@ convertInline (D.Node _pos attr il) = addAttrToInline attr <$>
refs <- asks references
case D.lookupReference label refs of
Just (url, lattr) ->
addAttrToInline lattr .
addAttrToInline pos lattr .
image (UTF8.toText url) "" <$> convertInlines ils
Nothing -> do
report $ ReferenceNotFound (UTF8.toText label) (newPos "" 0 0)
Expand All @@ -228,14 +249,6 @@ convertInline (D.Node _pos attr il) = addAttrToInline attr <$>
D.SoftBreak -> pure softbreak
D.HardBreak -> pure linebreak

addAttrToInline :: D.Attr -> Inlines -> Inlines
addAttrToInline attr =
case attr of
D.Attr [] -> id
D.Attr as -> addPandocAttributes
(map (\(k,v) -> (UTF8.toText k, UTF8.toText v))
(filter (not . internalAttribute) as))

internalAttribute :: (ByteString, ByteString) -> Bool
internalAttribute ("_implicit",_) = True
internalAttribute ("_autogen",_) = True
Expand Down

0 comments on commit 66bbdea

Please sign in to comment.