Skip to content

Commit 536732b

Browse files
author
Alexander Krotov
committed
Add endnotes support
1 parent d7164e5 commit 536732b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+311
-188
lines changed

data/docx/word/styles.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,14 @@
337337
<w:unhideWhenUsed />
338338
<w:qFormat />
339339
</w:style>
340+
<w:style w:type="paragraph" w:styleId="EndnoteText">
341+
<w:name w:val="Endnote Text" />
342+
<w:basedOn w:val="Normal" />
343+
<w:next w:val="EndnoteText" />
344+
<w:uiPriority w:val="9" />
345+
<w:unhideWhenUsed />
346+
<w:qFormat />
347+
</w:style>
340348
<w:style w:type="character" w:default="1" w:styleId="DefaultParagraphFont">
341349
<w:name w:val="Default Paragraph Font" />
342350
<w:semiHidden />
@@ -428,6 +436,13 @@
428436
<w:vertAlign w:val="superscript" />
429437
</w:rPr>
430438
</w:style>
439+
<w:style w:type="character" w:styleId="EndnoteReference">
440+
<w:name w:val="Endnote Reference" />
441+
<w:basedOn w:val="BodyTextChar" />
442+
<w:rPr>
443+
<w:vertAlign w:val="superscript" />
444+
</w:rPr>
445+
</w:style>
431446
<w:style w:type="character" w:styleId="Hyperlink">
432447
<w:name w:val="Hyperlink" />
433448
<w:basedOn w:val="BodyTextChar" />

data/pandoc.lua

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -581,11 +581,14 @@ M.InlineMath = M.Inline:create_constructor(
581581

582582
--- Creates a Note inline element
583583
-- @function Note
584-
-- @tparam {Block,...} content footnote block content
584+
-- @tparam "Footnote"|"Endnote" note type
585+
-- @tparam {Block,...} content note block content
585586
M.Note = M.Inline:create_constructor(
586587
"Note",
587-
function(content) return {c = ensureList(content)} end,
588-
"content"
588+
function(notetype, content)
589+
return {c = {notetype, ensureList(content)}}
590+
end,
591+
{"notetype", "content"}
589592
)
590593

591594
--- Creates a Quoted inline element given the quote type and quoted content.

src/Text/Pandoc/Lua/StackInstances.hs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ instance ToLuaStack QuoteType where
142142
instance FromLuaStack QuoteType where
143143
peek idx = safeRead' =<< peek idx
144144

145+
instance ToLuaStack NoteType where
146+
push = push . show
147+
instance FromLuaStack NoteType where
148+
peek idx = safeRead' =<< peek idx
149+
145150
instance ToLuaStack Double where
146151
push = push . (realToFrac :: Double -> LuaNumber)
147152
instance FromLuaStack Double where
@@ -254,7 +259,7 @@ pushInline = \case
254259
Image attr alt (src,tit) -> pushViaConstructor "Image" alt src tit (LuaAttr attr)
255260
LineBreak -> pushViaConstructor "LineBreak"
256261
Link attr lst (src,tit) -> pushViaConstructor "Link" lst src tit (LuaAttr attr)
257-
Note blcks -> pushViaConstructor "Note" blcks
262+
Note t blcks -> pushViaConstructor "Note" t blcks
258263
Math mty str -> pushViaConstructor "Math" mty str
259264
Quoted qt inlns -> pushViaConstructor "Quoted" qt inlns
260265
RawInline f cs -> pushViaConstructor "RawInline" f cs
@@ -282,7 +287,7 @@ peekInline idx = defineHowTo "get Inline value" $ do
282287
"Link" -> (\(LuaAttr attr, lst, tgt) -> Link attr lst tgt)
283288
<$> elementContent
284289
"LineBreak" -> return LineBreak
285-
"Note" -> Note <$> elementContent
290+
"Note" -> uncurry Note <$> elementContent
286291
"Math" -> uncurry Math <$> elementContent
287292
"Quoted" -> uncurry Quoted <$> elementContent
288293
"RawInline" -> uncurry RawInline <$> elementContent

src/Text/Pandoc/Readers/Docx.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ implemented, [-] means partially implemented):
6868
- [X] Link (links to an arbitrary bookmark create a span with the target as
6969
id and "anchor" class)
7070
- [X] Image
71-
- [X] Note (Footnotes and Endnotes are silently combined.)
71+
- [X] Note
7272
-}
7373

7474
module Text.Pandoc.Readers.Docx
@@ -333,12 +333,12 @@ runToInlines (Run rs runElems)
333333
let ils = smushInlines (map runElemToInlines runElems)
334334
transform <- runStyleToTransform rPr
335335
return $ transform ils
336-
runToInlines (Footnote bps) = do
336+
runToInlines (RunFootnote bps) = do
337337
blksList <- smushBlocks <$> mapM bodyPartToBlocks bps
338338
return $ note blksList
339-
runToInlines (Endnote bps) = do
339+
runToInlines (RunEndnote bps) = do
340340
blksList <- smushBlocks <$> mapM bodyPartToBlocks bps
341-
return $ note blksList
341+
return $ endNote blksList
342342
runToInlines (InlineDrawing fp title alt bs ext) = do
343343
(lift . lift) $ P.insertMedia fp Nothing bs
344344
return $ imageWith (extentToAttr ext) fp title $ text alt

src/Text/Pandoc/Readers/Docx/Parse.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,8 @@ data ParPart = PlainRun Run
285285
deriving Show
286286

287287
data Run = Run RunStyle [RunElem]
288-
| Footnote [BodyPart]
289-
| Endnote [BodyPart]
288+
| RunFootnote [BodyPart]
289+
| RunEndnote [BodyPart]
290290
| InlineDrawing FilePath String String B.ByteString Extent -- title, alt
291291
| InlineChart -- placeholder
292292
deriving Show
@@ -918,16 +918,16 @@ childElemToRun ns element
918918
notes <- asks envNotes
919919
case lookupFootnote fnId notes of
920920
Just e -> do bps <- local (\r -> r {envLocation=InFootnote}) $ mapD (elemToBodyPart ns) (elChildren e)
921-
return $ Footnote bps
922-
Nothing -> return $ Footnote []
921+
return $ RunFootnote bps
922+
Nothing -> return $ RunFootnote []
923923
childElemToRun ns element
924924
| isElem ns "w" "endnoteReference" element
925925
, Just enId <- findAttrByName ns "w" "id" element = do
926926
notes <- asks envNotes
927927
case lookupEndnote enId notes of
928928
Just e -> do bps <- local (\r -> r {envLocation=InEndnote}) $ mapD (elemToBodyPart ns) (elChildren e)
929-
return $ Endnote bps
930-
Nothing -> return $ Endnote []
929+
return $ RunEndnote bps
930+
Nothing -> return $ RunEndnote []
931931
childElemToRun _ _ = throwError WrongElem
932932

933933
elemToRun :: NameSpaces -> Element -> D Run

src/Text/Pandoc/Readers/HTML.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ replaceNotes :: PandocMonad m => [Block] -> TagParser m [Block]
112112
replaceNotes = walkM replaceNotes'
113113

114114
replaceNotes' :: PandocMonad m => Inline -> TagParser m Inline
115-
replaceNotes' (RawInline (Format "noteref") ref) = maybe (Str "") (Note . B.toList) . lookup ref <$> getNotes
115+
replaceNotes' (RawInline (Format "noteref") ref) = maybe (Str "") (Note Footnote . B.toList) . lookup ref <$> getNotes
116116
where
117117
getNotes = noteTable <$> getState
118118
replaceNotes' x = return x

src/Text/Pandoc/Readers/Muse.hs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -498,10 +498,21 @@ paraUntil end = do
498498
guard $ not $ museInPara state
499499
first (fmap B.para) <$> paraContentsUntil end
500500

501-
noteMarker :: PandocMonad m => MuseParser m String
502-
noteMarker = try $ do
503-
char '['
504-
(:) <$> oneOf "123456789" <*> manyTill digit (char ']')
501+
noteBrackets :: NoteType -> (Char, Char)
502+
noteBrackets nt =
503+
case nt of
504+
Endnote -> ('{', '}')
505+
_ -> ('[', ']')
506+
507+
noteMarker :: PandocMonad m => NoteType -> MuseParser m (NoteType, String)
508+
noteMarker nt = try $ do
509+
char l
510+
m <- (:) <$> oneOf "123456789" <*> manyTill digit (char r)
511+
return (nt, [l] ++ m ++ [r])
512+
where (l, r) = noteBrackets nt
513+
514+
anyNoteMarker :: PandocMonad m => MuseParser m (NoteType, String)
515+
anyNoteMarker = noteMarker Footnote <|> noteMarker Endnote
505516

506517
-- Amusewiki version of note
507518
-- Parsing is similar to list item, except that note marker is used instead of list marker
@@ -510,7 +521,7 @@ amuseNoteBlockUntil :: PandocMonad m
510521
-> MuseParser m (F Blocks, a)
511522
amuseNoteBlockUntil end = try $ do
512523
guardEnabled Ext_amuse
513-
ref <- noteMarker <* spaceChar
524+
(_, ref) <- anyNoteMarker <* spaceChar
514525
pos <- getPosition
515526
updateState (\st -> st { museInPara = False })
516527
(content, e) <- listItemContentsUntil (sourceColumn pos - 1) (fail "x") end
@@ -526,7 +537,7 @@ emacsNoteBlock :: PandocMonad m => MuseParser m (F Blocks)
526537
emacsNoteBlock = try $ do
527538
guardDisabled Ext_amuse
528539
pos <- getPosition
529-
ref <- noteMarker <* skipSpaces
540+
(_, ref) <- anyNoteMarker <* skipSpaces
530541
content <- mconcat <$> blocksTillNote
531542
oldnotes <- museNotes <$> getState
532543
when (M.member ref oldnotes)
@@ -535,7 +546,7 @@ emacsNoteBlock = try $ do
535546
return mempty
536547
where
537548
blocksTillNote =
538-
many1Till parseBlock (eof <|> () <$ lookAhead noteMarker)
549+
many1Till parseBlock (eof <|> () <$ lookAhead anyNoteMarker)
539550

540551
--
541552
-- Verse markup
@@ -814,15 +825,15 @@ footnote :: PandocMonad m => MuseParser m (F Inlines)
814825
footnote = try $ do
815826
inLink <- museInLink <$> getState
816827
guard $ not inLink
817-
ref <- noteMarker
828+
(notetype, ref) <- anyNoteMarker
818829
return $ do
819830
notes <- asksF museNotes
820831
case M.lookup ref notes of
821-
Nothing -> return $ B.str $ "[" ++ ref ++ "]"
832+
Nothing -> return $ B.str ref
822833
Just (_pos, contents) -> do
823834
st <- askF
824835
let contents' = runF contents st { museNotes = M.delete ref (museNotes st) }
825-
return $ B.note contents'
836+
return $ B.singleton $ Note notetype $ B.toList contents'
826837

827838
whitespace :: PandocMonad m => MuseParser m (F Inlines)
828839
whitespace = try $ do

src/Text/Pandoc/Readers/Odt/ContentReader.hs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,8 +696,12 @@ read_link = matchingElement NsText "a"
696696

697697
read_note :: InlineMatcher
698698
read_note = matchingElement NsText "note"
699-
$ liftA note
700-
$ matchChildContent' [ read_note_body ]
699+
$ liftA2 (\nt -> singleton . Note nt . toList)
700+
(liftA makeNoteType (findAttrWithDefault NsText "note-class" "footnote"))
701+
(matchChildContent' [ read_note_body ])
702+
where
703+
makeNoteType :: String -> NoteType
704+
makeNoteType x = if x == "endnote" then Endnote else Footnote
701705

702706
read_note_body :: BlockMatcher
703707
read_note_body = matchingElement NsText "note-body"

src/Text/Pandoc/Shared.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,8 @@ removeFormatting = query go . walk (deNote . deQuote)
348348
go _ = []
349349

350350
deNote :: Inline -> Inline
351-
deNote (Note _) = Str ""
352-
deNote x = x
351+
deNote (Note _ _) = Str ""
352+
deNote x = x
353353

354354
deQuote :: Inline -> Inline
355355
deQuote (Quoted SingleQuote xs) =

src/Text/Pandoc/Writers/AsciiDoc.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,13 +479,13 @@ inlineToAsciiDoc opts (Image attr alternate (src, tit)) = do
479479
then empty
480480
else "," <> cat (intersperse "," dimList)
481481
return $ "image:" <> text src <> "[" <> linktext <> linktitle <> dims <> "]"
482-
inlineToAsciiDoc opts (Note [Para inlines]) =
483-
inlineToAsciiDoc opts (Note [Plain inlines])
484-
inlineToAsciiDoc opts (Note [Plain inlines]) = do
482+
inlineToAsciiDoc opts (Note t [Para inlines]) =
483+
inlineToAsciiDoc opts (Note t [Plain inlines])
484+
inlineToAsciiDoc opts (Note _ [Plain inlines]) = do
485485
contents <- inlineListToAsciiDoc opts inlines
486486
return $ text "footnote:[" <> contents <> "]"
487487
-- asciidoc can't handle blank lines in notes
488-
inlineToAsciiDoc _ (Note _) = return "[multiblock footnote omitted]"
488+
inlineToAsciiDoc _ (Note _ _) = return "[multiblock footnote omitted]"
489489
inlineToAsciiDoc opts (Span (ident,_,_) ils) = do
490490
let identifier = if null ident then empty else ("[[" <> text ident <> "]]")
491491
contents <- inlineListToAsciiDoc opts ils

src/Text/Pandoc/Writers/CommonMark.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ softBreakToSpace SoftBreak = Space
7373
softBreakToSpace x = x
7474

7575
processNotes :: Inline -> State [[Block]] Inline
76-
processNotes (Note bs) = do
76+
processNotes (Note _ bs) = do
7777
modify (bs :)
7878
notes <- get
7979
return $ Str $ "[" ++ show (length notes) ++ "]"
@@ -312,5 +312,5 @@ inlineToNodes opts (Span attr ils) =
312312
[node (HTML_INLINE (T.pack "</span>")) []]) ++)
313313
else (nodes ++)
314314
inlineToNodes opts (Cite _ ils) = (inlinesToNodes opts ils ++)
315-
inlineToNodes _ (Note _) = id -- should not occur
315+
inlineToNodes _ (Note{}) = id -- should not occur
316316
-- we remove Note elements in preprocessing

src/Text/Pandoc/Writers/ConTeXt.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ inlineToConTeXt (Image attr@(_,cls,_) _ (src, _)) = do
461461
then src
462462
else unEscapeString src
463463
return $ braces $ "\\externalfigure" <> brackets (text src') <> dims <> clas
464-
inlineToConTeXt (Note contents) = do
464+
inlineToConTeXt (Note _ contents) = do
465465
contents' <- blockListToConTeXt contents
466466
let codeBlock x@(CodeBlock _ _) = [x]
467467
codeBlock _ = []

src/Text/Pandoc/Writers/Custom.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ inlineToCustom (Link attr txt (src,tit)) =
244244
inlineToCustom (Image attr alt (src,tit)) =
245245
callFunc "Image" (Stringify alt) src tit (attrToMap attr)
246246

247-
inlineToCustom (Note contents) = callFunc "Note" (Stringify contents)
247+
inlineToCustom (Note noteType contents) = callFunc "Note" (Stringify contents) noteType
248248

249249
inlineToCustom (Span attr items) =
250250
callFunc "Span" (Stringify items) (attrToMap attr)

src/Text/Pandoc/Writers/Docbook.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ hasLineBreaks :: [Inline] -> Bool
317317
hasLineBreaks = getAny . query isLineBreak . walk removeNote
318318
where
319319
removeNote :: Inline -> Inline
320-
removeNote (Note _) = Str ""
320+
removeNote (Note{}) = Str ""
321321
removeNote x = x
322322
isLineBreak :: Inline -> Any
323323
isLineBreak LineBreak = Any True
@@ -429,7 +429,7 @@ inlineToDocbook opts (Image attr _ (src, tit)) = return $
429429
inTagsIndented "title" (text $ escapeStringForXML tit)
430430
in inTagsIndented "inlinemediaobject" $ inTagsIndented "imageobject" $
431431
titleDoc $$ imageToDocbook opts attr src
432-
inlineToDocbook opts (Note contents) =
432+
inlineToDocbook opts (Note _ contents) =
433433
inTagsIndented "footnote" <$> blocksToDocbook opts contents
434434

435435
isMathML :: HTMLMathMethod -> Bool

0 commit comments

Comments
 (0)