git.iko.soy/typeable/pandoc
on master help sign in
Add XWiki Support (#4167)

Add XWiki Support Closes #1800

commit45944b51a0bd1d5149c968f90dc0a5e0bf4b0d6c authorDerek Chen-Becker <github@chen-becker.org> dateTue 2 Apr 2019, 17:27 (8 years ago) parent0abb858
6 files changed+934−1
data/templates/default.xwiki+13 pandoc.cabal+1 src/Text/Pandoc/Writers.hs+3 src/Text/Pandoc/Writers/MediaWiki.hs+1−1 src/Text/Pandoc/Writers/XWiki.hs+266 test/writer.xwiki+650
data/templates/default.xwikinew file+13
@@ -0,0 +1,13 @@
1+$for(include-before)$
2+$include-before$
3+
4+$endfor$
5+$if(toc)$
6+{{toc /}}
7+
8+$endif$
9+$body$
10+$for(include-after)$
11+
12+$include-after$
13+$endfor$
pandoc.cabal+1
@@ -506,6 +506,7 @@ library
506506 Text.Pandoc.Writers.Textile,
507507 Text.Pandoc.Writers.MediaWiki,
508508 Text.Pandoc.Writers.DokuWiki,
509+ Text.Pandoc.Writers.XWiki,
509510 Text.Pandoc.Writers.ZimWiki,
510511 Text.Pandoc.Writers.RTF,
511512 Text.Pandoc.Writers.ODT,
src/Text/Pandoc/Writers.hs+3
@@ -63,6 +63,7 @@ module Text.Pandoc.Writers
6363 , writeTEI
6464 , writeTexinfo
6565 , writeTextile
66+ , writeXWiki
6667 , writeZimWiki
6768 , getWriter
6869 ) where
@@ -107,6 +108,7 @@ import Text.Pandoc.Writers.RTF
107108import Text.Pandoc.Writers.TEI
108109import Text.Pandoc.Writers.Texinfo
109110import Text.Pandoc.Writers.Textile
111+import Text.Pandoc.Writers.XWiki
110112import Text.Pandoc.Writers.ZimWiki
111113import Text.Parsec.Error
112114
@@ -156,6 +158,7 @@ writers = [
156158 ,("rst" , TextWriter writeRST)
157159 ,("mediawiki" , TextWriter writeMediaWiki)
158160 ,("dokuwiki" , TextWriter writeDokuWiki)
161+ ,("xwiki" , TextWriter writeXWiki)
159162 ,("zimwiki" , TextWriter writeZimWiki)
160163 ,("textile" , TextWriter writeTextile)
161164 ,("rtf" , TextWriter writeRTF)
src/Text/Pandoc/Writers/MediaWiki.hs+1−1
@@ -12,7 +12,7 @@ Conversion of 'Pandoc' documents to MediaWiki markup.
1212
1313MediaWiki: <http://www.mediawiki.org/wiki/MediaWiki>
1414-}
15−module Text.Pandoc.Writers.MediaWiki ( writeMediaWiki ) where
15+module Text.Pandoc.Writers.MediaWiki ( writeMediaWiki, highlightingLangs ) where
1616import Prelude
1717import Control.Monad.Reader
1818import Control.Monad.State.Strict
src/Text/Pandoc/Writers/XWiki.hsnew file+266
@@ -0,0 +1,266 @@
1+{-# LANGUAGE NoImplicitPrelude #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+{-
4+Copyright (C) 2008-2017 John MacFarlane <jgm@berkeley.edu>
5+
6+This program is free software; you can redistribute it and/or modify
7+it under the terms of the GNU General Public License as published by
8+the Free Software Foundation; either version 2 of the License, or
9+(at your option) any later version.
10+
11+This program is distributed in the hope that it will be useful,
12+but WITHOUT ANY WARRANTY; without even the implied warranty of
13+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+GNU General Public License for more details.
15+
16+You should have received a copy of the GNU General Public License
17+along with this program; if not, write to the Free Software
18+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19+-}
20+
21+{- |
22+ Module : Text.Pandoc.Writers.XWiki
23+ Copyright : Copyright (C) 2008-2017 John MacFarlane
24+ License : GNU GPL, version 2 or above
25+
26+ Maintainer : Derek Chen-Becker <dchenbecker@gmail.com>
27+ Stability : alpha
28+ Portability : portable
29+
30+Conversion of 'Pandoc' documents to XWiki markup.
31+
32+XWiki: <http://www.xwiki.org/>
33+XWiki Syntax: <http://www.xwiki.org/xwiki/bin/view/Documentation/UserGuide/Features/XWikiSyntax/>
34+-}
35+
36+module Text.Pandoc.Writers.XWiki ( writeXWiki ) where
37+import Prelude
38+import Control.Monad.Reader (ReaderT, asks, local, runReaderT)
39+import qualified Data.Set as Set
40+import qualified Data.Text as Text
41+import Data.Text (Text, intercalate, pack, replace, split)
42+import Text.Pandoc.Class (PandocMonad, report)
43+import Text.Pandoc.Definition
44+import Text.Pandoc.Logging
45+import Text.Pandoc.Options
46+import Text.Pandoc.Shared (escapeURI, isURI, linesToPara)
47+import Text.Pandoc.Writers.MediaWiki (highlightingLangs)
48+
49+data WriterState = WriterState {
50+ listLevel :: Text -- String at the beginning of items
51+}
52+
53+type XWikiReader m = ReaderT WriterState m
54+
55+-- | Convert Pandoc to XWiki.
56+writeXWiki :: PandocMonad m => WriterOptions -> Pandoc -> m Text
57+writeXWiki _ (Pandoc _ blocks) = do
58+ let env = WriterState { listLevel = "" }
59+ body <- runReaderT (blockListToXWiki blocks) env
60+ return $ body
61+
62+-- | Concatenates strings with line breaks between them.
63+vcat :: [Text] -> Text
64+vcat = intercalate "\n"
65+
66+-- If an id is provided, we can generate an anchor using the id macro
67+-- https://extensions.xwiki.org/xwiki/bin/view/Extension/Id%20Macro
68+genAnchor :: String -> Text
69+genAnchor id' = if null id'
70+ then ""
71+ else pack $ "{{id name=\"" ++ id' ++ "\" /}}"
72+
73+blockListToXWiki :: PandocMonad m => [Block] -> XWikiReader m Text
74+blockListToXWiki blocks =
75+ fmap vcat $ mapM blockToXWiki blocks
76+
77+blockToXWiki :: PandocMonad m => Block -> XWikiReader m Text
78+
79+blockToXWiki Null = return ""
80+
81+blockToXWiki (Div (id', _, _) blocks) = do
82+ content <- blockListToXWiki blocks
83+ return $ (genAnchor id') <> content
84+
85+blockToXWiki (Plain inlines) =
86+ inlineListToXWiki inlines
87+
88+blockToXWiki (Para inlines) = do
89+ contents <- inlineListToXWiki inlines
90+ return $ contents <> "\n"
91+
92+blockToXWiki (LineBlock lns) =
93+ blockToXWiki $ linesToPara lns
94+
95+blockToXWiki b@(RawBlock f str)
96+ | f == Format "xwiki" = return $ pack str
97+ | otherwise = "" <$ report (BlockNotRendered b)
98+
99+blockToXWiki HorizontalRule = return "\n----\n"
100+
101+blockToXWiki (Header level (id', _, _) inlines) = do
102+ contents <- inlineListToXWiki inlines
103+ let eqs = Text.replicate level "="
104+ return $ eqs <> " " <> contents <> " " <> (genAnchor id') <> eqs <> "\n"
105+
106+-- XWiki doesn't appear to differentiate between inline and block-form code, so we delegate
107+-- We do amend the text to ensure that the code markers are on their own lines, since this is a block
108+blockToXWiki (CodeBlock attrs str) = do
109+ contents <- inlineToXWiki (Code attrs ("\n" <> str <> "\n"))
110+ return $ "\n" <> contents <> "\n"
111+
112+blockToXWiki (BlockQuote blocks) = do
113+ blockText <- blockListToXWiki blocks
114+ let quoteLines = split (== '\n') blockText
115+ let prefixed = map (">" <>) quoteLines
116+ return $ vcat prefixed
117+
118+blockToXWiki (BulletList contents) = blockToXWikiList "*" $ contents
119+
120+blockToXWiki (OrderedList _ contents) = blockToXWikiList "1" $ contents
121+
122+blockToXWiki (DefinitionList items) = do
123+ lev <- asks listLevel
124+ contents <- local (\s -> s { listLevel = listLevel s <> ";" }) $ mapM definitionListItemToMediaWiki items
125+ return $ vcat contents <> if Text.null lev then "\n" else ""
126+
127+-- TODO: support more features
128+blockToXWiki (Table _ _ _ headers rows') = do
129+ headers' <- mapM (tableCellXWiki True) headers
130+ otherRows <- mapM formRow rows'
131+ return $ Text.unlines (Text.unwords headers':otherRows)
132+
133+formRow :: PandocMonad m => [[Block]] -> XWikiReader m Text
134+formRow row = do
135+ cellStrings <- mapM (tableCellXWiki False) row
136+ return $ Text.unwords cellStrings
137+
138+
139+tableCellXWiki :: PandocMonad m => Bool -> [Block] -> XWikiReader m Text
140+tableCellXWiki isHeader cell = do
141+ contents <- blockListToXWiki cell
142+ let cellBorder = if isHeader then "|=" else "|"
143+ return $ cellBorder <> contents
144+
145+
146+inlineListToXWiki :: PandocMonad m => [Inline] -> XWikiReader m Text
147+inlineListToXWiki lst =
148+ mconcat <$> mapM inlineToXWiki lst
149+
150+inlineToXWiki :: PandocMonad m => Inline -> XWikiReader m Text
151+
152+inlineToXWiki (Str str) = return $ escapeXWikiString $ pack str
153+
154+inlineToXWiki Space = return " "
155+
156+-- Special syntax for XWiki 2.0. This won't break table cells
157+inlineToXWiki LineBreak = return "\\\\"
158+
159+inlineToXWiki SoftBreak = return " "
160+
161+inlineToXWiki (Emph lst) = do
162+ contents <- inlineListToXWiki lst
163+ return $ "//" <> contents <> "//"
164+
165+inlineToXWiki (Strong lst) = do
166+ contents <- inlineListToXWiki lst
167+ return $ "**" <> contents <> "**"
168+
169+inlineToXWiki (Strikeout lst) = do
170+ contents <- inlineListToXWiki lst
171+ return $ "--" <> contents <> "--"
172+
173+inlineToXWiki (Superscript lst) = do
174+ contents <- inlineListToXWiki lst
175+ return $ "^^" <> contents <> "^^"
176+
177+inlineToXWiki (Subscript lst) = do
178+ contents <- inlineListToXWiki lst
179+ return $ ",," <> contents <> ",,"
180+
181+-- TODO: Not supported. Maybe escape to HTML?
182+inlineToXWiki (SmallCaps lst) = do
183+ contents <- inlineListToXWiki lst
184+ return contents
185+
186+inlineToXWiki (Quoted SingleQuote lst) = do
187+ contents <- inlineListToXWiki lst
188+ return $ "‘" <> contents <> "’"
189+
190+inlineToXWiki (Quoted DoubleQuote lst) = do
191+ contents <- inlineListToXWiki lst
192+ return $ "“" <> contents <> "”"
193+
194+inlineToXWiki (Code (_,classes,_) contents') = do
195+ let at = Set.fromList classes `Set.intersection` highlightingLangs
196+ let contents = pack contents'
197+ return $
198+ case Set.toList at of
199+ [] -> "{{code}}" <> contents <> "{{/code}}"
200+ (l:_) -> "{{code language=\"" <> (pack l) <> "\"}}" <> contents <> "{{/code}}"
201+
202+inlineToXWiki (Cite _ lst) = inlineListToXWiki lst
203+
204+-- FIXME: optionally support this (plugin?)
205+inlineToXWiki (Math _ str) = return $ "{{formula}}" <> (pack str) <> "{{/formula}}"
206+
207+inlineToXWiki il@(RawInline frmt str)
208+ | frmt == Format "xwiki" = return $ pack str
209+ | otherwise = "" <$ report (InlineNotRendered il)
210+
211+-- TODO: Handle anchors
212+inlineToXWiki (Link (id', _, _) txt (src, _)) = do
213+ label <- inlineListToXWiki txt
214+ case txt of
215+ [Str s] | isURI src && escapeURI s == src -> return $ (pack src) <> (genAnchor id')
216+ _ -> return $ "[[" <> label <> ">>" <> (pack src) <> "]]" <> (genAnchor id')
217+
218+inlineToXWiki (Image _ alt (source, tit)) = do
219+ alt' <- inlineListToXWiki alt
220+ let
221+ titText = pack tit
222+ params = intercalate " " $ filter (not . Text.null) [
223+ if Text.null alt' then "" else "alt=\"" <> alt' <> "\"",
224+ if Text.null titText then "" else "title=\"" <> titText <> "\""
225+ ]
226+ return $ "[[image:" <> (pack source) <> (if Text.null params then "" else "||" <> params) <> "]]"
227+
228+inlineToXWiki (Note contents) = do
229+ contents' <- blockListToXWiki contents
230+ return $ "{{footnote}}" <> (Text.strip contents') <> "{{/footnote}}"
231+
232+-- TODO: support attrs other than id (anchor)
233+inlineToXWiki (Span (id', _, _) contents) = do
234+ contents' <- inlineListToXWiki contents
235+ return $ (genAnchor id') <> contents'
236+
237+-- Utility method since (for now) all lists are handled the same way
238+blockToXWikiList :: PandocMonad m => Text -> [[Block]] -> XWikiReader m Text
239+blockToXWikiList marker contents = do
240+ lev <- asks listLevel
241+ contents' <- local (\s -> s { listLevel = listLevel s <> marker } ) $ mapM listItemToXWiki contents
242+ return $ vcat contents' <> if Text.null lev then "\n" else ""
243+
244+
245+listItemToXWiki :: PandocMonad m => [Block] -> XWikiReader m Text
246+listItemToXWiki contents = do
247+ marker <- asks listLevel
248+ contents' <- blockListToXWiki contents
249+ return $ marker <> ". " <> (Text.strip contents')
250+
251+
252+-- | Convert definition list item (label, list of blocks) to MediaWiki.
253+definitionListItemToMediaWiki :: PandocMonad m
254+ => ([Inline],[[Block]])
255+ -> XWikiReader m Text
256+definitionListItemToMediaWiki (label, items) = do
257+ labelText <- inlineListToXWiki label
258+ contents <- mapM blockListToXWiki items
259+ marker <- asks listLevel
260+ return $ marker <> " " <> labelText <> "\n" <>
261+ intercalate "\n" (map (\d -> (Text.init marker) <> ": " <> d) contents)
262+
263+-- Escape the escape character, as well as formatting pairs
264+escapeXWikiString :: Text -> Text
265+escapeXWikiString s = foldr (uncurry replace) s $ zip ["--", "**", "//", "^^", ",,", "~"] ["~-~-", "~*~*", "~/~/", "~^~^", "~,~,", "~~"]
266+
test/writer.xwikinew file+650
@@ -0,0 +1,650 @@
1+This is a set of tests for pandoc. Most of them are adapted from John Gruber’s markdown test suite.
2+
3+
4+----
5+
6+= Headers {{id name="headers" /}}=
7+
8+== Level 2 with an [[embedded link>>/url]] {{id name="level-2-with-an-embedded-link" /}}==
9+
10+=== Level 3 with //emphasis// {{id name="level-3-with-emphasis" /}}===
11+
12+==== Level 4 {{id name="level-4" /}}====
13+
14+===== Level 5 {{id name="level-5" /}}=====
15+
16+= Level 1 {{id name="level-1" /}}=
17+
18+== Level 2 with //emphasis// {{id name="level-2-with-emphasis" /}}==
19+
20+=== Level 3 {{id name="level-3" /}}===
21+
22+with no blank line
23+
24+== Level 2 {{id name="level-2" /}}==
25+
26+with no blank line
27+
28+
29+----
30+
31+= Paragraphs {{id name="paragraphs" /}}=
32+
33+Here’s a regular paragraph.
34+
35+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.
36+
37+Here’s one with a bullet. * criminey.
38+
39+There should be a hard line break\\here.
40+
41+
42+----
43+
44+= Block Quotes {{id name="block-quotes" /}}=
45+
46+E-mail style:
47+
48+>This is a block quote. It is pretty short.
49+>
50+>Code in a block quote:
51+>
52+>
53+>{{code}}
54+>sub status {
55+> print "working";
56+>}
57+>{{/code}}
58+>
59+>A list:
60+>
61+>1. item one
62+>1. item two
63+>
64+>Nested block quotes:
65+>
66+>>nested
67+>>
68+>>nested
69+>>
70+This should not be a block quote: 2 > 1.
71+
72+And a following paragraph.
73+
74+
75+----
76+
77+= Code Blocks {{id name="code-blocks" /}}=
78+
79+Code:
80+
81+
82+{{code}}
83+---- (should be four hyphens)
84+
85+sub status {
86+ print "working";
87+}
88+
89+this code block is indented by one tab
90+{{/code}}
91+
92+And:
93+
94+
95+{{code}}
96+ this code block is indented by two tabs
97+
98+These should not be escaped: \$ \\ \> \[ \{
99+{{/code}}
100+
101+
102+----
103+
104+= Lists {{id name="lists" /}}=
105+
106+== Unordered {{id name="unordered" /}}==
107+
108+Asterisks tight:
109+
110+*. asterisk 1
111+*. asterisk 2
112+*. asterisk 3
113+
114+Asterisks loose:
115+
116+*. asterisk 1
117+*. asterisk 2
118+*. asterisk 3
119+
120+Pluses tight:
121+
122+*. Plus 1
123+*. Plus 2
124+*. Plus 3
125+
126+Pluses loose:
127+
128+*. Plus 1
129+*. Plus 2
130+*. Plus 3
131+
132+Minuses tight:
133+
134+*. Minus 1
135+*. Minus 2
136+*. Minus 3
137+
138+Minuses loose:
139+
140+*. Minus 1
141+*. Minus 2
142+*. Minus 3
143+
144+== Ordered {{id name="ordered" /}}==
145+
146+Tight:
147+
148+1. First
149+1. Second
150+1. Third
151+
152+and:
153+
154+1. One
155+1. Two
156+1. Three
157+
158+Loose using tabs:
159+
160+1. First
161+1. Second
162+1. Third
163+
164+and using spaces:
165+
166+1. One
167+1. Two
168+1. Three
169+
170+Multiple paragraphs:
171+
172+1. Item 1, graf one.
173+
174+Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.
175+1. Item 2.
176+1. Item 3.
177+
178+== Nested {{id name="nested" /}}==
179+
180+*. Tab
181+**. Tab
182+***. Tab
183+
184+Here’s another:
185+
186+1. First
187+1. Second:
188+1*. Fee
189+1*. Fie
190+1*. Foe
191+1. Third
192+
193+Same thing but with paragraphs:
194+
195+1. First
196+1. Second:
197+
198+1*. Fee
199+1*. Fie
200+1*. Foe
201+1. Third
202+
203+== Tabs and spaces {{id name="tabs-and-spaces" /}}==
204+
205+*. this is a list item indented with tabs
206+*. this is a list item indented with spaces
207+
208+**. this is an example list item indented with tabs
209+**. this is an example list item indented with spaces
210+
211+== Fancy list markers {{id name="fancy-list-markers" /}}==
212+
213+1. begins with 2
214+1. and now 3
215+
216+with a continuation
217+
218+11. sublist with roman numerals, starting with 4
219+11. more items
220+111. a subsublist
221+111. a subsublist
222+
223+Nesting:
224+
225+1. Upper Alpha
226+11. Upper Roman.
227+111. Decimal start with 6
228+1111. Lower alpha with paren
229+
230+Autonumbering:
231+
232+1. Autonumber.
233+1. More.
234+11. Nested.
235+
236+Should not be a list item:
237+
238+M.A. 2007
239+
240+B. Williams
241+
242+
243+----
244+
245+= Definition Lists {{id name="definition-lists" /}}=
246+
247+Tight using spaces:
248+
249+; apple
250+: red fruit
251+; orange
252+: orange fruit
253+; banana
254+: yellow fruit
255+
256+Tight using tabs:
257+
258+; apple
259+: red fruit
260+; orange
261+: orange fruit
262+; banana
263+: yellow fruit
264+
265+Loose:
266+
267+; apple
268+: red fruit
269+
270+; orange
271+: orange fruit
272+
273+; banana
274+: yellow fruit
275+
276+
277+Multiple blocks with italics:
278+
279+; //apple//
280+: red fruit
281+
282+contains seeds, crisp, pleasant to taste
283+
284+; //orange//
285+: orange fruit
286+
287+
288+{{code}}
289+{ orange code block }
290+{{/code}}
291+
292+>orange block quote
293+>
294+
295+Multiple definitions, tight:
296+
297+; apple
298+: red fruit
299+: computer
300+; orange
301+: orange fruit
302+: bank
303+
304+Multiple definitions, loose:
305+
306+; apple
307+: red fruit
308+
309+: computer
310+
311+; orange
312+: orange fruit
313+
314+: bank
315+
316+
317+Blank line after term, indented marker, alternate markers:
318+
319+; apple
320+: red fruit
321+
322+: computer
323+
324+; orange
325+: orange fruit
326+
327+;1. sublist
328+;1. sublist
329+
330+= HTML Blocks {{id name="html-blocks" /}}=
331+
332+Simple block on one line:
333+
334+foo
335+And nested without indentation:
336+
337+foo
338+
339+bar
340+Interpreted markdown in a table:
341+
342+
343+
344+
345+This is //emphasized//
346+
347+
348+And this is **strong**
349+
350+
351+
352+
353+Here’s a simple block:
354+
355+foo
356+
357+This should be a code block, though:
358+
359+
360+{{code}}
361+<div>
362+ foo
363+</div>
364+{{/code}}
365+
366+As should this:
367+
368+
369+{{code}}
370+<div>foo</div>
371+{{/code}}
372+
373+Now, nested:
374+
375+foo
376+This should just be an HTML comment:
377+
378+
379+Multiline:
380+
381+
382+
383+Code block:
384+
385+
386+{{code}}
387+<!-- Comment -->
388+{{/code}}
389+
390+Just plain comment, with trailing spaces on the line:
391+
392+
393+Code:
394+
395+
396+{{code}}
397+<hr />
398+{{/code}}
399+
400+Hr’s:
401+
402+
403+
404+
405+
406+
407+
408+
409+
410+
411+
412+----
413+
414+= Inline Markup {{id name="inline-markup" /}}=
415+
416+This is //emphasized//, and so //is this//.
417+
418+This is **strong**, and so **is this**.
419+
420+An //[[emphasized link>>/url]]//.
421+
422+**//This is strong and em.//**
423+
424+So is **//this//** word.
425+
426+**//This is strong and em.//**
427+
428+So is **//this//** word.
429+
430+This is code: {{code}}>{{/code}}, {{code}}${{/code}}, {{code}}\{{/code}}, {{code}}\${{/code}}, {{code}}<html>{{/code}}.
431+
432+--This is //strikeout//.--
433+
434+Superscripts: a^^bc^^d a^^//hello//^^ a^^hello there^^.
435+
436+Subscripts: H,,2,,O, H,,23,,O, H,,many of them,,O.
437+
438+These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~~b c~~d.
439+
440+
441+----
442+
443+= Smart quotes, ellipses, dashes {{id name="smart-quotes-ellipses-dashes" /}}=
444+
445+“Hello,” said the spider. “‘Shelob’ is my name.”
446+
447+‘A’, ‘B’, and ‘C’ are letters.
448+
449+‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’
450+
451+‘He said, “I want to go.”’ Were you alive in the 70’s?
452+
453+Here is some quoted ‘{{code}}code{{/code}}’ and a “[[quoted link>>http://example.com/?foo=1&bar=2]]”.
454+
455+Some dashes: one—two — three—four — five.
456+
457+Dashes between numbers: 5–7, 255–66, 1987–1999.
458+
459+Ellipses…and…and….
460+
461+
462+----
463+
464+= LaTeX {{id name="latex" /}}=
465+
466+*.
467+*. {{formula}}2+2=4{{/formula}}
468+*. {{formula}}x \in y{{/formula}}
469+*. {{formula}}\alpha \wedge \omega{{/formula}}
470+*. {{formula}}223{{/formula}}
471+*. {{formula}}p{{/formula}}-Tree
472+*. Here’s some display math: {{formula}}\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}{{/formula}}
473+*. Here’s one that has a line break in it: {{formula}}\alpha + \omega \times x^2{{/formula}}.
474+
475+These shouldn’t be math:
476+
477+*. To get the famous equation, write {{code}}$e = mc^2${{/code}}.
478+*. $22,000 is a //lot// of money. So is $34,000. (It worked if “lot” is emphasized.)
479+*. Shoes ($20) and socks ($5).
480+*. Escaped {{code}}${{/code}}: $73 //this should be emphasized// 23$.
481+
482+Here’s a LaTeX table:
483+
484+
485+
486+----
487+
488+= Special Characters {{id name="special-characters" /}}=
489+
490+Here is some unicode:
491+
492+*. I hat: Î
493+*. o umlaut: ö
494+*. section: §
495+*. set membership: ∈
496+*. copyright: ©
497+
498+AT&T has an ampersand in their name.
499+
500+AT&T is another way to write it.
501+
502+This & that.
503+
504+4 < 5.
505+
506+6 > 5.
507+
508+Backslash: \
509+
510+Backtick: `
511+
512+Asterisk: *
513+
514+Underscore: _
515+
516+Left brace: {
517+
518+Right brace: }
519+
520+Left bracket: [
521+
522+Right bracket: ]
523+
524+Left paren: (
525+
526+Right paren: )
527+
528+Greater-than: >
529+
530+Hash: #
531+
532+Period: .
533+
534+Bang: !
535+
536+Plus: +
537+
538+Minus: -
539+
540+
541+----
542+
543+= Links {{id name="links" /}}=
544+
545+== Explicit {{id name="explicit" /}}==
546+
547+Just a [[URL>>/url/]].
548+
549+[[URL and title>>/url/]].
550+
551+[[URL and title>>/url/]].
552+
553+[[URL and title>>/url/]].
554+
555+[[URL and title>>/url/]]
556+
557+[[URL and title>>/url/]]
558+
559+[[with_underscore>>/url/with_underscore]]
560+
561+[[Email link>>mailto:nobody@nowhere.net]]
562+
563+[[Empty>>]].
564+
565+== Reference {{id name="reference" /}}==
566+
567+Foo [[bar>>/url/]].
568+
569+With [[embedded [brackets]>>/url/]].
570+
571+[[b>>/url/]] by itself should be a link.
572+
573+Indented [[once>>/url]].
574+
575+Indented [[twice>>/url]].
576+
577+Indented [[thrice>>/url]].
578+
579+This should [not][] be a link.
580+
581+
582+{{code}}
583+[not]: /url
584+{{/code}}
585+
586+Foo [[bar>>/url/]].
587+
588+Foo [[biz>>/url/]].
589+
590+== With ampersands {{id name="with-ampersands" /}}==
591+
592+Here’s a [[link with an ampersand in the URL>>http://example.com/?foo=1&bar=2]].
593+
594+Here’s a link with an amersand in the link text: [[AT&T>>http://att.com/]].
595+
596+Here’s an [[inline link>>/script?foo=1&bar=2]].
597+
598+Here’s an [[inline link in pointy braces>>/script?foo=1&bar=2]].
599+
600+== Autolinks {{id name="autolinks" /}}==
601+
602+With an ampersand: http://example.com/?foo=1&bar=2
603+
604+*. In a list?
605+*. http://example.com/
606+*. It should.
607+
608+An e-mail address: [[nobody@nowhere.net>>mailto:nobody@nowhere.net]]
609+
610+>Blockquoted: http://example.com/
611+>
612+Auto-links should not occur here: {{code}}<http://example.com/>{{/code}}
613+
614+
615+{{code}}
616+or here: <http://example.com/>
617+{{/code}}
618+
619+
620+----
621+
622+= Images {{id name="images" /}}=
623+
624+From “Voyage dans la Lune” by Georges Melies (1902):
625+
626+[[image:lalune.jpg||alt="lalune" title="fig:Voyage dans la Lune"]]
627+
628+Here is a movie [[image:movie.jpg||alt="movie"]] icon.
629+
630+
631+----
632+
633+= Footnotes {{id name="footnotes" /}}=
634+
635+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.{{/footnote}} and another.{{footnote}}Here’s the long note. This one contains multiple blocks.
636+
637+Subsequent blocks are indented to show that they belong to the footnote (as with list items).
638+
639+
640+{{code}}
641+ { <code> }
642+{{/code}}
643+
644+If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.{{/footnote}} This should //not// be a footnote reference, because it contains a space.[^my note] Here is an inline note.{{footnote}}This is //easier// to type. Inline notes may contain [[links>>http://google.com]] and {{code}}]{{/code}} verbatim characters, as well as [bracketed text].{{/footnote}}
645+
646+>Notes can go in quotes.{{footnote}}In quote.{{/footnote}}
647+>
648+1. And in list items.{{footnote}}In list.{{/footnote}}
649+
650+This paragraph should not be part of the note, as it is not indented.