summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2012-09-24 19:13:34 -0700
committerJohn MacFarlane <jgm@berkeley.edu>2012-09-24 19:13:34 -0700
commit4ab30f3ceaec427b6f89f2fe32cef4b0b1b5e955 (patch)
treef59433aebc20b884fbb5369e1ac113c3f314d0df
parent12045d84b6f20c9d959f61d376bd89e722f7f50c (diff)
Texinfo writer: Fixed internal cross-references.
Now we insert anchors after each header, and use @ref instead of @uref for links. Commas are now escaped as @comma{} only when needed; previously all commas were escaped. (This change is needed, in part, because @ref commands must be followed by a real comma or period.) Also insert a blank line in from of @verbatim environments.
-rw-r--r--src/Text/Pandoc/Writers/Texinfo.hs33
-rw-r--r--tests/writer.texinfo93
2 files changed, 93 insertions, 33 deletions
diff --git a/src/Text/Pandoc/Writers/Texinfo.hs b/src/Text/Pandoc/Writers/Texinfo.hs
index 40e76c615..5ced0d9ec 100644
--- a/src/Text/Pandoc/Writers/Texinfo.hs
+++ b/src/Text/Pandoc/Writers/Texinfo.hs
@@ -45,6 +45,8 @@ data WriterState =
WriterState { stStrikeout :: Bool -- document contains strikeout
, stSuperscript :: Bool -- document contains superscript
, stSubscript :: Bool -- document contains subscript
+ , stEscapeComma :: Bool -- in a context where we need @comma
+ , stIdentifiers :: [String] -- header ids used already
}
{- TODO:
@@ -56,7 +58,8 @@ data WriterState =
writeTexinfo :: WriterOptions -> Pandoc -> String
writeTexinfo options document =
evalState (pandocToTexinfo options $ wrapTop document) $
- WriterState { stStrikeout = False, stSuperscript = False, stSubscript = False }
+ WriterState { stStrikeout = False, stSuperscript = False,
+ stEscapeComma = False, stSubscript = False, stIdentifiers = [] }
-- | Add a "Top" node around the document, needed by Texinfo.
wrapTop :: Pandoc -> Pandoc
@@ -95,7 +98,6 @@ stringToTexinfo = escapeStringUsing texinfoEscapes
where texinfoEscapes = [ ('{', "@{")
, ('}', "@}")
, ('@', "@@")
- , (',', "@comma{}") -- only needed in argument lists
, ('\160', "@ ")
, ('\x2014', "---")
, ('\x2013', "--")
@@ -103,6 +105,14 @@ stringToTexinfo = escapeStringUsing texinfoEscapes
, ('\x2019', "'")
]
+escapeCommas :: State WriterState Doc -> State WriterState Doc
+escapeCommas parser = do
+ oldEscapeComma <- gets stEscapeComma
+ modify $ \st -> st{ stEscapeComma = True }
+ res <- parser
+ modify $ \st -> st{ stEscapeComma = oldEscapeComma }
+ return res
+
-- | Puts contents into Texinfo command.
inCmd :: String -> Doc -> Doc
inCmd cmd contents = char '@' <> text cmd <> braces contents
@@ -134,7 +144,8 @@ blockToTexinfo (BlockQuote lst) = do
text "@end quotation"
blockToTexinfo (CodeBlock _ str) = do
- return $ text "@verbatim" $$
+ return $ blankline $$
+ text "@verbatim" $$
flush (text str) $$
text "@end verbatim" <> blankline
@@ -194,9 +205,13 @@ blockToTexinfo (Header 0 lst) = do
blockToTexinfo (Header level lst) = do
node <- inlineListForNode lst
txt <- inlineListToTexinfo lst
+ idsUsed <- gets stIdentifiers
+ let id' = uniqueIdent lst idsUsed
+ modify $ \st -> st{ stIdentifiers = id' : idsUsed }
return $ if (level > 0) && (level <= 4)
- then blankline <> text "@node " <> node <> cr <>
- text (seccmd level) <> txt
+ then blankline <> text "@node " <> node $$
+ text (seccmd level) <> txt $$
+ text "@anchor" <> braces (text $ '#':id')
else txt
where
seccmd 1 = "@chapter "
@@ -404,17 +419,21 @@ inlineToTexinfo (RawInline _ _) = return empty
inlineToTexinfo (LineBreak) = return $ text "@*"
inlineToTexinfo Space = return $ char ' '
+inlineToTexinfo (Link txt (src@('#':_), _)) = do
+ contents <- escapeCommas $ inlineListToTexinfo txt
+ return $ text "@ref" <>
+ braces (text (stringToTexinfo src) <> text "," <> contents)
inlineToTexinfo (Link txt (src, _)) = do
case txt of
[Code _ x] | x == src -> -- autolink
do return $ text $ "@url{" ++ x ++ "}"
- _ -> do contents <- inlineListToTexinfo txt
+ _ -> do contents <- escapeCommas $ inlineListToTexinfo txt
let src1 = stringToTexinfo src
return $ text ("@uref{" ++ src1 ++ ",") <> contents <>
char '}'
inlineToTexinfo (Image alternate (source, _)) = do
- content <- inlineListToTexinfo alternate
+ content <- escapeCommas $ inlineListToTexinfo alternate
return $ text ("@image{" ++ base ++ ",,,") <> content <> text "," <>
text (ext ++ "}")
where
diff --git a/tests/writer.texinfo b/tests/writer.texinfo
index aed237f2a..d88f404b7 100644
--- a/tests/writer.texinfo
+++ b/tests/writer.texinfo
@@ -30,7 +30,7 @@ _@{\text\@}
@title Pandoc Test Suite
@author John MacFarlane
@author Anonymous
-July 17@comma{} 2006
+July 17, 2006
@end titlepage
@node Top
@@ -64,28 +64,33 @@ This is a set of tests for pandoc. Most of them are adapted from John Gruber's m
@node Headers
@chapter Headers
+@anchor{#headers}
@menu
* Level 2 with an embedded link::
@end menu
@node Level 2 with an embedded link
@section Level 2 with an @uref{/url,embedded link}
+@anchor{#level-2-with-an-embedded-link}
@menu
* Level 3 with emphasis::
@end menu
@node Level 3 with emphasis
@subsection Level 3 with @emph{emphasis}
+@anchor{#level-3-with-emphasis}
@menu
* Level 4::
@end menu
@node Level 4
@subsubsection Level 4
+@anchor{#level-4}
Level 5
@node Level 1
@chapter Level 1
+@anchor{#level-1}
@menu
* Level 2 with emphasis::
* Level 2::
@@ -93,16 +98,19 @@ Level 5
@node Level 2 with emphasis
@section Level 2 with @emph{emphasis}
+@anchor{#level-2-with-emphasis}
@menu
* Level 3::
@end menu
@node Level 3
@subsection Level 3
+@anchor{#level-3}
with no blank line
@node Level 2
@section Level 2
+@anchor{#level-2}
with no blank line
@iftex
@@ -114,6 +122,7 @@ with no blank line
@node Paragraphs
@chapter Paragraphs
+@anchor{#paragraphs}
Here's a regular paragraph.
In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item.
@@ -131,6 +140,7 @@ There should be a hard line break@*here.
@node Block Quotes
@chapter Block Quotes
+@anchor{#block-quotes}
E-mail style:
@quotation
@@ -138,6 +148,7 @@ This is a block quote. It is pretty short.
@end quotation
@quotation
Code in a block quote:
+
@verbatim
sub status {
print "working";
@@ -175,7 +186,9 @@ And a following paragraph.
@node Code Blocks
@chapter Code Blocks
+@anchor{#code-blocks}
Code:
+
@verbatim
---- (should be four hyphens)
@@ -187,6 +200,7 @@ this code block is indented by one tab
@end verbatim
And:
+
@verbatim
this code block is indented by two tabs
@@ -202,6 +216,7 @@ These should not be escaped: \$ \\ \> \[ \{
@node Lists
@chapter Lists
+@anchor{#lists}
@menu
* Unordered::
* Ordered::
@@ -212,6 +227,7 @@ These should not be escaped: \$ \\ \> \[ \{
@node Unordered
@section Unordered
+@anchor{#unordered}
Asterisks tight:
@itemize
@@ -289,6 +305,7 @@ Minus 3
@node Ordered
@section Ordered
+@anchor{#ordered}
Tight:
@enumerate
@@ -343,7 +360,7 @@ Multiple paragraphs:
@enumerate
@item
-Item 1@comma{} graf one.
+Item 1, graf one.
Item 1. graf two. The quick brown fox jumped over the lazy dog's back.
@@ -357,6 +374,7 @@ Item 3.
@node Nested
@section Nested
+@anchor{#nested}
@itemize
@item
Tab
@@ -417,6 +435,7 @@ Third
@node Tabs and spaces
@section Tabs and spaces
+@anchor{#tabs-and-spaces}
@itemize
@item
this is a list item indented with tabs
@@ -437,6 +456,7 @@ this is an example list item indented with spaces
@node Fancy list markers
@section Fancy list markers
+@anchor{#fancy-list-markers}
@enumerate 2
@item
begins with 2
@@ -447,7 +467,7 @@ with a continuation
@enumerate 4
@item
-sublist with roman numerals@comma{} starting with 4
+sublist with roman numerals, starting with 4
@item
more items
@enumerate A
@@ -512,6 +532,7 @@ B. Williams
@node Definition Lists
@chapter Definition Lists
+@anchor{#definition-lists}
Tight using spaces:
@table @asis
@@ -564,11 +585,12 @@ Multiple blocks with italics:
red fruit
-contains seeds@comma{} crisp@comma{} pleasant to taste
+contains seeds, crisp, pleasant to taste
@item @emph{orange}
orange fruit
+
@verbatim
{ orange code block }
@end verbatim
@@ -578,7 +600,7 @@ orange block quote
@end quotation
@end table
-Multiple definitions@comma{} tight:
+Multiple definitions, tight:
@table @asis
@item apple
@@ -591,7 +613,7 @@ orange fruit
bank
@end table
-Multiple definitions@comma{} loose:
+Multiple definitions, loose:
@table @asis
@item apple
@@ -608,7 +630,7 @@ bank
@end table
-Blank line after term@comma{} indented marker@comma{} alternate markers:
+Blank line after term, indented marker, alternate markers:
@table @asis
@item apple
@@ -632,6 +654,7 @@ sublist
@node HTML Blocks
@chapter HTML Blocks
+@anchor{#html-blocks}
Simple block on one line:
foo
@@ -646,7 +669,8 @@ And this is @strong{strong}
Here's a simple block:
foo
-This should be a code block@comma{} though:
+This should be a code block, though:
+
@verbatim
<div>
foo
@@ -654,11 +678,12 @@ This should be a code block@comma{} though:
@end verbatim
As should this:
+
@verbatim
<div>foo</div>
@end verbatim
-Now@comma{} nested:
+Now, nested:
foo
This should just be an HTML comment:
@@ -666,13 +691,15 @@ This should just be an HTML comment:
Multiline:
Code block:
+
@verbatim
<!-- Comment -->
@end verbatim
-Just plain comment@comma{} with trailing spaces on the line:
+Just plain comment, with trailing spaces on the line:
Code:
+
@verbatim
<hr />
@end verbatim
@@ -688,9 +715,10 @@ Hr's:
@node Inline Markup
@chapter Inline Markup
-This is @emph{emphasized}@comma{} and so @emph{is this}.
+@anchor{#inline-markup}
+This is @emph{emphasized}, and so @emph{is this}.
-This is @strong{strong}@comma{} and so @strong{is this}.
+This is @strong{strong}, and so @strong{is this}.
An @emph{@uref{/url,emphasized link}}.
@@ -702,15 +730,15 @@ So is @strong{@emph{this}} word.
So is @strong{@emph{this}} word.
-This is code: @code{>}@comma{} @code{$}@comma{} @code{\}@comma{} @code{\$}@comma{} @code{<html>}.
+This is code: @code{>}, @code{$}, @code{\}, @code{\$}, @code{<html>}.
@textstrikeout{This is @emph{strikeout}.}
Superscripts: a@textsuperscript{bc}d a@textsuperscript{@emph{hello}} a@textsuperscript{hello@ there}.
-Subscripts: H@textsubscript{2}O@comma{} H@textsubscript{23}O@comma{} H@textsubscript{many@ of@ them}O.
+Subscripts: H@textsubscript{2}O, H@textsubscript{23}O, H@textsubscript{many@ of@ them}O.
-These should not be superscripts or subscripts@comma{} because of the unescaped spaces: a^b c^d@comma{} a~b c~d.
+These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.
@iftex
@bigskip@hrule@bigskip
@@ -720,20 +748,21 @@ These should not be superscripts or subscripts@comma{} because of the unescaped
@end ifnottex
@node Smart quotes ellipses dashes
-@chapter Smart quotes@comma{} ellipses@comma{} dashes
-``Hello@comma{}'' said the spider. ```Shelob' is my name.''
+@chapter Smart quotes, ellipses, dashes
+@anchor{#smart-quotes-ellipses-dashes}
+``Hello,'' said the spider. ```Shelob' is my name.''
-`A'@comma{} `B'@comma{} and `C' are letters.
+`A', `B', and `C' are letters.
-`Oak@comma{}' `elm@comma{}' and `beech' are names of trees. So is `pine.'
+`Oak,' `elm,' and `beech' are names of trees. So is `pine.'
-`He said@comma{} ``I want to go.''' Were you alive in the 70's?
+`He said, ``I want to go.''' Were you alive in the 70's?
Here is some quoted `@code{code}' and a ``@uref{http://example.com/?foo=1&bar=2,quoted link}''.
Some dashes: one---two --- three---four --- five.
-Dashes between numbers: 5--7@comma{} 255--66@comma{} 1987--1999.
+Dashes between numbers: 5--7, 255--66, 1987--1999.
Ellipses@dots{}and@dots{}and@dots{}.
@@ -746,6 +775,7 @@ Ellipses@dots{}and@dots{}and@dots{}.
@node LaTeX
@chapter LaTeX
+@anchor{#latex}
@itemize
@item
@tex
@@ -771,9 +801,9 @@ These shouldn't be math:
@itemize
@item
-To get the famous equation@comma{} write @code{$e = mc^2$}.
+To get the famous equation, write @code{$e = mc^2$}.
@item
-$22@comma{}000 is a @emph{lot} of money. So is $34@comma{}000. (It worked if ``lot'' is emphasized.)
+$22,000 is a @emph{lot} of money. So is $34,000. (It worked if ``lot'' is emphasized.)
@item
Shoes ($20) and socks ($5).
@item
@@ -798,6 +828,7 @@ Cat & 1 \\ \hline
@node Special Characters
@chapter Special Characters
+@anchor{#special-characters}
Here is some unicode:
@itemize
@@ -864,6 +895,7 @@ Minus: -
@node Links
@chapter Links
+@anchor{#links}
@menu
* Explicit::
* Reference::
@@ -873,6 +905,7 @@ Minus: -
@node Explicit
@section Explicit
+@anchor{#explicit}
Just a @uref{/url/,URL}.
@uref{/url/,URL and title}.
@@ -893,6 +926,7 @@ Just a @uref{/url/,URL}.
@node Reference
@section Reference
+@anchor{#reference}
Foo @uref{/url/,bar}.
Foo @uref{/url/,bar}.
@@ -910,6 +944,7 @@ Indented @uref{/url,twice}.
Indented @uref{/url,thrice}.
This should [not][] be a link.
+
@verbatim
[not]: /url
@end verbatim
@@ -920,6 +955,7 @@ Foo @uref{/url/,biz}.
@node With ampersands
@section With ampersands
+@anchor{#with-ampersands}
Here's a @uref{http://example.com/?foo=1&bar=2,link with an ampersand in the URL}.
Here's a link with an amersand in the link text: @uref{http://att.com/,AT&T}.
@@ -930,6 +966,7 @@ Here's an @uref{/script?foo=1&bar=2,inline link in pointy braces}.
@node Autolinks
@section Autolinks
+@anchor{#autolinks}
With an ampersand: @url{http://example.com/?foo=1&bar=2}
@itemize
@@ -947,6 +984,7 @@ An e-mail address: @uref{mailto:nobody@@nowhere.net,@code{nobody@@nowhere.net}}
Blockquoted: @url{http://example.com/}
@end quotation
Auto-links should not occur here: @code{<http://example.com/>}
+
@verbatim
or here: <http://example.com/>
@end verbatim
@@ -960,6 +998,7 @@ or here: <http://example.com/>
@node Images
@chapter Images
+@anchor{#images}
From ``Voyage dans la Lune'' by Georges Melies (1902):
@float
@@ -978,14 +1017,16 @@ Here is a movie @image{movie,,,movie,jpg} icon.
@node Footnotes
@chapter Footnotes
-Here is a footnote reference@comma{}@footnote{Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.} and another.@footnote{Here's the long note. This one contains multiple blocks.
+@anchor{#footnotes}
+Here is a footnote reference,@footnote{Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.} and another.@footnote{Here's the long note. This one contains multiple blocks.
Subsequent blocks are indented to show that they belong to the footnote (as with list items).
+
@verbatim
{ <code> }
@end verbatim
-If you want@comma{} you can indent every line@comma{} but you can also be lazy and just indent the first line of each block.} This should @emph{not} be a footnote reference@comma{} because it contains a space.[^my note] Here is an inline note.@footnote{This is @emph{easier} to type. Inline notes may contain @uref{http://google.com,links} and @code{]} verbatim characters@comma{} as well as [bracketed text].}
+If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.} This should @emph{not} be a footnote reference, because it contains a space.[^my note] Here is an inline note.@footnote{This is @emph{easier} to type. Inline notes may contain @uref{http://google.com,links} and @code{]} verbatim characters, as well as [bracketed text].}
@quotation
Notes can go in quotes.@footnote{In quote.}
@@ -995,6 +1036,6 @@ Notes can go in quotes.@footnote{In quote.}
And in list items.@footnote{In list.}
@end enumerate
-This paragraph should not be part of the note@comma{} as it is not indented.
+This paragraph should not be part of the note, as it is not indented.
@bye