Skip to content

Commit e6eac11

Browse files
author
Alexander Krotov
committed
Add endnotes support
1 parent 02e515c commit e6eac11

Some content is hidden

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

90 files changed

+315
-194
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
@@ -631,11 +631,14 @@ M.InlineMath = M.Inline:create_constructor(
631631

632632
--- Creates a Note inline element
633633
-- @function Note
634-
-- @tparam {Block,...} content footnote block content
634+
-- @tparam "Footnote"|"Endnote" note type
635+
-- @tparam {Block,...} content note block content
635636
M.Note = M.Inline:create_constructor(
636637
"Note",
637-
function(content) return {c = ensureList(content)} end,
638-
"content"
638+
function(notetype, content)
639+
return {c = {notetype, ensureList(content)}}
640+
end,
641+
{"notetype", "content"}
639642
)
640643

641644
--- 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
@@ -135,6 +135,11 @@ instance Pushable QuoteType where
135135
instance Peekable QuoteType where
136136
peek = Lua.peekRead
137137

138+
instance Pushable NoteType where
139+
push = Lua.push . show
140+
instance Peekable NoteType where
141+
peek = Lua.peekRead
142+
138143
-- | Push an meta value element to the top of the lua stack.
139144
pushMetaValue :: MetaValue -> Lua ()
140145
pushMetaValue = \case
@@ -234,7 +239,7 @@ pushInline = \case
234239
Image attr alt (src,tit) -> pushViaConstructor "Image" alt src tit (LuaAttr attr)
235240
LineBreak -> pushViaConstructor "LineBreak"
236241
Link attr lst (src,tit) -> pushViaConstructor "Link" lst src tit (LuaAttr attr)
237-
Note blcks -> pushViaConstructor "Note" blcks
242+
Note t blcks -> pushViaConstructor "Note" t blcks
238243
Math mty str -> pushViaConstructor "Math" mty str
239244
Quoted qt inlns -> pushViaConstructor "Quoted" qt inlns
240245
RawInline f cs -> pushViaConstructor "RawInline" f cs
@@ -261,7 +266,7 @@ peekInline idx = defineHowTo "get Inline value" $ do
261266
"Link" -> (\(LuaAttr attr, lst, tgt) -> Link attr lst tgt)
262267
<$> elementContent
263268
"LineBreak" -> return LineBreak
264-
"Note" -> Note <$> elementContent
269+
"Note" -> uncurry Note <$> elementContent
265270
"Math" -> uncurry Math <$> elementContent
266271
"Quoted" -> uncurry Quoted <$> elementContent
267272
"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
@@ -115,7 +115,7 @@ replaceNotes :: PandocMonad m => [Block] -> TagParser m [Block]
115115
replaceNotes = walkM replaceNotes'
116116

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

src/Text/Pandoc/Readers/Muse.hs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -468,11 +468,21 @@ paraUntil end = do
468468
guard $ not inPara
469469
first (fmap B.para) <$> paraContentsUntil end
470470

471-
noteMarker :: PandocMonad m => MuseParser m String
472-
noteMarker = try $ (:)
473-
<$ char '['
474-
<*> oneOf "123456789"
475-
<*> manyTill digit (char ']')
471+
noteBrackets :: NoteType -> (Char, Char)
472+
noteBrackets nt =
473+
case nt of
474+
Endnote -> ('{', '}')
475+
_ -> ('[', ']')
476+
477+
noteMarker :: PandocMonad m => NoteType -> MuseParser m (NoteType, String)
478+
noteMarker nt = try $ do
479+
char l
480+
m <- (:) <$> oneOf "123456789" <*> manyTill digit (char r)
481+
return (nt, [l] ++ m ++ [r])
482+
where (l, r) = noteBrackets nt
483+
484+
anyNoteMarker :: PandocMonad m => MuseParser m (NoteType, String)
485+
anyNoteMarker = noteMarker Footnote <|> noteMarker Endnote
476486

477487
addNote :: PandocMonad m
478488
=> String
@@ -492,7 +502,7 @@ amuseNoteBlockUntil :: PandocMonad m
492502
-> MuseParser m (F Blocks, a)
493503
amuseNoteBlockUntil end = try $ do
494504
guardEnabled Ext_amuse
495-
ref <- noteMarker
505+
(_, ref) <- anyNoteMarker
496506
pos <- getPosition
497507
void spaceChar <|> lookAhead eol
498508
(content, e) <- allowPara $ listItemContentsUntil (sourceColumn pos) (fail "x") end
@@ -504,14 +514,14 @@ amuseNoteBlockUntil end = try $ do
504514
emacsNoteBlock :: PandocMonad m => MuseParser m (F Blocks)
505515
emacsNoteBlock = try $ do
506516
guardDisabled Ext_amuse
507-
ref <- noteMarker
517+
(_, ref) <- anyNoteMarker
508518
pos <- getPosition
509519
content <- fmap mconcat blocksTillNote
510520
addNote ref pos content
511521
return mempty
512522
where
513523
blocksTillNote =
514-
many1Till parseBlock (eof <|> () <$ lookAhead noteMarker)
524+
many1Till parseBlock (eof <|> () <$ lookAhead anyNoteMarker)
515525

516526
--
517527
-- Verse markup
@@ -750,15 +760,15 @@ footnote :: PandocMonad m => MuseParser m (F Inlines)
750760
footnote = try $ do
751761
inLink <- asks museInLink
752762
guard $ not inLink
753-
ref <- noteMarker
763+
(notetype, ref) <- anyNoteMarker
754764
return $ do
755765
notes <- asksF museNotes
756766
case M.lookup ref notes of
757-
Nothing -> return $ B.str $ "[" ++ ref ++ "]"
767+
Nothing -> return $ B.str ref
758768
Just (_pos, contents) -> do
759769
st <- askF
760770
let contents' = runF contents st { museNotes = M.delete ref (museNotes st) }
761-
return $ B.note contents'
771+
return $ B.singleton $ Note notetype $ B.toList contents'
762772

763773
whitespace :: PandocMonad m => MuseParser m (F Inlines)
764774
whitespace = try $ pure B.space <$ skipMany1 spaceChar

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
@@ -352,8 +352,8 @@ removeFormatting = query go . walk (deNote . deQuote)
352352
go _ = []
353353

354354
deNote :: Inline -> Inline
355-
deNote (Note _) = Str ""
356-
deNote x = x
355+
deNote (Note _ _) = Str ""
356+
deNote x = x
357357

358358
deQuote :: Inline -> Inline
359359
deQuote (Quoted SingleQuote xs) =

src/Text/Pandoc/Writers/AsciiDoc.hs

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

0 commit comments

Comments
 (0)