ConTeXt writer: Updated to use Text.Pandoc.Pretty.

This commit is contained in:
John MacFarlane 2010-12-20 19:33:05 -08:00
parent 112717de4e
commit 2587543457
3 changed files with 151 additions and 162 deletions

View file

@ -1,3 +1,4 @@
{-# LANGUAGE OverloadedStrings #-}
{- {-
Copyright (C) 2007-2010 John MacFarlane <jgm@berkeley.edu> Copyright (C) 2007-2010 John MacFarlane <jgm@berkeley.edu>
@ -31,9 +32,9 @@ module Text.Pandoc.Writers.ConTeXt ( writeConTeXt ) where
import Text.Pandoc.Definition import Text.Pandoc.Definition
import Text.Pandoc.Shared import Text.Pandoc.Shared
import Text.Printf ( printf ) import Text.Printf ( printf )
import Data.List ( isSuffixOf, intercalate, intersperse ) import Data.List ( intercalate )
import Control.Monad.State import Control.Monad.State
import Text.PrettyPrint.HughesPJ hiding ( Str ) import Text.Pandoc.Pretty
import Text.Pandoc.Templates ( renderTemplate ) import Text.Pandoc.Templates ( renderTemplate )
data WriterState = data WriterState =
@ -56,15 +57,18 @@ writeConTeXt options document =
pandocToConTeXt :: WriterOptions -> Pandoc -> State WriterState String pandocToConTeXt :: WriterOptions -> Pandoc -> State WriterState String
pandocToConTeXt options (Pandoc (Meta title authors date) blocks) = do pandocToConTeXt options (Pandoc (Meta title authors date) blocks) = do
let colwidth = if writerWrapText options
then Just $ writerColumns options
else Nothing
titletext <- if null title titletext <- if null title
then return "" then return ""
else liftM render $ inlineListToConTeXt title else liftM (render colwidth) $ inlineListToConTeXt title
authorstext <- mapM (liftM render . inlineListToConTeXt) authors authorstext <- mapM (liftM (render colwidth) . inlineListToConTeXt) authors
datetext <- if null date datetext <- if null date
then return "" then return ""
else liftM render $ inlineListToConTeXt date else liftM (render colwidth) $ inlineListToConTeXt date
body <- blockListToConTeXt blocks body <- blockListToConTeXt blocks
let main = render $ body $$ text "" let main = render colwidth $ body
let context = writerVariables options ++ let context = writerVariables options ++
[ ("toc", if writerTableOfContents options then "yes" else "") [ ("toc", if writerTableOfContents options then "yes" else "")
, ("body", main) , ("body", main)
@ -104,32 +108,26 @@ stringToConTeXt = concatMap escapeCharForConTeXt
-- | Convert Pandoc block element to ConTeXt. -- | Convert Pandoc block element to ConTeXt.
blockToConTeXt :: Block blockToConTeXt :: Block
-> State WriterState BlockWrapper -> State WriterState Doc
blockToConTeXt Null = return $ Reg empty blockToConTeXt Null = return empty
blockToConTeXt (Plain lst) = do blockToConTeXt (Plain lst) = inlineListToConTeXt lst
st <- get
let options = stOptions st
contents <- wrapTeXIfNeeded options False inlineListToConTeXt lst
return $ Reg contents
blockToConTeXt (Para [Image txt (src,_)]) = do blockToConTeXt (Para [Image txt (src,_)]) = do
capt <- inlineListToConTeXt txt capt <- inlineListToConTeXt txt
return $ Pad $ text "\\placefigure[here,nonumber]{" <> capt <> return $ blankline $$ "\\placefigure[here,nonumber]" <> braces capt <>
text "}{\\externalfigure[" <> text src <> text "]}" braces ("\\externalfigure" <> brackets (text src)) <> blankline
blockToConTeXt (Para lst) = do blockToConTeXt (Para lst) = do
st <- get contents <- inlineListToConTeXt lst
let options = stOptions st return $ contents <> blankline
contents <- wrapTeXIfNeeded options False inlineListToConTeXt lst
return $ Pad contents
blockToConTeXt (BlockQuote lst) = do blockToConTeXt (BlockQuote lst) = do
contents <- blockListToConTeXt lst contents <- blockListToConTeXt lst
return $ Pad $ text "\\startblockquote" $$ contents $$ text "\\stopblockquote" return $ "\\startblockquote" $$ nest 0 contents $$ "\\stopblockquote" <> blankline
blockToConTeXt (CodeBlock _ str) = blockToConTeXt (CodeBlock _ str) =
return $ Reg $ text $ "\\starttyping\n" ++ str ++ "\n\\stoptyping\n" return $ "\\starttyping" <> cr <> flush (text str) <> cr <> "\\stoptyping" <> blankline
-- \n because \stoptyping can't have anything after it, inc. } -- blankline because \stoptyping can't have anything after it, inc. '}'
blockToConTeXt (RawHtml _) = return $ Reg empty blockToConTeXt (RawHtml _) = return empty
blockToConTeXt (BulletList lst) = do blockToConTeXt (BulletList lst) = do
contents <- mapM listItemToConTeXt lst contents <- mapM listItemToConTeXt lst
return $ Pad $ text "\\startitemize" $$ vcat contents $$ text "\\stopitemize" return $ "\\startitemize" $$ vcat contents $$ text "\\stopitemize" <> blankline
blockToConTeXt (OrderedList (start, style', delim) lst) = do blockToConTeXt (OrderedList (start, style', delim) lst) = do
st <- get st <- get
let level = stOrderedListLevel st let level = stOrderedListLevel st
@ -161,20 +159,20 @@ blockToConTeXt (OrderedList (start, style', delim) lst) = do
LowerAlpha -> "[a]" LowerAlpha -> "[a]"
UpperAlpha -> "[A]" UpperAlpha -> "[A]"
let specs = style'' ++ specs2 let specs = style'' ++ specs2
return $ Pad $ text ("\\startitemize" ++ specs) $$ vcat contents $$ return $ "\\startitemize" <> text specs $$ vcat contents $$
text "\\stopitemize" "\\stopitemize" <> blankline
blockToConTeXt (DefinitionList lst) = blockToConTeXt (DefinitionList lst) =
mapM defListItemToConTeXt lst >>= return . Pad . wrappedBlocksToDoc liftM vcat $ mapM defListItemToConTeXt lst
blockToConTeXt HorizontalRule = return $ Pad $ text "\\thinrule" blockToConTeXt HorizontalRule = return $ "\\thinrule" <> blankline
blockToConTeXt (Header level lst) = do blockToConTeXt (Header level lst) = do
contents <- inlineListToConTeXt lst contents <- inlineListToConTeXt lst
st <- get st <- get
let opts = stOptions st let opts = stOptions st
let base = if writerNumberSections opts then "section" else "subject" let base = if writerNumberSections opts then "section" else "subject"
return $ Pad $ if level >= 1 && level <= 5 return $ if level >= 1 && level <= 5
then char '\\' <> text (concat (replicate (level - 1) "sub")) <> then char '\\' <> text (concat (replicate (level - 1) "sub")) <>
text base <> char '{' <> contents <> char '}' text base <> char '{' <> contents <> char '}' <> blankline
else contents else contents <> blankline
blockToConTeXt (Table caption aligns widths heads rows) = do blockToConTeXt (Table caption aligns widths heads rows) = do
let colDescriptor colWidth alignment = (case alignment of let colDescriptor colWidth alignment = (case alignment of
AlignLeft -> 'l' AlignLeft -> 'l'
@ -188,80 +186,83 @@ blockToConTeXt (Table caption aligns widths heads rows) = do
zipWith colDescriptor widths aligns) zipWith colDescriptor widths aligns)
headers <- if all null heads headers <- if all null heads
then return empty then return empty
else liftM ($$ text "\\HL") $ tableRowToConTeXt heads else liftM ($$ "\\HL") $ tableRowToConTeXt heads
captionText <- inlineListToConTeXt caption captionText <- inlineListToConTeXt caption
let captionText' = if null caption then text "none" else captionText let captionText' = if null caption then text "none" else captionText
rows' <- mapM tableRowToConTeXt rows rows' <- mapM tableRowToConTeXt rows
return $ Pad $ text "\\placetable[here]{" <> captionText' <> char '}' $$ return $ "\\placetable[here]" <> braces captionText' $$
text "\\starttable[" <> text colDescriptors <> char ']' $$ "\\starttable" <> brackets (text colDescriptors) $$
text "\\HL" $$ headers $$ "\\HL" $$ headers $$
vcat rows' $$ text "\\HL\n\\stoptable" vcat rows' $$ "\\HL" $$ "\\stoptable" <> blankline
tableRowToConTeXt :: [[Block]] -> State WriterState Doc tableRowToConTeXt :: [[Block]] -> State WriterState Doc
tableRowToConTeXt cols = do tableRowToConTeXt cols = do
cols' <- mapM blockListToConTeXt cols cols' <- mapM blockListToConTeXt cols
return $ (vcat (map (text "\\NC " <>) cols')) $$ return $ (vcat (map ("\\NC " <>) cols')) $$ "\\NC\\AR"
text "\\NC\\AR"
listItemToConTeXt :: [Block] -> State WriterState Doc listItemToConTeXt :: [Block] -> State WriterState Doc
listItemToConTeXt list = blockListToConTeXt list >>= listItemToConTeXt list = blockListToConTeXt list >>=
return . (text "\\item" $$) . (nest 2) return . ("\\item" $$) . (nest 2)
defListItemToConTeXt :: ([Inline], [[Block]]) -> State WriterState BlockWrapper defListItemToConTeXt :: ([Inline], [[Block]]) -> State WriterState Doc
defListItemToConTeXt (term, defs) = do defListItemToConTeXt (term, defs) = do
term' <- inlineListToConTeXt term term' <- inlineListToConTeXt term
def' <- liftM (vcat . intersperse (text "")) $ mapM blockListToConTeXt defs def' <- liftM vsep $ mapM blockListToConTeXt defs
return $ Pad $ text "\\startdescr{" <> term' <> char '}' $$ def' $$ text "\\stopdescr" return $ "\\startdescr" <> braces term' $$ nest 2 def' $$
"\\stopdescr" <> blankline
-- | Convert list of block elements to ConTeXt. -- | Convert list of block elements to ConTeXt.
blockListToConTeXt :: [Block] -> State WriterState Doc blockListToConTeXt :: [Block] -> State WriterState Doc
blockListToConTeXt lst = mapM blockToConTeXt lst >>= return . wrappedBlocksToDoc blockListToConTeXt lst = liftM vcat $ mapM blockToConTeXt lst
-- | Convert list of inline elements to ConTeXt. -- | Convert list of inline elements to ConTeXt.
inlineListToConTeXt :: [Inline] -- ^ Inlines to convert inlineListToConTeXt :: [Inline] -- ^ Inlines to convert
-> State WriterState Doc -> State WriterState Doc
inlineListToConTeXt lst = mapM inlineToConTeXt lst >>= return . hcat inlineListToConTeXt lst = liftM hcat $ mapM inlineToConTeXt lst
-- | Convert inline element to ConTeXt -- | Convert inline element to ConTeXt
inlineToConTeXt :: Inline -- ^ Inline to convert inlineToConTeXt :: Inline -- ^ Inline to convert
-> State WriterState Doc -> State WriterState Doc
inlineToConTeXt (Emph lst) = do inlineToConTeXt (Emph lst) = do
contents <- inlineListToConTeXt lst contents <- inlineListToConTeXt lst
return $ text "{\\em " <> contents <> char '}' return $ braces $ "\\em " <> contents
inlineToConTeXt (Strong lst) = do inlineToConTeXt (Strong lst) = do
contents <- inlineListToConTeXt lst contents <- inlineListToConTeXt lst
return $ text "{\\bf " <> contents <> char '}' return $ braces $ "\\bf " <> contents
inlineToConTeXt (Strikeout lst) = do inlineToConTeXt (Strikeout lst) = do
contents <- inlineListToConTeXt lst contents <- inlineListToConTeXt lst
return $ text "\\overstrikes{" <> contents <> char '}' return $ "\\overstrikes" <> braces contents
inlineToConTeXt (Superscript lst) = do inlineToConTeXt (Superscript lst) = do
contents <- inlineListToConTeXt lst contents <- inlineListToConTeXt lst
return $ text "\\high{" <> contents <> char '}' return $ "\\high" <> braces contents
inlineToConTeXt (Subscript lst) = do inlineToConTeXt (Subscript lst) = do
contents <- inlineListToConTeXt lst contents <- inlineListToConTeXt lst
return $ text "\\low{" <> contents <> char '}' return $ "\\low" <> braces contents
inlineToConTeXt (SmallCaps lst) = do inlineToConTeXt (SmallCaps lst) = do
contents <- inlineListToConTeXt lst contents <- inlineListToConTeXt lst
return $ text "{\\sc " <> contents <> char '}' return $ braces $ "\\sc " <> contents
inlineToConTeXt (Code str) = return $ text $ "\\type{" ++ str ++ "}" inlineToConTeXt (Code str) =
return $ "\\type" <> braces (text str)
inlineToConTeXt (Quoted SingleQuote lst) = do inlineToConTeXt (Quoted SingleQuote lst) = do
contents <- inlineListToConTeXt lst contents <- inlineListToConTeXt lst
return $ text "\\quote{" <> contents <> char '}' return $ "\\quote" <> braces contents
inlineToConTeXt (Quoted DoubleQuote lst) = do inlineToConTeXt (Quoted DoubleQuote lst) = do
contents <- inlineListToConTeXt lst contents <- inlineListToConTeXt lst
return $ text "\\quotation{" <> contents <> char '}' return $ "\\quotation" <> braces contents
inlineToConTeXt (Cite _ lst) = inlineListToConTeXt lst inlineToConTeXt (Cite _ lst) = inlineListToConTeXt lst
inlineToConTeXt Apostrophe = return $ char '\'' inlineToConTeXt Apostrophe = return $ char '\''
inlineToConTeXt EmDash = return $ text "---" inlineToConTeXt EmDash = return "---"
inlineToConTeXt EnDash = return $ text "--" inlineToConTeXt EnDash = return "--"
inlineToConTeXt Ellipses = return $ text "\\ldots{}" inlineToConTeXt Ellipses = return "\\ldots{}"
inlineToConTeXt (Str str) = return $ text $ stringToConTeXt str inlineToConTeXt (Str str) = return $ text $ stringToConTeXt str
inlineToConTeXt (Math InlineMath str) = return $ char '$' <> text str <> char '$' inlineToConTeXt (Math InlineMath str) =
inlineToConTeXt (Math DisplayMath str) = return $ text "\\startformula " <> text str <> text " \\stopformula" return $ char '$' <> text str <> char '$'
inlineToConTeXt (Math DisplayMath str) =
return $ text "\\startformula " <> text str <> text " \\stopformula"
inlineToConTeXt (TeX str) = return $ text str inlineToConTeXt (TeX str) = return $ text str
inlineToConTeXt (HtmlInline _) = return empty inlineToConTeXt (HtmlInline _) = return empty
inlineToConTeXt (LineBreak) = return $ text "\\crlf\n" inlineToConTeXt (LineBreak) = return $ text "\\crlf" <> cr
inlineToConTeXt Space = return $ char ' ' inlineToConTeXt Space = return space
inlineToConTeXt (Link [Code str] (src, tit)) = -- since ConTeXt has its own inlineToConTeXt (Link [Code str] (src, tit)) = -- since ConTeXt has its own
inlineToConTeXt (Link [Str str] (src, tit)) -- way of printing links... inlineToConTeXt (Link [Str str] (src, tit)) -- way of printing links...
inlineToConTeXt (Link txt (src, _)) = do inlineToConTeXt (Link txt (src, _)) = do
@ -270,15 +271,12 @@ inlineToConTeXt (Link txt (src, _)) = do
put $ st {stNextRef = next + 1} put $ st {stNextRef = next + 1}
let ref = show next let ref = show next
label <- inlineListToConTeXt txt label <- inlineListToConTeXt txt
return $ text "\\useURL[" <> text ref <> text "][" <> text src <> return $ "\\useURL" <> brackets (text ref) <> brackets (text src) <>
text "][][" <> label <> text "]\\from[" <> text ref <> char ']' brackets empty <> brackets label <>
"\\from" <> brackets (text ref)
inlineToConTeXt (Image _ (src, _)) = do inlineToConTeXt (Image _ (src, _)) = do
return $ text "{\\externalfigure[" <> text src <> text "]}" return $ braces $ "\\externalfigure" <> brackets (text src)
inlineToConTeXt (Note contents) = do inlineToConTeXt (Note contents) = do
contents' <- blockListToConTeXt contents contents' <- blockListToConTeXt contents
let rawnote = stripTrailingNewlines $ render contents' return $ text "\\footnote{" <>
-- note: a \n before } is needed when note ends with a \stoptyping nest 2 contents' <> char '}' <> cr
let optNewline = "\\stoptyping" `isSuffixOf` rawnote
return $ text "\\footnote{" <>
text rawnote <> (if optNewline then char '\n' else empty) <> char '}'

View file

@ -172,4 +172,4 @@ Multiline table without column headers:
\NC Here's another one. Note the blank line between rows. \NC Here's another one. Note the blank line between rows.
\NC\AR \NC\AR
\HL \HL
\stoptable \stoptable

View file

@ -61,8 +61,8 @@ after={\blank[medium]},
\blank[3*medium] \blank[3*medium]
\stopalignment \stopalignment
This is a set of tests for pandoc. Most of them are adapted from This is a set of tests for pandoc. Most of them are adapted from John Gruber's
John Gruber's markdown test suite. markdown test suite.
\thinrule \thinrule
@ -94,9 +94,9 @@ with no blank line
Here's a regular paragraph. Here's a regular paragraph.
In Markdown 1.0.0 and earlier. Version 8. This line turns into a In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item.
list item. Because a hard-wrapped line in the middle of a paragraph Because a hard-wrapped line in the middle of a paragraph looked like a list
looked like a list item. item.
Here's one with a bullet. * criminey. Here's one with a bullet. * criminey.
@ -293,9 +293,8 @@ Multiple paragraphs:
\startitemize[n][stopper=.] \startitemize[n][stopper=.]
\item \item
Item 1, graf one. Item 1, graf one.
Item 1. graf two. The quick brown fox jumped over the lazy dog's Item 1. graf two. The quick brown fox jumped over the lazy dog's back.
back.
\item \item
Item 2. Item 2.
\item \item
@ -343,7 +342,7 @@ Same thing but with paragraphs:
First First
\item \item
Second: Second:
\startitemize \startitemize
\item \item
Fee Fee
@ -363,7 +362,7 @@ Same thing but with paragraphs:
this is a list item indented with tabs this is a list item indented with tabs
\item \item
this is a list item indented with spaces this is a list item indented with spaces
\startitemize \startitemize
\item \item
this is an example list item indented with tabs this is an example list item indented with tabs
@ -379,9 +378,9 @@ Same thing but with paragraphs:
begins with 2 begins with 2
\item \item
and now 3 and now 3
with a continuation with a continuation
\startitemize[r][start=4,stopper=.,width=2.0em] \startitemize[r][start=4,stopper=.,width=2.0em]
\item \item
sublist with roman numerals, starting with 4 sublist with roman numerals, starting with 4
@ -441,110 +440,110 @@ B. Williams
Tight using spaces: Tight using spaces:
\startdescr{apple} \startdescr{apple}
red fruit red fruit
\stopdescr \stopdescr
\startdescr{orange} \startdescr{orange}
orange fruit orange fruit
\stopdescr \stopdescr
\startdescr{banana} \startdescr{banana}
yellow fruit yellow fruit
\stopdescr \stopdescr
Tight using tabs: Tight using tabs:
\startdescr{apple} \startdescr{apple}
red fruit red fruit
\stopdescr \stopdescr
\startdescr{orange} \startdescr{orange}
orange fruit orange fruit
\stopdescr \stopdescr
\startdescr{banana} \startdescr{banana}
yellow fruit yellow fruit
\stopdescr \stopdescr
Loose: Loose:
\startdescr{apple} \startdescr{apple}
red fruit red fruit
\stopdescr \stopdescr
\startdescr{orange} \startdescr{orange}
orange fruit orange fruit
\stopdescr \stopdescr
\startdescr{banana} \startdescr{banana}
yellow fruit yellow fruit
\stopdescr \stopdescr
Multiple blocks with italics: Multiple blocks with italics:
\startdescr{{\em apple}} \startdescr{{\em apple}}
red fruit red fruit
contains seeds, crisp, pleasant to taste contains seeds, crisp, pleasant to taste
\stopdescr \stopdescr
\startdescr{{\em orange}} \startdescr{{\em orange}}
orange fruit orange fruit
\starttyping \starttyping
{ orange code block } { orange code block }
\stoptyping \stoptyping
\startblockquote \startblockquote
orange block quote orange block quote
\stopblockquote \stopblockquote
\stopdescr \stopdescr
Multiple definitions, tight: Multiple definitions, tight:
\startdescr{apple} \startdescr{apple}
red fruit red fruit
computer computer
\stopdescr \stopdescr
\startdescr{orange} \startdescr{orange}
orange fruit orange fruit
bank bank
\stopdescr \stopdescr
Multiple definitions, loose: Multiple definitions, loose:
\startdescr{apple} \startdescr{apple}
red fruit red fruit
computer computer
\stopdescr \stopdescr
\startdescr{orange} \startdescr{orange}
orange fruit orange fruit
bank bank
\stopdescr \stopdescr
Blank line after term, indented marker, alternate markers: Blank line after term, indented marker, alternate markers:
\startdescr{apple} \startdescr{apple}
red fruit red fruit
computer computer
\stopdescr \stopdescr
\startdescr{orange} \startdescr{orange}
orange fruit orange fruit
\startitemize[n][stopper=.] \startitemize[n][stopper=.]
\item \item
sublist sublist
\item \item
sublist sublist
\stopitemize \stopitemize
\stopdescr \stopdescr
\subject{HTML Blocks} \subject{HTML Blocks}
@ -618,8 +617,7 @@ So is {\bf {\em this}} word.
So is {\bf {\em this}} word. So is {\bf {\em this}} word.
This is code: \type{>}, \type{$}, \type{\}, \type{\$}, This is code: \type{>}, \type{$}, \type{\}, \type{\$}, \type{<html>}.
\type{<html>}.
\overstrikes{This is {\em strikeout}.} \overstrikes{This is {\em strikeout}.}
@ -627,27 +625,25 @@ Superscripts: a\high{bc}d a\high{{\em hello}} a\high{hello~there}.
Subscripts: H\low{2}O, H\low{23}O, H\low{many~of~them}O. Subscripts: H\low{2}O, H\low{23}O, H\low{many~of~them}O.
These should not be superscripts or subscripts, because of the These should not be superscripts or subscripts, because of the unescaped
unescaped spaces: a\letterhat{}b c\letterhat{}d, a\lettertilde{}b spaces: a\letterhat{}b c\letterhat{}d, a\lettertilde{}b c\lettertilde{}d.
c\lettertilde{}d.
\thinrule \thinrule
\subject{Smart quotes, ellipses, dashes} \subject{Smart quotes, ellipses, dashes}
\quotation{Hello,} said the spider. \quotation{Hello,} said the spider. \quotation{\quote{Shelob} is my name.}
\quotation{\quote{Shelob} is my name.}
\quote{A}, \quote{B}, and \quote{C} are letters. \quote{A}, \quote{B}, and \quote{C} are letters.
\quote{Oak,} \quote{elm,} and \quote{beech} are names of trees. So \quote{Oak,} \quote{elm,} and \quote{beech} are names of trees. So is
is \quote{pine.} \quote{pine.}
\quote{He said, \quotation{I want to go.}} Were you alive in the \quote{He said, \quotation{I want to go.}} Were you alive in the 70's?
70's?
Here is some quoted \quote{\type{code}} and a Here is some quoted \quote{\type{code}} and a
\quotation{\useURL[3][http://example.com/?foo=1&bar=2][][quoted link]\from[3]}. \quotation{\useURL[3][http://example.com/?foo=1&bar=2][][quoted
link]\from[3]}.
Some dashes: one---two --- three---four --- five. Some dashes: one---two --- three---four --- five.
@ -676,8 +672,7 @@ Ellipses\ldots{}and\ldots{}and\ldots{}.
Here's some display math: Here's some display math:
\startformula \frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h} \stopformula \startformula \frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h} \stopformula
\item \item
Here's one that has a line break in it: Here's one that has a line break in it: $\alpha + \omega \times x^2$.
$\alpha + \omega \times x^2$.
\stopitemize \stopitemize
These shouldn't be math: These shouldn't be math:
@ -817,16 +812,16 @@ Foo \useURL[22][/url/][][biz]\from[22].
\subsubject{With ampersands} \subsubject{With ampersands}
Here's a Here's a \useURL[23][http://example.com/?foo=1&bar=2][][link with an ampersand
\useURL[23][http://example.com/?foo=1&bar=2][][link with an ampersand in the URL]\from[23]. in the URL]\from[23].
Here's a link with an amersand in the link text: Here's a link with an amersand in the link text:
\useURL[24][http://att.com/][][AT\&T]\from[24]. \useURL[24][http://att.com/][][AT\&T]\from[24].
Here's an \useURL[25][/script?foo=1&bar=2][][inline link]\from[25]. Here's an \useURL[25][/script?foo=1&bar=2][][inline link]\from[25].
Here's an Here's an \useURL[26][/script?foo=1&bar=2][][inline link in pointy
\useURL[26][/script?foo=1&bar=2][][inline link in pointy braces]\from[26]. braces]\from[26].
\subsubject{Autolinks} \subsubject{Autolinks}
@ -846,8 +841,7 @@ An e-mail address:
\useURL[29][mailto:nobody@nowhere.net][][nobody@nowhere.net]\from[29] \useURL[29][mailto:nobody@nowhere.net][][nobody@nowhere.net]\from[29]
\startblockquote \startblockquote
Blockquoted: Blockquoted: \useURL[30][http://example.com/][][http://example.com/]\from[30]
\useURL[30][http://example.com/][][http://example.com/]\from[30]
\stopblockquote \stopblockquote
Auto-links should not occur here: \type{<http://example.com/>} Auto-links should not occur here: \type{<http://example.com/>}
@ -870,39 +864,36 @@ Here is a movie {\externalfigure[movie.jpg]} icon.
\subject{Footnotes} \subject{Footnotes}
Here is a footnote reference, Here is a footnote reference,\footnote{Here is the footnote. It can go
\footnote{Here is the footnote. It can go anywhere after the footnote anywhere after the footnote reference. It need not be placed at the end of
reference. It need not be placed at the end of the document.} the document.}
and another. and another.\footnote{Here's the long note. This one contains multiple
\footnote{Here's the long note. This one contains multiple blocks. blocks.
Subsequent blocks are indented to show that they belong to the Subsequent blocks are indented to show that they belong to the footnote (as
footnote (as with list items). with list items).
\starttyping \starttyping
{ <code> } { <code> }
\stoptyping \stoptyping
If you want, you can indent every line, but you can also be lazy If you want, you can indent every line, but you can also be lazy and just
and just indent the first line of each block.} indent the first line of each block.}
This should {\em not} be a footnote reference, because it contains This should {\em not} be a footnote reference, because it contains a
a space.{[}\letterhat{}my note{]} Here is an inline note. space.{[}\letterhat{}my note{]} Here is an inline note.\footnote{This is
\footnote{This is {\em easier} to type. Inline notes may contain {\em easier} to type. Inline notes may contain
\useURL[31][http://google.com][][links]\from[31] and \type{]} \useURL[31][http://google.com][][links]\from[31] and \type{]} verbatim
verbatim characters, as well as {[}bracketed text{]}.} characters, as well as {[}bracketed text{]}.}
\startblockquote \startblockquote
Notes can go in quotes. Notes can go in quotes.\footnote{In quote.}
\footnote{In quote.}
\stopblockquote \stopblockquote
\startitemize[n][stopper=.] \startitemize[n][stopper=.]
\item \item
And in list items. And in list items.\footnote{In list.}
\footnote{In list.}
\stopitemize \stopitemize
This paragraph should not be part of the note, as it is not This paragraph should not be part of the note, as it is not indented.
indented.
\stoptext \stoptext