pandoc (empty) → 0.4
raw patch · 170 files changed
+31770/−0 lines, 170 filesdep +basedep +mtldep +parsecbuild-type:Customsetup-changedbinary-added
Dependencies added: base, mtl, parsec, regex-compat, xhtml
Files
- BUGS +2/−0
- COPYING +340/−0
- INSTALL +130/−0
- Makefile +391/−0
- PROFILING +10/−0
- README +911/−0
- Setup.hs +2/−0
- debian/changelog +644/−0
- debian/compat +1/−0
- debian/control +90/−0
- debian/copyright +82/−0
- debian/pandoc-doc.doc-base +11/−0
- debian/pandoc-doc.docs +1/−0
- debian/pandoc.dirs +1/−0
- debian/rules +122/−0
- freebsd/Makefile +44/−0
- freebsd/distinfo +3/−0
- freebsd/pkg-descr +19/−0
- hsmarkdown +5/−0
- html2markdown +216/−0
- man/man1/hsmarkdown.1.md +42/−0
- man/man1/html2markdown.1.md +92/−0
- man/man1/markdown2pdf.1.md +69/−0
- man/man1/pandoc.1.md +180/−0
- markdown2pdf +140/−0
- osx/Description.plist +10/−0
- osx/Info.plist +42/−0
- osx/Welcome +18/−0
- osx/uninstall-pandoc +43/−0
- pandoc.cabal +61/−0
- src/ASCIIMathML.js +945/−0
- src/Main.hs +494/−0
- src/Text/Pandoc.hs +105/−0
- src/Text/Pandoc/ASCIIMathML.hs +14/−0
- src/Text/Pandoc/Blocks.hs +145/−0
- src/Text/Pandoc/CharacterReferences.hs +335/−0
- src/Text/Pandoc/Definition.hs +116/−0
- src/Text/Pandoc/Readers/HTML.hs +486/−0
- src/Text/Pandoc/Readers/LaTeX.hs +648/−0
- src/Text/Pandoc/Readers/Markdown.hs +908/−0
- src/Text/Pandoc/Readers/RST.hs +646/−0
- src/Text/Pandoc/Shared.hs +818/−0
- src/Text/Pandoc/UTF8.hs +44/−0
- src/Text/Pandoc/Writers/ConTeXt.hs +248/−0
- src/Text/Pandoc/Writers/DefaultHeaders.hs +59/−0
- src/Text/Pandoc/Writers/Docbook.hs +297/−0
- src/Text/Pandoc/Writers/HTML.hs +446/−0
- src/Text/Pandoc/Writers/LaTeX.hs +281/−0
- src/Text/Pandoc/Writers/Man.hs +298/−0
- src/Text/Pandoc/Writers/Markdown.hs +343/−0
- src/Text/Pandoc/Writers/RST.hs +329/−0
- src/Text/Pandoc/Writers/RTF.hs +286/−0
- src/Text/Pandoc/Writers/S5.hs +140/−0
- src/headers/ConTeXtHeader +61/−0
- src/headers/DocbookHeader +3/−0
- src/headers/LaTeXHeader +5/−0
- src/headers/RTFHeader +4/−0
- src/headers/S5Header +3/−0
- src/templates/ASCIIMathML.hs +7/−0
- src/templates/DefaultHeaders.hs +52/−0
- src/templates/Makefile +20/−0
- src/templates/S5.hs +133/−0
- src/templates/fillTemplates.pl +131/−0
- src/ui/default/blank.gif binary
- src/ui/default/bodybg.gif binary
- src/ui/default/framing.css +23/−0
- src/ui/default/iepngfix.htc +42/−0
- src/ui/default/opera.css +7/−0
- src/ui/default/outline.css +15/−0
- src/ui/default/pretty.css +86/−0
- src/ui/default/print.css +24/−0
- src/ui/default/s5-core.css +9/−0
- src/ui/default/slides.css +3/−0
- src/ui/default/slides.js +553/−0
- src/wrappers/common.sh +43/−0
- src/wrappers/hsmarkdown.in +5/−0
- src/wrappers/html2markdown.in +157/−0
- src/wrappers/markdown2pdf.in +81/−0
- src/wrappers/tempdir.sh +18/−0
- tests/MarkdownTest_1.0.3/MarkdownTest.pl +176/−0
- tests/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html +17/−0
- tests/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text +21/−0
- tests/MarkdownTest_1.0.3/Tests/Auto links.html +18/−0
- tests/MarkdownTest_1.0.3/Tests/Auto links.text +13/−0
- tests/MarkdownTest_1.0.3/Tests/Backslash escapes.html +118/−0
- tests/MarkdownTest_1.0.3/Tests/Backslash escapes.text +120/−0
- tests/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html +15/−0
- tests/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text +11/−0
- tests/MarkdownTest_1.0.3/Tests/Code Blocks.html +18/−0
- tests/MarkdownTest_1.0.3/Tests/Code Blocks.text +14/−0
- tests/MarkdownTest_1.0.3/Tests/Code Spans.html +6/−0
- tests/MarkdownTest_1.0.3/Tests/Code Spans.text +6/−0
- tests/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html +8/−0
- tests/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text +8/−0
- tests/MarkdownTest_1.0.3/Tests/Horizontal rules.html +71/−0
- tests/MarkdownTest_1.0.3/Tests/Horizontal rules.text +67/−0
- tests/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html +15/−0
- tests/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text +15/−0
- tests/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html +72/−0
- tests/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text +69/−0
- tests/MarkdownTest_1.0.3/Tests/Inline HTML comments.html +13/−0
- tests/MarkdownTest_1.0.3/Tests/Inline HTML comments.text +13/−0
- tests/MarkdownTest_1.0.3/Tests/Links, inline style.html +11/−0
- tests/MarkdownTest_1.0.3/Tests/Links, inline style.text +12/−0
- tests/MarkdownTest_1.0.3/Tests/Links, reference style.html +52/−0
- tests/MarkdownTest_1.0.3/Tests/Links, reference style.text +71/−0
- tests/MarkdownTest_1.0.3/Tests/Links, shortcut references.html +9/−0
- tests/MarkdownTest_1.0.3/Tests/Links, shortcut references.text +20/−0
- tests/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html +3/−0
- tests/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text +7/−0
- tests/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html +314/−0
- tests/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text +306/−0
- tests/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html +942/−0
- tests/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text +888/−0
- tests/MarkdownTest_1.0.3/Tests/Nested blockquotes.html +9/−0
- tests/MarkdownTest_1.0.3/Tests/Nested blockquotes.text +5/−0
- tests/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html +148/−0
- tests/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text +131/−0
- tests/MarkdownTest_1.0.3/Tests/Strong and em together.html +7/−0
- tests/MarkdownTest_1.0.3/Tests/Strong and em together.text +7/−0
- tests/MarkdownTest_1.0.3/Tests/Tabs.html +25/−0
- tests/MarkdownTest_1.0.3/Tests/Tabs.text +21/−0
- tests/MarkdownTest_1.0.3/Tests/Tidyness.html +8/−0
- tests/MarkdownTest_1.0.3/Tests/Tidyness.text +5/−0
- tests/bodybg.gif binary
- tests/generate.sh +12/−0
- tests/html-reader.html +463/−0
- tests/html-reader.native +346/−0
- tests/insert +1/−0
- tests/lalune.jpg binary
- tests/movie.jpg binary
- tests/rst-reader.native +211/−0
- tests/rst-reader.rst +387/−0
- tests/runtests.pl +114/−0
- tests/s5.basic.html +790/−0
- tests/s5.fancy.html +1702/−0
- tests/s5.fragment.html +15/−0
- tests/s5.inserts.html +36/−0
- tests/s5.native +9/−0
- tests/tables.context +136/−0
- tests/tables.docbook +287/−0
- tests/tables.html +207/−0
- tests/tables.latex +140/−0
- tests/tables.man +205/−0
- tests/tables.markdown +60/−0
- tests/tables.native +84/−0
- tests/tables.rst +71/−0
- tests/tables.rtf +281/−0
- tests/tables.txt +57/−0
- tests/testsuite.native +398/−0
- tests/testsuite.txt +701/−0
- tests/writer.context +764/−0
- tests/writer.docbook +1274/−0
- tests/writer.html +1112/−0
- tests/writer.latex +690/−0
- tests/writer.man +804/−0
- tests/writer.markdown +717/−0
- tests/writer.native +398/−0
- tests/writer.rst +871/−0
- tests/writer.rtf +442/−0
- web/Makefile +37/−0
- web/S5DEMO +19/−0
- web/config.xsl +9/−0
- web/demos +71/−0
- web/docbook.css +29/−0
- web/footer.html +4/−0
- web/index.txt +166/−0
- web/mkdemos.pl +31/−0
- web/myheader.tex +5/−0
- web/pandoc.css +71/−0
+ BUGS view
@@ -0,0 +1,2 @@+To view a list of known bugs, or to enter a bug report, please use+Pandoc's issue tracker: <http://code.google.com/p/pandoc/issues/list>
+ COPYING view
@@ -0,0 +1,340 @@+ GNU GENERAL PUBLIC LICENSE+ Version 2, June 1991++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++ Preamble++ The licenses for most software are designed to take away your+freedom to share and change it. By contrast, the GNU General Public+License is intended to guarantee your freedom to share and change free+software--to make sure the software is free for all its users. This+General Public License applies to most of the Free Software+Foundation's software and to any other program whose authors commit to+using it. (Some other Free Software Foundation software is covered by+the GNU Library General Public License instead.) You can apply it to+your programs, too.++ When we speak of free software, we are referring to freedom, not+price. Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+this service if you wish), that you receive source code or can get it+if you want it, that you can change the software or use pieces of it+in new free programs; and that you know you can do these things.++ To protect your rights, we need to make restrictions that forbid+anyone to deny you these rights or to ask you to surrender the rights.+These restrictions translate to certain responsibilities for you if you+distribute copies of the software, or if you modify it.++ For example, if you distribute copies of such a program, whether+gratis or for a fee, you must give the recipients all the rights that+you have. You must make sure that they, too, receive or can get the+source code. And you must show them these terms so they know their+rights.++ We protect your rights with two steps: (1) copyright the software, and+(2) offer you this license which gives you legal permission to copy,+distribute and/or modify the software.++ Also, for each author's protection and ours, we want to make certain+that everyone understands that there is no warranty for this free+software. If the software is modified by someone else and passed on, we+want its recipients to know that what they have is not the original, so+that any problems introduced by others will not reflect on the original+authors' reputations.++ Finally, any free program is threatened constantly by software+patents. We wish to avoid the danger that redistributors of a free+program will individually obtain patent licenses, in effect making the+program proprietary. To prevent this, we have made it clear that any+patent must be licensed for everyone's free use or not licensed at all.++ The precise terms and conditions for copying, distribution and+modification follow.++ GNU GENERAL PUBLIC LICENSE+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION++ 0. This License applies to any program or other work which contains+a notice placed by the copyright holder saying it may be distributed+under the terms of this General Public License. The "Program", below,+refers to any such program or work, and a "work based on the Program"+means either the Program or any derivative work under copyright law:+that is to say, a work containing the Program or a portion of it,+either verbatim or with modifications and/or translated into another+language. (Hereinafter, translation is included without limitation in+the term "modification".) Each licensee is addressed as "you".++Activities other than copying, distribution and modification are not+covered by this License; they are outside its scope. The act of+running the Program is not restricted, and the output from the Program+is covered only if its contents constitute a work based on the+Program (independent of having been made by running the Program).+Whether that is true depends on what the Program does.++ 1. You may copy and distribute verbatim copies of the Program's+source code as you receive it, in any medium, provided that you+conspicuously and appropriately publish on each copy an appropriate+copyright notice and disclaimer of warranty; keep intact all the+notices that refer to this License and to the absence of any warranty;+and give any other recipients of the Program a copy of this License+along with the Program.++You may charge a fee for the physical act of transferring a copy, and+you may at your option offer warranty protection in exchange for a fee.++ 2. You may modify your copy or copies of the Program or any portion+of it, thus forming a work based on the Program, and copy and+distribute such modifications or work under the terms of Section 1+above, provided that you also meet all of these conditions:++ a) You must cause the modified files to carry prominent notices+ stating that you changed the files and the date of any change.++ b) You must cause any work that you distribute or publish, that in+ whole or in part contains or is derived from the Program or any+ part thereof, to be licensed as a whole at no charge to all third+ parties under the terms of this License.++ c) If the modified program normally reads commands interactively+ when run, you must cause it, when started running for such+ interactive use in the most ordinary way, to print or display an+ announcement including an appropriate copyright notice and a+ notice that there is no warranty (or else, saying that you provide+ a warranty) and that users may redistribute the program under+ these conditions, and telling the user how to view a copy of this+ License. (Exception: if the Program itself is interactive but+ does not normally print such an announcement, your work based on+ the Program is not required to print an announcement.)++These requirements apply to the modified work as a whole. If+identifiable sections of that work are not derived from the Program,+and can be reasonably considered independent and separate works in+themselves, then this License, and its terms, do not apply to those+sections when you distribute them as separate works. But when you+distribute the same sections as part of a whole which is a work based+on the Program, the distribution of the whole must be on the terms of+this License, whose permissions for other licensees extend to the+entire whole, and thus to each and every part regardless of who wrote it.++Thus, it is not the intent of this section to claim rights or contest+your rights to work written entirely by you; rather, the intent is to+exercise the right to control the distribution of derivative or+collective works based on the Program.++In addition, mere aggregation of another work not based on the Program+with the Program (or with a work based on the Program) on a volume of+a storage or distribution medium does not bring the other work under+the scope of this License.++ 3. You may copy and distribute the Program (or a work based on it,+under Section 2) in object code or executable form under the terms of+Sections 1 and 2 above provided that you also do one of the following:++ a) Accompany it with the complete corresponding machine-readable+ source code, which must be distributed under the terms of Sections+ 1 and 2 above on a medium customarily used for software interchange; or,++ b) Accompany it with a written offer, valid for at least three+ years, to give any third party, for a charge no more than your+ cost of physically performing source distribution, a complete+ machine-readable copy of the corresponding source code, to be+ distributed under the terms of Sections 1 and 2 above on a medium+ customarily used for software interchange; or,++ c) Accompany it with the information you received as to the offer+ to distribute corresponding source code. (This alternative is+ allowed only for noncommercial distribution and only if you+ received the program in object code or executable form with such+ an offer, in accord with Subsection b above.)++The source code for a work means the preferred form of the work for+making modifications to it. For an executable work, complete source+code means all the source code for all modules it contains, plus any+associated interface definition files, plus the scripts used to+control compilation and installation of the executable. However, as a+special exception, the source code distributed need not include+anything that is normally distributed (in either source or binary+form) with the major components (compiler, kernel, and so on) of the+operating system on which the executable runs, unless that component+itself accompanies the executable.++If distribution of executable or object code is made by offering+access to copy from a designated place, then offering equivalent+access to copy the source code from the same place counts as+distribution of the source code, even though third parties are not+compelled to copy the source along with the object code.++ 4. You may not copy, modify, sublicense, or distribute the Program+except as expressly provided under this License. Any attempt+otherwise to copy, modify, sublicense or distribute the Program is+void, and will automatically terminate your rights under this License.+However, parties who have received copies, or rights, from you under+this License will not have their licenses terminated so long as such+parties remain in full compliance.++ 5. You are not required to accept this License, since you have not+signed it. However, nothing else grants you permission to modify or+distribute the Program or its derivative works. These actions are+prohibited by law if you do not accept this License. Therefore, by+modifying or distributing the Program (or any work based on the+Program), you indicate your acceptance of this License to do so, and+all its terms and conditions for copying, distributing or modifying+the Program or works based on it.++ 6. Each time you redistribute the Program (or any work based on the+Program), the recipient automatically receives a license from the+original licensor to copy, distribute or modify the Program subject to+these terms and conditions. You may not impose any further+restrictions on the recipients' exercise of the rights granted herein.+You are not responsible for enforcing compliance by third parties to+this License.++ 7. If, as a consequence of a court judgment or allegation of patent+infringement or for any other reason (not limited to patent issues),+conditions are imposed on you (whether by court order, agreement or+otherwise) that contradict the conditions of this License, they do not+excuse you from the conditions of this License. If you cannot+distribute so as to satisfy simultaneously your obligations under this+License and any other pertinent obligations, then as a consequence you+may not distribute the Program at all. For example, if a patent+license would not permit royalty-free redistribution of the Program by+all those who receive copies directly or indirectly through you, then+the only way you could satisfy both it and this License would be to+refrain entirely from distribution of the Program.++If any portion of this section is held invalid or unenforceable under+any particular circumstance, the balance of the section is intended to+apply and the section as a whole is intended to apply in other+circumstances.++It is not the purpose of this section to induce you to infringe any+patents or other property right claims or to contest validity of any+such claims; this section has the sole purpose of protecting the+integrity of the free software distribution system, which is+implemented by public license practices. Many people have made+generous contributions to the wide range of software distributed+through that system in reliance on consistent application of that+system; it is up to the author/donor to decide if he or she is willing+to distribute software through any other system and a licensee cannot+impose that choice.++This section is intended to make thoroughly clear what is believed to+be a consequence of the rest of this License.++ 8. If the distribution and/or use of the Program is restricted in+certain countries either by patents or by copyrighted interfaces, the+original copyright holder who places the Program under this License+may add an explicit geographical distribution limitation excluding+those countries, so that distribution is permitted only in or among+countries not thus excluded. In such case, this License incorporates+the limitation as if written in the body of this License.++ 9. The Free Software Foundation may publish revised and/or new versions+of the General Public License from time to time. Such new versions will+be similar in spirit to the present version, but may differ in detail to+address new problems or concerns.++Each version is given a distinguishing version number. If the Program+specifies a version number of this License which applies to it and "any+later version", you have the option of following the terms and conditions+either of that version or of any later version published by the Free+Software Foundation. If the Program does not specify a version number of+this License, you may choose any version ever published by the Free Software+Foundation.++ 10. If you wish to incorporate parts of the Program into other free+programs whose distribution conditions are different, write to the author+to ask for permission. For software which is copyrighted by the Free+Software Foundation, write to the Free Software Foundation; we sometimes+make exceptions for this. Our decision will be guided by the two goals+of preserving the free status of all derivatives of our free software and+of promoting the sharing and reuse of software generally.++ NO WARRANTY++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,+REPAIR OR CORRECTION.++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE+POSSIBILITY OF SUCH DAMAGES.++ END OF TERMS AND CONDITIONS++ How to Apply These Terms to Your New Programs++ If you develop a new program, and you want it to be of the greatest+possible use to the public, the best way to achieve this is to make it+free software which everyone can redistribute and change under these terms.++ To do so, attach the following notices to the program. It is safest+to attach them to the start of each source file to most effectively+convey the exclusion of warranty; and each file should have at least+the "copyright" line and a pointer to where the full notice is found.++ <one line to give the program's name and a brief idea of what it does.>+ Copyright (C) <year> <name of author>++ This program is free software; you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation; either version 2 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program; if not, write to the Free Software+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA+++Also add information on how to contact you by electronic and paper mail.++If the program is interactive, make it output a short notice like this+when it starts in an interactive mode:++ Gnomovision version 69, Copyright (C) year name of author+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.+ This is free software, and you are welcome to redistribute it+ under certain conditions; type `show c' for details.++The hypothetical commands `show w' and `show c' should show the appropriate+parts of the General Public License. Of course, the commands you use may+be called something other than `show w' and `show c'; they could even be+mouse-clicks or menu items--whatever suits your program.++You should also get your employer (if you work as a programmer) or your+school, if any, to sign a "copyright disclaimer" for the program, if+necessary. Here is a sample; alter the names:++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program+ `Gnomovision' (which makes passes at compilers) written by James Hacker.++ <signature of Ty Coon>, 1 April 1989+ Ty Coon, President of Vice++This General Public License does not permit incorporating your program into+proprietary programs. If your program is a subroutine library, you may+consider it more useful to permit linking proprietary applications with the+library. If this is what you want to do, use the GNU Library General+Public License instead of this License.
+ INSTALL view
@@ -0,0 +1,130 @@+% Installing pandoc++The following instructions are for installing pandoc from source. Binary+packages are also available for Windows, MacOS X, Linux (Debian and+derivatives), and FreeBSD. See the [pandoc home page] for more details.++[pandoc home page]: http://sophos.berkeley.edu/macfarlane/pandoc/++# Installing GHC++To compile Pandoc, you'll need [GHC] version 6.6 or greater. If+you don't have GHC already, you can get it from the [GHC Download]+page. If you're running MacOS X, you can also install GHC using+[MacPorts] or [Fink].++[GHC]: http://www.haskell.org/ghc/+[GHC Download]: http://www.haskell.org/ghc/download.html+[MacPorts]: http://macports.org+[Fink]: http://finkproject.org++You'll also need standard build tools: [GNU `make`], `sed`, `bash`,+and `perl`. These are standard on unix systems (including MacOS+X). If you're using Windows, you can install [Cygwin].++[Cygwin]: http://www.cygwin.com/+[GNU `make`]: http://www.gnu.org/software/make/++# Installing Pandoc++1. Change to the directory containing the Pandoc distribution.++2. Compile:++ make++ If you get "Unknown modifier" errors, it is probably because `make`+ on your system is not [GNU `make`]. Try using `gmake` instead.++3. See if it worked (optional, but recommended): ++ make test++4. Install:++ sudo make install++ Note: This installs `pandoc`, together with its wrappers and+ documentation, into the `/usr/local` directory. If you'd rather+ install `pandoc` somewhere else--say, in `/opt/local`--you can+ set the `PREFIX` environment variable:++ PREFIX=/opt/local sudo make install++ If you don't have root privileges or would prefer to install+ `pandoc` and the associated wrappers into your `~/bin` directory,+ type this instead:++ PREFIX=~ make install-exec++5. Build and install the Haskell libraries and library+ documentation (optional--for Haskell programmers only):++ make build-all+ sudo make install-all++ Note that building the library documentation requires [haddock].++[haddock]: http://www.haskell.org/haddock/ ++# Removing Pandoc++Each of the installation steps described above can be reversed:++ sudo make uninstall++ PREFIX=~ make uninstall-exec++ sudo make uninstall-all++# Other targets++The following 'make' targets should not be needed by the average user,+but are documented here for packagers and developers:++## Building and installing++* `configure`: Performs the needed preprocessing to create a proper+ Cabal package for Pandoc:+ - Builds `ASCIIMathML.hs`, `DefaultHeaders.hs`, and `S5.hs`+ from templates in `src/templates` and data in `src/ASCIIMathML.js`,+ `src/ui`, and `src/headers`.+ - Stores values of relevant environment variables in `vars` for+ persistence.+ - Runs Cabal's "configure" command.+* `build-exec`: Builds `pandoc` executable (using Cabal's "build"+ command) and creates the wrappers `html2markdown` and `markdown2pdf`+ from templates in `src/wrappers`.+* `build-doc`: Builds program documentation (e.g. `README.html`).+* `build-lib-doc`: Builds Haddock documentation for Pandoc libraries.+* `install-doc`, `uninstall-doc`: Installs/uninstalls user documentation+ and man pages.+* `install-lib-doc`, `uninstall-lib-doc`: Installs/uninstalls library+ documentation and man pages.+* `install-exec`, `uninstall-exec`: Installs/uninstalls programs+ (`pandoc` and wrappers).++## Testing++* `test`: Runs Pandoc's test suite. (All tests should pass.)+* `test-markdown`: Runs the Markdown regression test suite, using+ `pandoc --strict`. (Three of the tests will fail.)++## Cleaning++* `clean`: Restores directory to pre-build state, removing generated files.+* `distclean`: Like clean, but also cleans up files created by `make deb`.++## Packaging++* `tarball`: Creates a source tarball for distribution.+* `deb`: Creates debian packages in `..` directory.+* `osx-pkg-prep`: Prepares for building a MacOS X package.+* `osx-pkg`: Builds a MacOS X package (must be run as root, and on OS X).+ You should make `osx-pkg-prep` first (not as root).+* `osx-dmg`: Creates a compressed disk image containing Mac OS X package+ (must be run on OS X). You should make `osx-pkg` first.+* `win-pkg`: Creates a Windows binary package (presupposes `pandoc.exe`,+ which must be created by building Pandoc on a Windows machine).+* `website`: Creates Pandoc's website in `web/pandoc` directory.+
+ Makefile view
@@ -0,0 +1,391 @@+# Makefile for Pandoc.++#-------------------------------------------------------------------------------+# Constant names and commands in source tree+#-------------------------------------------------------------------------------+CABAL := pandoc.cabal+SRCDIR := src+MANDIR := man+TESTDIR := tests+BUILDDIR := dist+BUILDCONF := .setup-config+BUILDCMD := runhaskell Setup.hs+BUILDVARS := vars+CONFIGURE := configure++#-------------------------------------------------------------------------------+# Cabal constants+#-------------------------------------------------------------------------------+NAME := $(shell sed -ne 's/^[Nn]ame:[[:space:]]*//p' $(CABAL))+THIS := $(shell echo $(NAME) | tr A-Z a-z)+VERSION := $(shell sed -ne 's/^version[[:space:]]*=[[:space:]]*"\([^"]*\)"/\1/p' $(SRCDIR)/Main.hs)+RELNAME := $(THIS)-$(VERSION)+EXECSBASE := $(shell sed -ne 's/^[Ee]xecutable:[[:space:]]*//p' $(CABAL))++#-------------------------------------------------------------------------------+# Install targets+#-------------------------------------------------------------------------------+WRAPPERS := html2markdown markdown2pdf hsmarkdown+# Add .exe extensions if we're running Windows/Cygwin.+EXTENSION := $(shell uname | tr '[:upper:]' '[:lower:]' | \+ sed -ne 's/^cygwin.*$$/\.exe/p')+EXECS := $(addsuffix $(EXTENSION),$(EXECSBASE))+PROGS := $(EXECS) $(WRAPPERS) +MAIN := $(firstword $(EXECS))+DOCS := README.html README BUGS +MANPAGES := $(patsubst %.md,%,$(wildcard $(MANDIR)/man?/*.?.md))++#-------------------------------------------------------------------------------+# Variables to setup through environment+#-------------------------------------------------------------------------------++# Specify default values.+prefix := /usr/local+destdir := +# Attempt to set variables from a previous make session.+-include $(BUILDVARS)+# Fallback to defaults but allow to get the values from environment.+PREFIX ?= $(prefix)+DESTDIR ?= $(destdir)++#-------------------------------------------------------------------------------+# Installation paths+#-------------------------------------------------------------------------------+DESTPATH := $(DESTDIR)$(PREFIX)+BINPATH := $(DESTPATH)/bin+DATAPATH := $(DESTPATH)/share+LIBPATH := $(DESTPATH)/$(NAME)-$(VERSION)+DOCPATH := $(DATAPATH)/doc/$(THIS)+LIBDOCPATH := $(DATAPATH)/doc/$(THIS)-doc+MANPATH := $(DATAPATH)/man+PKGPATH := $(DATAPATH)/$(THIS)++#-------------------------------------------------------------------------------+# Generic Makefile variables+#-------------------------------------------------------------------------------+INSTALL := install -c+INSTALL_PROGRAM := $(INSTALL) -m 755+INSTALL_DATA := $(INSTALL) -m 644+STRIP := strip+GHC := ghc+GHC_PKG := ghc-pkg++#-------------------------------------------------------------------------------+# Recipes+#-------------------------------------------------------------------------------++# Default target.+.PHONY: all+all: build-program++# Document process rules.+%.html: % $(MAIN)+ ./$(MAIN) -s -S --toc $< >$@ || rm -f $@+%.tex: % $(MAIN)+ ./$(MAIN) -s -w latex $< >$@ || rm -f $@+%.rtf: % $(MAIN)+ ./$(MAIN) -s -w rtf $< >$@ || rm -f $@+%.pdf: % $(MAIN) markdown2pdf+ sh ./markdown2pdf $< || rm -f $@+%.txt: %+ perl -p -e 's/\n/\r\n/' $< > $@ || rm -f $@ # convert to DOS line endings+%.1: %.1.md $(MAIN)+ ./$(MAIN) -s -S -w man $< >$@ || rm -f $@++.PHONY: templates+templates: $(SRCDIR)/templates+ $(MAKE) -C $(SRCDIR)/templates++define generate-shell-script+echo "Generating $@..."; \+awk ' \+ /^[ \t]*###+ / { \+ lead = $$0; sub(/[^ \t].*$$/, "", lead); \+ t = "$(dir $<)/"$$2; \+ while (getline line < t > 0) \+ print lead line; \+ next; \+ } \+ { print } \+' <$< >$@+chmod +x $@+endef++.PHONY: wrappers+wrappers: $(WRAPPERS)+cleanup_files+=$(WRAPPERS)+$(WRAPPERS): %: $(SRCDIR)/wrappers/%.in $(SRCDIR)/wrappers/*.sh+ @$(generate-shell-script)++.PHONY: configure+cleanup_files+=$(BUILDDIR) $(BUILDCONF) $(BUILDVARS)+configure: $(BUILDCONF) templates+$(BUILDCONF): $(CABAL)+ $(BUILDCMD) configure --prefix=$(PREFIX)+ # Make configuration time settings persistent (definitely a hack).+ @echo "PREFIX?=$(PREFIX)" >$(BUILDVARS)+ @echo "DESTDIR?=$(DESTDIR)" >>$(BUILDVARS)++.PHONY: build+build: configure+ $(BUILDCMD) build++.PHONY: build-exec+build-exec: $(PROGS)+cleanup_files+=$(EXECS)+$(EXECS): build+ for f in $@; do \+ find $(BUILDDIR) -type f -name "$$f" \+ -perm +a=x -exec ln -s -f {} . \; ; \+ done++.PHONY: build-doc+cleanup_files+=README.html $(MANPAGES)+build-doc: $(DOCS) $(MANPAGES)++.PHONY: build-program+build-program: build-exec build-doc++.PHONY: build-lib-doc haddock+build-lib-doc: html+haddock: build-lib-doc+cleanup_files+=html+html/: configure+ -rm -rf html+ $(BUILDCMD) haddock && cp -r $(BUILDDIR)/doc/html .++.PHONY: build-all+build-all: build-program build-lib-doc++# User documents installation.+.PHONY: install-doc uninstall-doc+man_all:=$(patsubst $(MANDIR)/%,%,$(MANPAGES))+install-doc: build-doc+ $(INSTALL) -d $(DOCPATH) && $(INSTALL_DATA) $(DOCS) $(DOCPATH)/+ for f in $(man_all); do \+ $(INSTALL) -d $(MANPATH)/$$(dirname $$f); \+ $(INSTALL_DATA) $(MANDIR)/$$f $(MANPATH)/$$f; \+ done+uninstall-doc:+ -for f in $(DOCS); do rm -f $(DOCPATH)/$$f; done+ -for f in $(man_all); do rm -f $(MANPATH)/$$f; done+ -rmdir $(DOCPATH)++# Library documents installation.+.PHONY: install-lib-doc uninstall-lib-doc+install-lib-doc: build-lib-doc+ $(INSTALL) -d $(LIBDOCPATH) && cp -R html $(LIBDOCPATH)/+uninstall-lib-doc:+ -rm -rf $(LIBDOCPATH)/html+ -rmdir $(LIBDOCPATH)++# Helper to install the given files $(1) into the path $(2).+# It also has the ability to follow symlinks.+install-executable-files = \+ $(INSTALL) -d $(2); \+ for f in $(1); do \+ if [ -L $$f ]; then \+ f=$$(readlink $$f); \+ fi; \+ $(INSTALL_PROGRAM) $$f $(2)/; \+ done++# Program only installation.+.PHONY: install-exec uninstall-exec+install-exec: build-exec+ $(STRIP) $(EXECS)+ $(call install-executable-files,$(PROGS),$(BINPATH))+uninstall-exec:+ -for f in $(notdir $(PROGS)); do rm -f $(BINPATH)/$$f; done ;++# Program + user documents installation.+.PHONY: install-program uninstall-program+install-program: install-exec install-doc+uninstall-program: uninstall-exec uninstall-doc++.PHONY: install-all uninstall-all+# Install libraries+install-all: build-all install-doc install-lib-doc+ # Install the library (+ main executable) and register it.+ destdir=$(DESTDIR); \+ # Older Cabal versions have no '--destdir' option.+ if $(BUILDCMD) copy --help | grep -q '\-\-destdir'; then \+ opt="--destdir=$${destdir-/}"; \+ else \+ opt="--copy-prefix=$${destdir}$(PREFIX)"; \+ fi; \+ $(BUILDCMD) copy $$opt; \+ $(BUILDCMD) register+ # Note that, we are in the position of having to install the wrappers+ # separately, as Cabal installs the main exec along with the library.+ $(call install-executable-files,$(WRAPPERS),$(BINPATH))+uninstall-all: uninstall-program uninstall-lib-doc+ -pkg_id="$(NAME)-$(VERSION)"; \+ libdir=$$($(GHC_PKG) field $$pkg_id library-dirs 2>/dev/null | \+ sed 's/^library-dirs: *//'); \+ if [ -d "$$libdir" ]; then \+ $(BUILDCMD) unregister; \+ rm -rf $$libdir; \+ rmdir $$(dirname $$libdir); \+ else \+ echo "*** Couldn't locate library files for pkgid: $$pkg_id. ***"; \+ fi++# Default installation recipe for a common deployment scenario.+.PHONY: install uninstall+install: install-program+uninstall: uninstall-program++# OSX packages: make osx-pkg-prep, then (as root) make osx-pkg+.PHONY: osx-pkg osx-pkg-prep+osx_dest:=osx-pkg-tmp+osx_src:=osx+doc_more:=COPYRIGHT.rtf $(osx_src)/Welcome.rtf+osx_pkg_name:=$(RELNAME).pkg+cleanup_files+=$(osx_dest) $(doc_more) $(osx_pkg_name)+osx-pkg-prep: $(osx_dest)+$(osx_dest)/: build-program $(doc_more)+ -rm -rf $(osx_dest)+ $(INSTALL) -d $(osx_dest)+ DESTDIR=$(osx_dest)/Package_root $(MAKE) install-program+ cp $(osx_src)/uninstall-pandoc $(osx_dest)/Package_root/usr/local/bin/+ find $(osx_dest) -type f -regex ".*bin/.*" | xargs chmod +x+ find $(osx_dest) -type f -regex ".*bin/$(notdir $(MAIN))" | xargs $(STRIP)+ $(INSTALL) -d $(osx_dest)/Resources+ ./$(MAIN) -s -S README -o $(osx_dest)/Resources/ReadMe.html+ cp COPYRIGHT.rtf $(osx_dest)/Resources/License.rtf+ sed -e 's#@PREFIX@#$(PREFIX)#g' $(osx_src)/Welcome.rtf > $(osx_dest)/Resources/Welcome.rtf+ sed -e 's/@VERSION@/$(VERSION)/g' $(osx_src)/Info.plist > $(osx_dest)/Info.plist+ cp $(osx_src)/Description.plist $(osx_dest)/+osx-pkg: $(osx_pkg_name)+$(osx_pkg_name)/: $(osx_dest)+ if [ "`id -u`" != 0 ]; then \+ echo "Root permissions needed to create OSX package!"; \+ exit 1; \+ fi+ find $(osx_dest) | xargs chown root:wheel+ PackageMaker -build -p $(osx_pkg_name) \+ -f $(osx_dest)/Package_root \+ -r $(osx_dest)/Resources \+ -i $(osx_dest)/Info.plist \+ -d $(osx_dest)/Description.plist+ chgrp admin $(osx_pkg_name)+ -rm -rf $(osx_dest)++.PHONY: osx-dmg+osx_dmg_name:=$(RELNAME).dmg+cleanup_files+=$(osx_dmg_name)+osx_udzo_name:=$(RELNAME).udzo.dmg+osx_dmg_volume:="$(NAME) $(VERSION)"+osx-dmg: $(osx_dmg_name)+$(osx_dmg_name): $(osx_pkg_name)+ -rm -f $(osx_dmg_name)+ hdiutil create $(osx_dmg_name) -size 05m -fs HFS+ -volname $(osx_dmg_volume)+ dev_handle=`hdid $(osx_dmg_name) | grep Apple_HFS | \+ perl -e '\$$_=<>; /^\\/dev\\/(disk.)/; print \$$1'`; \+ ditto $(osx_pkg_name) /Volumes/$(osx_dmg_volume)/$(osx_pkg_name); \+ hdiutil detach $$dev_handle+ hdiutil convert $(osx_dmg_name) -format UDZO -o $(osx_udzo_name)+ -rm -f $(osx_dmg_name)+ mv $(osx_udzo_name) $(osx_dmg_name)+++.PHONY: win-pkg+win_pkg_name:=$(RELNAME).zip+win_docs:=COPYING.txt COPYRIGHT.txt BUGS.txt README.txt README.html+cleanup_files+=$(win_pkg_name) $(win_docs)+win-pkg: $(win_pkg_name)+$(win_pkg_name): $(THIS).exe $(win_docs)+ zip -r $(win_pkg_name) $(THIS).exe $(win_docs)++.PHONY: test test-markdown+test: $(MAIN)+ @cd $(TESTDIR) && perl runtests.pl -s $(PWD)/$(MAIN)+compat:=$(PWD)/hsmarkdown+markdown_test_dirs:=$(wildcard $(TESTDIR)/MarkdownTest_*)+test-markdown: $(MAIN) $(compat)+ @for suite in $(markdown_test_dirs); do \+ ( \+ suite_version=$$(echo $$suite | sed -e 's/.*_//');\+ echo "-----------------------------------------";\+ echo "Running Markdown test suite version $${suite_version}.";\+ PATH=$(PWD):$$PATH; export PATH; cd $$suite && \+ perl MarkdownTest.pl -s $(compat) -tidy ; \+ ) \+ done++# Stolen and slightly improved from a GPLed Makefile. Credits to John Meacham.+src_all:=$(shell find $(SRCDIR) -type f -name '*hs' | egrep -v '^\./(_darcs|lib|test)/')+cleanup_files+=$(patsubst %,$(SRCDIR)/%,tags tags.sorted)+tags: $(src_all)+ cd $(SRCDIR) && hasktags -c $(src_all:$(SRCDIR)/%=%); \+ LC_ALL=C sort tags >tags.sorted; mv tags.sorted tags++.PHONY: tarball+tarball_name:=$(RELNAME).tar.gz+cleanup_files+=$(tarball_name)+tarball: $(tarball_name)+$(tarball_name):+ svn export . $(RELNAME)+ $(MAKE) -C $(RELNAME) templates+ $(MAKE) -C $(RELNAME) wrappers+ tar cvzf $(tarball_name) $(RELNAME)+ -rm -rf $(RELNAME)++.PHONY: deb+deb_name:=$(shell grep ^Package debian/control | cut -d' ' -f2 | head -n 1)+deb_version:=$(shell head -n 1 debian/changelog | cut -f2 -d' ' | tr -d '()')+deb_arch:=i386+deb_main:=$(deb_name)_$(deb_version)_$(deb_arch).deb+deb: debian+ @[ -x /usr/bin/fakeroot ] || { \+ echo "*** Please install fakeroot package. ***"; \+ exit 1; \+ }+ @[ -x /usr/bin/dpkg-buildpackage ] || { \+ echo "*** Please install dpkg-dev package. ***"; \+ exit 1; \+ }+ -mv $(BUILDVARS) $(BUILDVARS).old # backup settings + if [ -x /usr/bin/debuild ]; then \+ debuild -uc -us -i.svn -I.svn -i_darcs -I_darcs --lintian-opts -i; \+ else \+ echo "*** Please install devscripts package. ***"; \+ echo "*** Using dpkg-buildpackage for package building. ***"; \+ dpkg-buildpackage -rfakeroot -uc -us -i.svn -I.svn -i_darcs -I_darcs; \+ fi+ -mv $(BUILDVARS).old $(BUILDVARS) # restore ++.PHONY: website+web_src:=web+web_dest:=web/pandoc+make_page:=./$(MAIN) -s -S -B $(web_src)/header.html \+ -A $(web_src)/footer.html \+ -H $(web_src)/css +cleanup_files+=$(web_dest)+website: $(MAIN) html+ -rm -rf $(web_dest)+ ( \+ mkdir $(web_dest); \+ cp -r html $(web_dest)/doc; \+ cp $(web_src)/* $(web_dest)/; \+ sed -e 's#@PREFIX@#$(PREFIX)#g' $(osx_src)/Welcome > \+ $(web_dest)/osx-notes.txt; \+ cp changelog $(web_dest)/ ; \+ cp README $(web_dest)/ ; \+ cp INSTALL $(web_dest)/ ; \+ cp $(MANDIR)/man1/pandoc.1.md $(web_dest)/ ; \+ cp $(MANDIR)/man1/*.1 $(web_dest)/ ; \+ PANDOC_PATH=$(shell pwd) make -C $(web_dest) ; \+ ) || { rm -rf $(web_dest); exit 1; }++.PHONY: distclean clean+distclean: clean+ if [ -d debian ]; then \+ chmod +x debian/rules; fakeroot debian/rules clean; \+ fi++clean:+ make -C $(SRCDIR)/templates clean+ -if [ -f $(BUILDCONF) ]; then $(BUILDCMD) clean; fi+ -rm -rf $(cleanup_files)
+ PROFILING view
@@ -0,0 +1,10 @@+To use the GHC profiler:++first, add -auto-all to ghc-options in pandoc.cabal. then++make clean+make templates+runhaskell Setup.hs configure --enable-library-profiling --enable-executable-profiling+runhaskell Setup.hs build+dist/build/pandoc/pandoc +RTS -p -RTS [file]...+less pandoc.prof
+ README view
@@ -0,0 +1,911 @@+% Pandoc User's Guide+% John MacFarlane+% August 15, 2007++Pandoc is a [Haskell] library for converting from one markup format to+another, and a command-line tool that uses this library. It can read+[markdown] and (subsets of) [reStructuredText], [HTML], and [LaTeX], and+it can write [markdown], [reStructuredText], [HTML], [LaTeX], [ConTeXt],+[RTF], [DocBook XML], [groff man] pages, and [S5] HTML slide shows.+Pandoc's version of markdown contains some enhancements, like footnotes+and embedded LaTeX.++In contrast to existing tools for converting markdown to HTML, which+use regex substitutions, Pandoc has a modular design: it consists of a+set of readers, which parse text in a given format and produce a native+representation of the document, and a set of writers, which convert+this native representation into a target format. Thus, adding an input+or output format requires only adding a reader or writer.++[markdown]: http://daringfireball.net/projects/markdown/+[reStructuredText]: http://docutils.sourceforge.net/docs/ref/rst/introduction.html+[S5]: http://meyerweb.com/eric/tools/s5/+[HTML]: http://www.w3.org/TR/html40/+[LaTeX]: http://www.latex-project.org/+[ConTeXt]: http://www.pragma-ade.nl/ +[RTF]: http://en.wikipedia.org/wiki/Rich_Text_Format+[DocBook XML]: http://www.docbook.org/+[groff man]: http://developer.apple.com/DOCUMENTATION/Darwin/Reference/ManPages/man7/groff_man.7.html+[Haskell]: http://www.haskell.org/++© 2006-7 John MacFarlane (jgm at berkeley dot edu). Released under the+[GPL], version 2 or greater. This software carries no warranty of+any kind. (See COPYRIGHT for full copyright and warranty notices.)+Recai Oktaş (roktas at debian dot org) deserves credit for the build+system, the debian package, and the robust wrapper scripts.++[GPL]: http://www.gnu.org/copyleft/gpl.html "GNU General Public License"++Requirements+============++The `pandoc` program itself does not depend on any external libraries+or programs.++The wrapper script `html2markdown` requires++ - `pandoc` (which must be in the PATH)+ - a POSIX-compliant shell (installed by default on all linux and unix+ systems, including Mac OS X, and in [Cygwin] for Windows),+ - `HTML Tidy`+ - `iconv` (for character encoding conversion). (If `iconv` is absent,+ `html2markdown` will still work, but it will treat everything as UTF-8.)++The wrapper script `markdown2pdf` requires++ - `pandoc` (which must be in the PATH)+ - a POSIX-compliant shell+ - `pdflatex`, which should be part of any [LaTeX] distribution+ - the following LaTeX packages (available from [CTAN], if they+ are not already included in your LaTeX distribution):+ + `unicode`+ + `fancyhdr` (if you have verbatim text in footnotes)+ + `graphicx` (if you use images)+ + `array` (if you use tables)+ + `ulem` (if you use strikeout text)++The wrapper script `hsmarkdown` requires only a POSIX-compliant shell.++[Cygwin]: http://www.cygwin.com/ +[HTML Tidy]: http://tidy.sourceforge.net/+[`iconv`]: http://www.gnu.org/software/libiconv/+[CTAN]: http://www.ctan.org "Comprehensive TeX Archive Network"++Using Pandoc+============++If you run `pandoc` without arguments, it will accept input from+STDIN. If you run it with file names as arguments, it will take input+from those files. By default, `pandoc` writes its output to STDOUT.+If you want to write to a file, use the `-o` option:++ pandoc -o hello.html hello.txt++Note that you can specify multiple input files on the command line.+`pandoc` will concatenate them all (with blank lines between them)+before parsing:++ pandoc -s ch1.txt ch2.txt refs.txt > book.html++(The `-s` option here tells `pandoc` to produce a standalone HTML file,+with a proper header, rather than a fragment. For more details on this+and many other command-line options, see below.)++The format of the input and output can be specified explicitly using+command-line options. The input format can be specified using the+`-r/--read` or `-f/--from` options, the output format using the+`-w/--write` or `-t/--to` options. Thus, to convert `hello.txt` from+markdown to LaTeX, you could type:++ pandoc -f markdown -t latex hello.txt++To convert `hello.html` from html to markdown:++ pandoc -f html -t markdown hello.html++Supported output formats include `markdown`, `latex`, `context`+(ConTeXt), `html`, `rtf` (rich text format), `rst` (reStructuredText),+`docbook` (DocBook XML), `man` (groff man), and `s5` (which produces an+HTML file that acts like powerpoint). Supported input formats include+`markdown`, `html`, `latex`, and `rst`. Note that the `rst` reader only+parses a subset of reStructuredText syntax. For example, it doesn't+handle tables, option lists, or footnotes. But for simple documents it+should be adequate. The `latex` and `html` readers are also limited in+what they can do. Because the `html` reader is picky about the HTML it+parses, it is recommended that you pipe HTML through [HTML Tidy] before+sending it to `pandoc`, or use the `html2markdown` script described+below.++If you don't specify a reader or writer explicitly, `pandoc` will+try to determine the input and output format from the extensions of+the input and output filenames. Thus, for example, ++ pandoc -o hello.tex hello.txt++will convert `hello.txt` from markdown to LaTeX. If no output file+is specified (so that output goes to STDOUT), or if the output file's+extension is unknown, the output format will default to HTML.+If no input file is specified (so that input comes from STDIN), or+if the input files' extensions are unknown, the input format will+be assumed to be markdown unless explicitly specified.++Character encodings+-------------------++All input is assumed to be in the UTF-8 encoding, and all output+is in UTF-8. If your local character encoding is not UTF-8 and you use+accented or foreign characters, you should pipe the input and output+through [`iconv`]. For example,++ iconv -t utf-8 source.txt | pandoc | iconv -f utf-8 > output.html++will convert `source.txt` from the local encoding to UTF-8, then+convert it to HTML, then convert back to the local encoding,+putting the output in `output.html`.++The shell scripts (described below) automatically convert the input +from the local encoding to UTF-8 before running them through `pandoc`,+then convert the output back to the local encoding.++Shell scripts+=============++Three shell scripts, `markdown2pdf`, `html2markdown`, and `hsmarkdown`,+are included in the standard Pandoc installation. (They are not included+in the Windows binary package, as they require a POSIX shell, but they+may be used in Windows under Cygwin.)++1. `markdown2pdf` produces a PDF file from markdown-formatted+ text, using `pandoc` and `pdflatex`. The default+ behavior of `markdown2pdf` is to create a file with the same+ base name as the first argument and the extension `pdf`; thus,+ for example,++ markdown2pdf sample.txt endnotes.txt++ will produce `sample.pdf`. (If `sample.pdf` exists already,+ it will be backed up before being overwritten.) An output file+ name can be specified explicitly using the `-o` option:++ markdown2pdf -o book.pdf chap1 chap2++ If no input file is specified, input will be taken from STDIN.+ All of `pandoc`'s options will work with `markdown2pdf` as well.++2. `html2markdown` grabs a web page from a file or URL and converts+ it to markdown-formatted text, using `tidy` and `pandoc`.++ All of `pandoc`'s options will work with `html2markdown` as well.+ In addition, the following special options may be used.+ The special options must be separated from the `html2markdown`+ command and any regular Pandoc options by the delimiter `--`:++ html2markdown -o out.txt -- -e latin1 -g curl google.com ++ The `-e` or `--encoding` option specifies the character encoding+ of the HTML input. If this option is not specified, and input+ is not from STDIN, `html2markdown` will attempt to determine the+ page's character encoding from the "Content-type" meta tag.+ If this is not present, UTF-8 is assumed.++ The `-g` or `--grabber` option specifies the command to be used to+ fetch the contents of a URL:++ html2markdown -g 'curl --user foo:bar' www.mysite.com++ If this option is not specified, `html2markdown` searches for an+ available program (`wget`, `curl`, or a text-mode browser) to fetch+ the contents of a URL.++3. `hsmarkdown` is designed to be used as a drop-in replacement for+ `Markdown.pl`. It forces `pandoc` to convert from markdown to+ HTML, and to use the `--strict` flag for maximal compliance with+ official markdown syntax. (All of Pandoc's syntax extensions and+ variants, described below, are disabled.) No other command-line+ options are allowed. (In fact, options will be interpreted as+ filenames.)++ As an alternative to using the `hsmarkdown` shell script, the+ user may create a symbolic link to `pandoc` called `hsmarkdown`.+ When invoked under the name `hsmarkdown`, `pandoc` will behave+ as if the `--strict` flag had been selected, and no command-line+ options will be recognized. However, this approach does not work+ under Cygwin, due to problems with its simulation of symbolic+ links.++Command-line options+====================++Various command-line options can be used to customize the output.+For further documentation, see the `pandoc(1)` man page.++`-f`, `--from`, `-r`, or `--read` *format*+: specifies the input format (the format Pandoc will be converting+ *from*). *format* can be `native`, `markdown`, `rst`, `html`, or+ `latex`.++`-t`, `--to`, `-w`, or `--write` *format*+: specifies the output format -- the format Pandoc will+ be converting *to*. *format* can be `native`, `html`, `s5`,+ `docbook`, `latex`, `context`, `markdown`, `man`, `rst`, and `rtf`.++`-s` or `--standalone`+: indicates that a standalone document is to be produced (with+ appropriate headers and footers), rather than a fragment.++`-o` or `--output` *filename*+: sends output to *filename*. If this option is not specified,+ or if its argument is `-`, output will be sent to STDOUT.++`-p` or `--preserve-tabs`+: causes tabs in the source text to be preserved, rather than converted+ to spaces (the default).++`--tabstop` *tabstop*+: sets the number of spaces per tab to *tabstop* (defaults to 4).++`--strict`+: specifies that strict markdown syntax is to be used, without+ pandoc's usual extensions and variants (described below). When the+ input format is HTML, this means that constructs that have no+ equivalents in standard markdown (e.g. definition lists or strikeout+ text) will be parsed as raw HTML.++`--reference-links`+: causes reference-style links to be used in markdown + and reStructuredText output. By default inline links are used.++`-R` or `--parse-raw`+: causes the HTML and LaTeX readers to parse HTML codes and LaTeX+ environments that it can't translate as raw HTML or LaTeX. Raw HTML can+ be printed in markdown, reStructuredText, HTML, and S5 output; raw LaTeX+ can be printed in markdown, reStructuredText, LaTeX, and ConTeXt output.+ The default is for the readers to omit untranslatable HTML codes and+ LaTeX environments. (The LaTeX reader does pass through untranslatable+ LaTeX *commands*, even if `-R` is not specified.)++`-C` or `--custom-header` *filename*+: can be used to specify a custom document header. To see the headers+ used by default, use the `-D` option: for example, `pandoc -D html`+ prints the default HTML header.++`--toc` or `--table-of-contents`+: includes an automatically generated table of contents (or, in the+ case of `latex`, `context`, and `rst`, an instruction to create+ one) in the output document. This option has no effect with `man`,+ `docbook`, or `s5` output formats.++`-c` or `--css` *filename*+: allows the user to specify a custom stylesheet that will be linked to+ in HTML and S5 output.++`-H` or `--include-in-header` *filename*+: includes the contents of *filename* (verbatim) at the end of the+ document header. This can be used, for example, to include special+ CSS or javascript in HTML documents.++`-B` or `--include-before-body` *filename*+: includes the contents of *filename* (verbatim) at the beginning of+ the document body (e.g. after the `<body>` tag in HTML, or the+ `\begin{document}` command in LaTeX). This can be used to include+ navigation bars or banners in HTML documents.++`-A` or `--include-after-body` *filename*+: includes the contents of *filename* (verbatim) at the end of+ the document body (before the `</body>` tag in HTML, or the+ `\end{document}` command in LaTeX).++`-T` or `--title-prefix` *string*+: includes *string* as a prefix at the beginning of the title that+ appears in the HTML header (but not in the title as it appears at+ the beginning of the HTML body). (See below on+ [Title Blocks](#title-blocks).)++`-S` or `--smart`+: causes `pandoc` to produce typographically correct output, along the+ lines of John Gruber's [Smartypants]. Straight quotes are converted+ to curly quotes, `---` to dashes, and `...` to ellipses. (Note: This+ option is only significant when the input format is `markdown`.+ It is selected automatically when the output format is `latex` or+ `context`.)++`-m`*[url]* or `--asciimathml`*[=url]*+: will cause LaTeX formulas (between $ signs) in HTML or S5 to display+ as formulas rather than as code. The trick will not work in all+ browsers, but it works in Firefox. Peter Jipsen's [ASCIIMathML]+ script is used to do the magic. If a local copy of `ASCIIMathML.js`+ is available on the webserver where the page will be viewed,+ provide a *url* and a link will be inserted in the generated+ HTML or S5. If no *url* is provided, the contents of the script+ will be inserted directly; this provides portability at the price of+ efficiency. If you plan to use math on several pages, it is much+ better to link to a copy of `ASCIIMathML.js`, which can be cached.++`-i` or `--incremental`+: causes all lists in S5 output to be displayed incrementally by+ default (one item at a time). The normal default is for lists to be+ displayed all at once.++`-N` or `--number-sections`+: causes sections to be numbered in LaTeX or ConTeXt output. By default,+ sections are not numbered.++`--dump-args`+: is intended to make it easier to create wrapper scripts that use+ Pandoc. It causes Pandoc to dump information about the arguments+ with which it was called to STDOUT, then exit. The first line+ printed is the name of the output file specified using the `-o`+ or `--output` option, or `-` if output would go to STDOUT. The+ remaining lines, if any, list command-line arguments. These will+ include the names of input files and any special options passed+ after ` -- ` on the command line. So, for example,++: pandoc --dump-args -o foo.html -s foo.txt \+ appendix.txt -- -e latin1++: will cause the following to be printed to STDOUT:++: foo.html foo.txt appendix.txt -e latin1++`--ignore-args`+: causes Pandoc to ignore all command-line arguments.+ Regular Pandoc options are not ignored. Thus, for example,++: pandoc --ignore-args -o foo.html -s foo.txt -- -e latin1++: is equivalent to++: pandoc -o foo.html -s ++`-v` or `--version`+: prints the version number to STDERR.++`-h` or `--help`+: prints a usage message to STDERR.++[Smartypants]: http://daringfireball.net/projects/smartypants/+[ASCIIMathML]: http://www1.chapman.edu/~jipsen/mathml/asciimath.html++Pandoc's markdown vs. standard markdown+=======================================++In parsing markdown, Pandoc departs from and extends [standard markdown]+in a few respects. (To run Pandoc on the official markdown test suite,+type `make test-markdown`.) Except where noted, these differences can+be suppressed by specifying the `--strict` command-line option or by+using the `hsmarkdown` wrapper.++[standard markdown]: http://daringfireball.net/projects/markdown/syntax+ "Markdown syntax description"++Backslash escapes+-----------------++Except inside a code block or inline code, any punctuation or space+character preceded by a backslash will be treated literally, even if it+would normally indicate formatting. Thus, for example, if one writes++ *\*hello\**++one will get++ <em>*hello*</em>++instead of++ <strong>hello</strong>++This rule is easier to remember than standard markdown's rule,+which allows only the following characters to be backslash-escaped:++ \`*_{}[]()>#+-.!++Subscripts and superscripts+---------------------------++Superscripts may be written by surrounding the superscripted text by `^`+characters; subscripts may be written by surrounding the subscripted+text by `~` characters. Thus, for example,++ H~2~O is a liquid. 2^10^ is 1024.++If the superscripted or subscripted text contains spaces, these spaces+must be escaped with backslashes. (This is to prevent accidental+superscripting and subscripting through the ordinary use of `~` and `^`.)+Thus, if you want the letter P with 'a cat' in subscripts, use+`P~a\ cat~`, not `P~a cat~`.++Strikeout+---------++To strikeout a section of text with a horizontal line, begin and end it+with `~~`. Thus, for example,++ This ~~is deleted text.~~++Lists+-----++Pandoc behaves differently from standard markdown on some "edge+cases" involving lists. Consider this source: ++ 1. First+ 2. Second:+ - Fee+ - Fie+ - Foe++ 3. Third++Pandoc transforms this into a "compact list" (with no `<p>` tags around+"First", "Second", or "Third"), while markdown puts `<p>` tags around+"Second" and "Third" (but not "First"), because of the blank space+around "Third". Pandoc follows a simple rule: if the text is followed by+a blank line, it is treated as a paragraph. Since "Second" is followed+by a list, and not a blank line, it isn't treated as a paragraph. The+fact that the list is followed by a blank line is irrelevant. (Note:+Pandoc works this way even when the `--strict` option is specified. This+behavior is consistent with the official markdown syntax description,+even though it is different from that of `Markdown.pl`.)++Unlike standard markdown, Pandoc allows ordered list items to be marked+with uppercase and lowercase letters and roman numerals, in addition to+arabic numerals. (This behavior can be turned off using the `--strict`+option.) List markers may be enclosed in parentheses or followed by a+single right-parentheses or period. Pandoc also pays attention to the+type of list marker used, and to the starting number, and both of these+are preserved where possible in the output format. Thus, the following+yields a list with numbers followed by a single parenthesis, starting+with 9, and a sublist with lowercase roman numerals:++ 9) Ninth+ 10) Tenth+ 11) Eleventh+ i. subone+ ii. subtwo+ iii. subthree++Note that Pandoc pays attention only to the *starting* number in a list.+So, the following yields a list numbered sequentially starting from 2:++ (2) Two+ (5) Three+ (2) Four++If default list markers are desired, use '`#.`':++ #. one+ #. two+ #. three++If you change list style in mid-list, Pandoc will notice and assume you+are starting a sublist. So,++ 1. One+ 2. Two+ A. Sub+ B. Sub+ 3. Three++gets treated as if it were++ 1. One+ 2. Two+ A. Sub+ B. Sub+ 3. Three++Note that a list beginning with a single letter will be interpreted as+an alphabetic list. So you are out of luck if you want a roman-numbered+list starting with 100 (C).++Note also that a paragraph starting with a capital letter and a period+(for example, an initial) or a capital letter in parentheses+(for example, `(C)`) will be interpreted as a list:++ B. Russell was an English philosopher.++ (C) 2007 Joe Smith++To avoid this, use backslash escapes:++ B\. Russell was an English philosopher.++ \(C) 2007 Joe Smith++Definition lists+----------------++Pandoc supports definition lists, using a syntax inspired by+[PHP Markdown Extra] and [reStructuredText]:++ [PHP Markdown Extra]: http://www.michelf.com/projects/php-markdown/extra/++ Term 1+ : Definition 1++ Term 2+ : Definition 2++ : Second paragraph of definition 2.++Each term must fit on one line. The definition must begin on the line+after the term. The definition consists of one or more block elements+(paragraph, code block, list, etc.), each beginning with a colon and+(aside from the colon) indented one tab stop.++ Term *with inline markup*+ : Here is the definition. It may contain multiple blocks.+ Here is some code:++ : {* my code *} ++ : Here is the third paragraph of this definition.++If you leave space after the definition (as in the first example above),+the definitions will be considered paragraphs. In some output formats,+this will mean greater spacing between term/definition pairs. For a+compact definition list, do not leave space between the definition and+the next term:++ Term 1+ : Definition 1+ Term 2+ : Definition 2++Reference links+---------------++Pandoc allows implicit reference links with just a single set of+brackets. So, the following links are equivalent:++ 1. Here's my [link]+ 2. Here's my [link][]++ [link]: linky.com++(Note: Pandoc works this way even if `--strict` is specified, because+`Markdown.pl` 1.0.2b7 allows single-bracket links.)++Footnotes+---------++Pandoc's markdown allows footnotes, using the following syntax:++ Here is a footnote reference,[^1] and another.[^longnote]++ [^1]: Here is the footnote.++ [^longnote]: Here's one with multiple blocks.++ Subsequent paragraphs are indented to show that they + belong to the previous footnote.++ { some.code }++ The whole paragraph can be indented, or just the first+ line. In this way, multi-paragraph footnotes work like+ multi-paragraph list items.++ This paragraph won't be part of the note, because it isn't indented.++The identifiers in footnote references may not contain spaces, tabs,+or newlines. These identifiers are used only to correlate the+footnote reference with the note itself; in the output, footnotes+will be numbered sequentially.++The footnotes themselves need not be placed at the end of the+document. They may appear anywhere except inside other block elements+(lists, block quotes, tables, etc.).++Inline footnotes are also allowed (though, unlike regular notes,+they cannot contain multiple paragraphs). The syntax is as follows:++ Here is an inline note.^[Inlines notes are easier to write, since+ you don't have to pick an identifier and move down to type the+ note.]++Inline and regular footnotes may be mixed freely.++Tables+------++Two kinds of tables may be used. Both kinds presuppose the use of+a fixed-width font, such as Courier.++Simple tables look like this:++ Right Left Center Default + ------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 ++ Table: Demonstration of simple table syntax.++The headers and table rows must each fit on one line. Column+alignments are determined by the position of the header text relative+to the dashed line below it:[^1]++ - If the dashed line is flush with the header text on the right side+ but extends beyond it on the left, the column is right-aligned.+ - If the dashed line is flush with the header text on the left side + but extends beyond it on the right, the column is left-aligned.+ - If the dashed line extends beyond the header text on both sides,+ the column is centered.+ - If the dashed line is flush with the header text on both sides,+ the default alignment is used (in most cases, this will be left).++[^1]: This scheme is due to Michel Fortin, who proposed it on the+ Markdown discussion list: <http://six.pairlist.net/pipermail/markdown-discuss/2005-March/001097.html>++The table must end with a blank line. Optionally, a caption may be+provided (as illustrated in the example above). A caption is a paragraph+beginning with the string `Table:`, which will be stripped off.++The table parser pays attention to the widths of the columns, and+the writers try to reproduce these relative widths in the output.+So, if you find that one of the columns is too narrow in the output,+try widening it in the markdown source.++Multiline tables allow headers and table rows to span multiple lines+of text. Here is an example:++ -------------------------------------------------------------+ Centered Default Right Left+ Header Aligned Aligned Aligned+ ----------- ------- --------------- -------------------------+ First row 12.0 Example of a row that+ spans multiple lines.+ + Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ -------------------------------------------------------------+ + Table: Here's the caption. It, too, may span+ multiple lines.++These work like simple tables, but with the following differences:++ - They must begin with a row of dashes, before the header text.+ - They must end with a row of dashes, then a blank line.+ - The rows must be separated by blank lines. ++Title blocks+------------++If the file begins with a title block++ % title+ % author(s) (separated by commas)+ % date++it will be parsed as bibliographic information, not regular text. (It+will be used, for example, in the title of standalone LaTeX or HTML+output.) The block may contain just a title, a title and an author,+or all three lines. Each must begin with a % and fit on one line.+The title may contain standard inline formatting. If you want to+include an author but no title, or a title and a date but no author,+you need a blank line:++ % My title+ % + % June 15, 2006++Titles will be written only when the `--standalone` (`-s`) option is+chosen. In HTML output, titles will appear twice: once in the+document head -- this is the title that will appear at the top of the+window in a browser -- and once at the beginning of the document body.+The title in the document head can have an optional prefix attached+(`--title-prefix` or `-T` option). The title in the body appears as+an H1 element with class "title", so it can be suppressed or+reformatted with CSS. If a title prefix is specified with `-T` and no+title block appears in the document, the title prefix will be used by+itself as the HTML title.++The man page writer extracts a title, man page section number, and+other header and footer information from the title line. The title+is assumed to be the first word on the title line, which may optionally+end with a (single-digit) section number in parentheses. (There should+be no space between the title and the parentheses.) Anything after+this is assumed to be additional footer and header text. A single pipe+character (`|`) should be used to separate the footer text from the header+text. Thus,++ % PANDOC(1)++will yield a man page with the title `PANDOC` and section 1.++ % PANDOC(1) Pandoc User Manuals++will also have "Pandoc User Manuals" in the footer.++ % PANDOC(1) Pandoc User Manuals | Version 4.0++will also have "Version 4.0" in the header.++Markdown in HTML blocks+-----------------------++While standard markdown leaves HTML blocks exactly as they are, Pandoc+treats text between HTML tags as markdown. Thus, for example, Pandoc+will turn++ <table>+ <tr>+ <td>*one*</td>+ <td>[a link](http://google.com)</td>+ </tr>+ </table>++into++ <table>+ <tr>+ <td><em>one</em></td>+ <td><a href="http://google.com">a link</a></td>+ </tr>+ </table>++whereas `Markdown.pl` will preserve it as is.++There is one exception to this rule: text between `<script>` and+`</script>` tags is not interpreted as markdown.++This departure from standard markdown should make it easier to mix+markdown with HTML block elements. For example, one can surround+a block of markdown text with `<div>` tags without preventing it+from being interpreted as markdown.++Header identifiers in HTML+--------------------------++Each header element in pandoc's HTML output is given a unique+identifier. This identifier is based on the text of the header. To+derive the identifier from the header text,++ - Remove all formatting, links, etc.+ - Remove all punctuation, except dashes and hyphens.+ - Replace all spaces, dashes, newlines, and hyphens with hyphens.+ - Convert all alphabetic characters to lowercase.++Thus, for example, a heading 'Header identifiers in HTML' will get+the identifier `header-identifiers-in-html`, a heading+'*Dogs*?--in *my* house?' will get the identifier `dogs--in-my-house`,+and a heading '[HTML], [S5], or [RTF]?' will get the identifier+`html-s5-or-rtf`.++These rules should, in most cases, allow one to determine the identifier+from the header text. The exception is when several headers have the+same text; in this case, the first will get an identifier as described+above; the second will get the same identifier with `-1` appended; the+third with `-2`; and so on.++These identifiers are used to provide link targets in the table of+contents generated by the `--toc|--table-of-contents` option. They+also make it easy to provide links from one section of a document to+another. A link to this section, for example, might look like this:++ See the section on [header identifiers](#header-identifiers-in-html). ++Note, however, that this method of providing links to sections works+only in HTML.++Box-style blockquotes+---------------------++Pandoc supports emacs-style boxquote block quotes, in addition to+standard markdown (email-style) block quotes:++ ,----+ | They look like this.+ `----++Blank lines before headers and blockquotes+------------------------------------------++Standard markdown syntax does not require a blank line before a header+or blockquote. Pandoc does require this (except, of course, at the+beginning of the document). The reason for the requirement is that+it is all too easy for a `>` or `#` to end up at the beginning of a+line by accident (perhaps through line wrapping). Consider, for+example:++ I like several of their flavors of ice cream: #22, for example, and+ #5.++Inline LaTeX+------------++Anything between two $ characters will be parsed as LaTeX math. The+opening $ must have a character immediately to its right, while the+closing $ must have a character immediately to its left. Thus,+`$20,000 and $30,000` won't parse as math. The $ character can be+escaped with a backslash if needed.++Pandoc can use the [ASCIIMathML] script to display LaTeX formulas+in HTML (at least on better browsers). See above on the+`-m|--asciimathml` command-line option.++[ASCIIMathML]: http://www1.chapman.edu/~jipsen/asciimath.html ++Inline LaTeX commands will also be preserved and passed unchanged+to the LaTeX writer. Thus, for example, you can use LaTeX to+include BibTeX citations:++ This result was proved in \cite{jones.1967}.++Note that in LaTeX environments, like++ \begin{tabular}{|l|l|}\hline+ Age & Frequency \\ \hline+ 18--25 & 15 \\+ 26--35 & 33 \\ + 36--45 & 22 \\ \hline+ \end{tabular}++the material between the begin and end tags will be interpreted as raw+LaTeX, not as markdown.++Custom headers+==============++When run with the "standalone" option (`-s`), `pandoc` creates a+standalone file, complete with an appropriate header. To see the+default headers used for html and latex, use the following commands:++ pandoc -D html++ pandoc -D latex ++If you want to use a different header, just create a file containing+it and specify it on the command line as follows:++ pandoc --header=MyHeaderFile++Producing S5 with Pandoc+========================++Producing an [S5] web-based slide show with Pandoc is easy. A title+page is constructed automatically from the document's title block (see+above). Each section (with a level-one header) produces a single slide.+(Note that if the section is too big, the slide will not fit on the page;+S5 is not smart enough to produce multiple pages.)++Here's the markdown source for a simple slide show, `eating.txt`:++ % Eating Habits+ % John Doe+ % March 22, 2005++ # In the morning++ - Eat eggs+ - Drink coffee++ # In the evening++ - Eat spaghetti+ - Drink wine++To produce the slide show, simply type++ pandoc -w s5 -s eating.txt > eating.html++and open up `eating.html` in a browser. The HTML file embeds+all the required javascript and CSS, so no other files are necessary.++Note that by default, the S5 writer produces lists that display+"all at once." If you want your lists to display incrementally+(one item at a time), use the `-i` option. If you want a+particular list to depart from the default (that is, to display+incrementally without the `-i` option and all at once with the+`-i` option), put it in a block quote:++ > - Eat spaghetti+ > - Drink wine++In this way incremental and nonincremental lists can be mixed in+a single document.+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ debian/changelog view
@@ -0,0 +1,644 @@+pandoc (0.4) unstable; urgency=low++ [ John MacFarlane ]++ * Added two new output formats: groff man pages and ConTeXt. By+ default, output files with extensions ".ctx" and ".context" are+ assumed to be ConTeXt, and output files with single-digit extensions+ are assumed to be man pages.++ * Enhanced ordered lists (documented in README, under Lists):+ + The OrderedList block element now stores information about+ list number style, list number delimiter, and starting number.+ + The readers parse this information when possible.+ + The writers use this information to style ordered lists.+ + The enhancement can be disabled using the --strict option. ++ * Added support for tables (with a new Table block element). Two kinds+ of tables are supported: a simple table with one-line rows, and a+ more complex variety with multiline rows. All output formats are+ supported, but only markdown tables are parsed at the moment. The+ syntax is documented in README.++ * Added support for definition lists (with a new DefinitionList block+ element). All output and input formats are supported. The syntax is+ documented in README.++ * Added support for superscripts and subscripts (with new Superscript+ and Subscript inline elements). All input and output+ formats. The syntax is documented in README.++ * Added support for strikeout (with a new Strikeout inline element).+ All input and output formats are supported. Thanks to Bradley Kuhn,+ who contributed a patch. The syntax is documented in README. Resolves+ Issue #18.++ * Added a --toc|--table-of-contents option. This causes an automatically+ generated table of contents (or an instruction that creates one) to+ be inserted at the beginning of the document. Not supported in S5,+ DocBook, or man page writers.++ * Modified the -m|--asciimathml option:++ + If an optional URL argument is provided, a link is inserted+ instead of the contents of the ASCIIMathML.js script.+ + Nothing is inserted unless the document actually contains+ LaTeX math.++ * Removed Blank block element as unnecessary.++ * Removed Key and Note blocks from the Pandoc data structure. All+ links are now stored as explicit links, and note contents are+ stored with the (inline) notes.++ + All link Targets are now explicit (URL, title) pairs; there+ is no longer a 'Ref' target.+ + Markdown and RST parsers now need to extract data from key and+ note blocks and insert them into the relevant inline elements.+ Other parsers have been simplified, since there is no longer any need+ to construct separate key and note blocks.+ + Markdown, RST, and HTML writers need to construct lists of+ notes; Markdown and RST writers need to construct lists of link+ references (when the --reference-links option is specified); and+ the RST writer needs to construct a list of image substitution+ references. All writers have been rewritten to use the State monad+ when state is required.+ + Several functions (generateReference, keyTable,+ replaceReferenceLinks, replaceRefLinksBlockList, and some auxiliaries+ used by them) have been removed from Text.Pandoc.Shared, since+ they are no longer needed. New functions and data structures+ (Reference, isNoteBlock, isKeyBlock, isLineClump) have been+ added. The functions inTags, selfClosingTag, inTagsSimple, and+ inTagsIndented have been moved to the DocBook writer, since that+ is now the only module that uses them. NoteTable is now exported+ in Text.Pandoc.Shared.+ + Added stateKeys and stateNotes to ParserState; removed stateKeyBlocks,+ stateKeysUsed, stateNoteBlocks, stateNoteIdentifiers, stateInlineLinks. + + Added writerNotes and writerReferenceLinks to WriterOptions.++ * Added Text.Pandoc module that exports basic readers, writers,+ definitions, and utility functions. This should export everything+ needed for most uses of Pandoc libraries. The haddock documentation+ includes a short example program.++ * Text.Pandoc.ASCIIMathML is no longer an exported module.++ * Added Text.Pandoc.Blocks module to help in printing markdown+ and RST tables. This module provides functions for working with+ fixed-width blocks of text--e.g., placing them side by side, as+ in a table row.++ * Refactored to avoid reliance on Haskell's Text.Regex library, which+ (a) is slow, and (b) does not properly handle unicode. This fixed+ some strange bugs, e.g. in parsing S-cedilla, and improved performance.++ + Replaced 'gsub' with a general list function 'substitute'+ that does not rely on Text.Regex.+ + Rewrote extractTagType in HTML reader so that it doesn't use+ regexs.+ + In Markdown reader, replaced email regex test with a custom email+ autolink parser (autoLinkEmail). Also replaced selfClosingTag regex+ with a custom function isSelfClosingTag.+ + Modified Docbook writer so that it doesn't rely on Text.Regex for+ detecting 'mailto' links.+ + Removed escapePreservingRegex and reamped entity-handling+ functions in Text.Pandoc.Shared and Text.Pandoc.CharacterReferences to+ avoid reliance on Text.Regex (see below on character reference+ handling changes).++ * Renamed Text.Pandoc.Entities as Text.Pandoc.CharacterReferences.++ * Changed handling of XML entities. Entities are now parsed (and unicode+ characters returned) in the Markdown and HTML readers, rather than being+ handled in the writers. In HTML and Docbook writers, UTF-8 is now used+ instead of entities for characters above 128. This makes the HTML and + DocBook output much more readable and more easily editable.++ + Removed sgmlHexEntity, sgmlDecimalEntity, sgmlNamedEntity, and+ sgmlCharacterEntity regexes from Text.Pandoc.Shared.+ + Renamed escapeSGMLChar to escapeCharForXML. Added escapeStringForXML.+ Moved both functions to Text.Pandoc.Writers.Docbook.+ + Added characterReference parser to Text.Pandoc.CharacterReferences.+ This parses a string and return a unicode character.+ + Rewrote decodeCharacterReferences to use the new parser instead of + Text.Regex.+ + Added new charRef parser for Markdown and HTML, which replaces the+ old 'entity' parser. Added '&' as a special character in Markdown reader.+ + Modified HTML and Markdown readers to call decodeEntities on all raw+ strings (e.g. authors, dates, link titles), to ensure that no + unprocessed entities are included in the native representation of+ the document. (In the HTML reader, most of this work is done by a + change in extractAttributeName.)+ + In XML and Markdown output, escape unicode nonbreaking space as ' ', + since a unicode non-breaking space is impossible to distinguish visually+ from a regular space. (Resolves Issue #3.)+ + Removed encodeEntitiesNumerical.+ + Use Data.Map for entityTable and (new) reverseEntityTable, for a+ slight performance boost over the old association list.+ + Removed unneeded decodeEntities from 'str' parser in HTML and+ Markdown readers.++ * Text.Pandoc.UTF8: Renamed encodeUTF8 to toUTF8, decodeUTF8 to+ fromUTF8, for clarity.++ * Replaced old haskell98 module names replaced by hierarchical module+ names, e.g. List by Data.List. Removed haskell98 from dependencies+ in pandoc.cabal, and added mtl (needed for state monad). Substituted+ xhtml for html.++ * Refactored and cleaned up character escaping in writers, using+ backslashEscapes and escapeStringUsing functions.++ * Instead of adding "\n\n" to the end of an input string in Main.hs,+ this is now done in the readers. This makes the libraries behave+ the way you'd expect from the pandoc program. Resolves Issue #10.++ * URLs and email addresses in autolinks are now typeset as Code.++ * In Main.hs, changed putStr to putStrLn -- mainly because MacOS X+ doesn't display the whole output unless there's a line ending.++ * Major code cleanup in all modules, for greater consistency, concision,+ and readability.++ * HTML reader:++ + Fixed several bugs (extractTagType, attribute parsing).+ + Remove Null blocks in lists of blocks when possible.+ + Allow HTML comments as raw HTML inline.++ * Markdown reader:++ + Ordered list items may no longer begin with uppercase letters, or+ letters greater than 'n'. (This prevents first initials and page+ reference, e.g. 'p. 400', from being parsed as beginning lists.)+ Also, numbers beginning list items may no longer end with ')',+ which is now allowed only after letters. Note: These changes+ may cause documents to be parsed differently. Users should take+ care in upgrading.+ + Changed autoLink parsing to conform better to Markdown.pl's+ behavior. <google.com> is not treated as a link, but + <http://google.com>, <ftp://google.com>, and <mailto:google@google.com>+ are.+ + Cleaned up handling of embedded quotes in link titles. Now these are + stored as a '"' character, not as '"'.+ + Use lookAhead parser for the 'first pass' (looking for reference keys),+ instead of parsing normally, then using setInput to reset input. This+ yields a slight performance boost.+ + Fixed several bugs in smart quote recognition.+ + Fixed bug in indentSpaces (which didn't properly handle+ cases with mixed spaces and tabs).+ + Consolidated 'text', 'special', and 'inline' into 'inline'.+ + Fixed bug which allowed URL and title to be separated by multiple blank+ lines in links and reference keys. They can be on separate lines but+ can't have blank lines between them.+ + Correctly handle bracketed text inside inline footnotes and links,using+ new function inlinesInBalanced. Resolves Issue #14. + + Fixed bug in footnotes: links in footnotes were not being+ processed. Solution: three-stage parse. First, get all the+ reference keys and add information to state. Next, get all the+ notes and add information to state. (Reference keys may be needed+ at this stage.) Finally, parse everything else.+ + Replaced named constants like 'emphStart' with literals.+ + Removed an extra occurance of escapedChar in definition of inline.++ * RST reader:++ + Allow the URI in a RST hyperlink target to start on the line+ after the reference key.+ + Added 'try' in front of 'string', where needed, or used a different+ parser. This fixes a bug where ````` would not be correctly parsed as+ a verbatim `.+ + Fixed slow performance in parsing inline literals in RST reader. The + problem was that ``#`` was seen by 'inline' as a potential link or image.+ Fix: inserted 'notFollowedBy (char '`')' in link parsers.+ Resolves Issue #8.+ + Use lookAhead instead of getInput/setInput in RST reader. Removed+ unneeded getState call, since lookAhead automatically saves and+ restores the parser state.+ + Allow hyperlink target URIs to be split over multiple lines, and+ to start on the line after the reference. Resolves Issue #7.+ + Fixed handling of autolinks.++ * LaTeX reader:++ + Replaced 'choice [(try (string ...), ...]' idiom with 'oneOfStrings',+ for clarity.+ + Added clauses for tilde and caret. Tilde is \ensuremath{\sim}, and+ caret is \^{}, not \^ as before.+ + Added parsing for \url.+ + Parse \texttt{} as code, provided there's nothing fancy inside.++ * HTML writer:++ + Modified HTML writer to use the Text.XHtml library. This results+ in cleaner, faster code, and it makes it easier to use Pandoc in+ other projects, like wikis, which use Text.XHtml. Two functions are+ now provided, writeHtml and writeHtmlString: the former outputs an+ Html structure, the latter a rendered string. The S5 writer is also+ changed, in parallel ways (writeS5, writeS5String). + + The Html header is now written programmatically, so it has been+ removed from the 'headers' directory. The S5 header is still+ needed, but the doctype and some of the meta declarations have+ been removed, since they are written programatically. This change+ introduces a new dependency on the xhtml package.+ + Fixed two bugs in email obfuscation involving improper escaping+ of '&' in the <noscript> section and in --strict mode. Resolves+ Issue #9.+ + Fixed another bug in email obfuscation: If the text to be obfuscated+ contains an entity, this needs to be decoded before obfuscation.+ Thanks to thsutton for the patch. Resolves Issue #15.+ + Changed the way the backlink is displayed in HTML footnotes.+ Instead of appearing on a line by itself, it now generally+ appears on the last line of the note. (Exception: when the+ note does not end with a Plain or Para block.) This saves space+ and looks better.+ + Added automatic unique identifiers to headers:+ - The identifier is derived from the header via a scheme+ documented in README.+ - WriterState now includes a list of header identifiers and a table+ of contents in addition to notes.+ - The function uniqueIdentifiers creates a list of unique identifiers+ from a list of inline lists (e.g. headers).+ - This list is part of WriterState and gets consumed by blockToHtml+ each time a header is encountered.+ + Include CSS for .strikethrough class in header only if strikethrough+ text appears in the document.+ + If the 'strict' option is specified, elements that do not appear in+ standard markdown (like definition lists) are passed through as+ raw HTML.+ + Simplified treatment of autolinks, using pattern matching instead of+ conditionals.++ * Markdown writer:++ + Links in markdown output are now printed as inline links by default,+ rather than reference links. A --reference-links option has been added+ that forces links to be printed as reference links. Resolves Issue #4.+ + Use autolinks when possible. Instead of [site.com](site.com), + use <site.com>.++ * LaTeX writer:++ + Rewrote to use the State monad. The preamble now includes only those+ packages that are actually required, given the document's content.+ Thus, for example, if strikeout is not used, ulem is not required.+ Modified LaTeXHeader accordingly.+ + Modified LaTeX writer to insert '\,' between consecutive quotes.+ + Removed unused function tableRowColumnWidths.+ + Simplified code for escaping special characters.+ + Leave extra blank line after \maketitle.+ + Include empty '\author{}' when no author specified to avoid LaTeX+ errors.+ + Include fancyvrb code in header only if needed -- that is, only+ if there is actually code in a footnote.+ + Use \url{} for autolinks.+ + Include [mathletters] option in ucs package, so that basic unicode+ Greek letters will work correctly.++ * RST writer: Force blank line before lists, so that sublists will+ be handled correctly.++ * Docbook writer: Fixed a bug: email links with text, like+ [foo](me@bar.baz), were being incorrectly treated as autolinks.++ * Removed Text.ParserCombinators.Pandoc and moved all its functions to+ Text.Pandoc.Shared.++ * Text.Pandoc.Shared:++ + Added defaultWriterOptions.+ + Added writerTableOfContents to WriterOptions.+ + Added writerIgnoreNotes option to WriterOptions. This is needed+ for processing header blocks for a table of contents, since notes on+ headers should not appear in the TOC.+ + Added prettyprinting for native Table format.+ + Removed some unneeded imports. + + Moved escape and nullBlock parsers from+ Text.ParserCombinators.Pandoc, since the latter is for+ general-purpose parsers that don't depend on Text.Pandoc.Definition.+ + Moved isHeaderBlock from Text.Pandoc.Writers.HTML.+ + Moved Element, headerAtLeast, and hierarchicalize from Docbook+ writer, because HTML writer now uses these in constructing a table+ of contents.+ + Added clauses for new inline elements (Strikeout, Superscript,+ Subscript) to refsMatch.+ + Removed backslashEscape; added new functions escapeStringUsing and+ backslashEscapes.+ + Moved failIfStrict from markdown reader, since it is now used also+ by the HTML reader.+ + Added a 'try' to the definition of indentSpaces.+ + In definition of 'reference', added check to make sure it's not a note+ reference.+ + Added functions: camelCaseToHyphenated, toRomanNumeral,+ anyOrderedListMarker, orderedListmarker, orderedListMarkers,+ charsInBalanced', withHorizDisplacement, romanNumeral+ + Fixed a bug in the anyLine parser. Previously it would parse an empty+ string "", but it should fail on an empty string, or we get an error+ when it is used inside "many" combinators.+ + Removed followedBy' parser, replacing it with the lookAhead parser from+ Parsec. + + Added some needed 'try's before multicharacter parsers, especially in + 'option' contexts.+ + Removed the 'try' from the 'end' parser in 'enclosed', so that+ 'enclosed' behaves like 'option', 'manyTill', etc.+ + Added lineClump parser, which parses a raw line block up to and+ including any following blank lines.+ + Renamed parseFromStr to parseFromString.+ + Added a 'try' to the 'end' parser in 'enclosed'. This makes errors in+ the use of 'enclosed' less likely. Removed some now-unnecessary 'try's+ in calling code.+ + Removed unneeded 'try' in blanklines.+ + Removed endsWith function and rewrote calling functions to use+ isSuffixOf instead.+ + Added >>~ combinator.+ + Fixed bug in normalizeSpaces: Space:Str "":Space should compress to+ Space.++ * Refactored runtests.pl; added separate tests for tables. ++ * Shell scripts:++ + Added -asxhtml flag to tidy in html2markdown. This will+ perhaps help the parser, which expects closing tags.+ + Modified markdown2pdf to run pdflatex a second time if --toc or+ --table-of-contents was specified; otherwise the table of + contents won't appear.+ + Modified markdown2pdf to print a helpful message if the 'ulem'+ LaTeX package is required and not found.+ + * Changes to build process:++ + Dropped support for compilation with GHC 6.4. GHC 6.6 or higher+ is now required.+ + Removed cabalize and Pandoc.cabal.in. The repository now contains+ pandoc.cabal itself.+ + Pandoc.cabal has been changed to pandoc.cabal, because HackageDB+ likes the cabal file to have the same name as the tarball. + + Expanded and revised the package description in pandoc.cabal.+ Revised the package synopsis.+ + The tarball built by 'make tarball' now contains files built from+ templates (including man pages and shell scripts), so pandoc can+ be built directly using Cabal tools, without preprocessing.+ + Executable binaries are now stripped before installing.+ + Man pages are now generated from markdown sources, using pandoc's+ man page writer.+ + Use HTML version of README (instead of RTF) in Mac OS X installer.+ + Instead of testing for the existence of a pandoc symlink in build-exec,+ use ln -f.++ * Documentation:++ + Updated README and man pages with information on new features.+ + Updated INSTALL instructions with some useful clarifications and+ links. + + Updated web content.++ * Added FreeBSD port.++ [ Recai Oktaş ]++ * debian/control:++ + Changed pandoc's Build-Depends to include libghc6-mtl-dev and+ libghc6-xhtml-dev. Removed libghc6-html-dev.+ + Suggest texlive-latex-recommended | tetex-extra instead of+ tetex-bin. This brings in fancyvrb and unicode support.+++ -- Recai Oktaş <roktas@debian.org> Tue, 16 Jan 2007 00:37:21 +0200++pandoc (0.3) unstable; urgency=low++ [ John MacFarlane ]++ * Changes in pandoc options:++ + Allow options to follow or precede arguments.+ + Changed '--smartypants' to '--smart' and adjusted symbols accordingly.+ + Added '--strict' option.+ + Added '-o/--output' option.+ + Added '--dump-args' and '--ignore-args' options (for use in wrappers).+ + Modified '-v' and '-h' output to go to STDERR, not STDOUT, and return+ error conditions. This is helpful for writing wrappers.+ + Added copyright message to '-v' output, modeled after FSF messages.+ + Reformatted usage message so that it doesn't wrap illegibly.+ + Removed extra blanks after '-h' and '-D' output.++ * Added docbook writer.++ * Added implicit setting of default input and output format based+ on input and output filename extensions. These defaults are+ overridden if explicit input and output formats are specified using+ '-t', '-f', '-r', or '-w' options. Documented in pandoc(1) man page+ and README.++ * Allow ordered list items to begin with (single) letters, as well+ as numbers. The list item marker may now be terminated either by+ '.' or by ')'. This extension to standard markdown is documented+ in README.++ * Revised footnote syntax. (See README for full details.) The+ '[^1]' format now standard in markdown extensions is supported,+ as are inline footnotes with this syntax: '^[My note.]'.+ The earlier footnote syntax '^(1)' is no longer supported.++ * Improved HTML representation of footnotes. All footnotes+ are now auto-numbered and appear in an ordered list at the+ end of the HTML document. Since the default appearance is now+ acceptable, the old footnote styles have been removed from the+ HTML header.++ * Bug fixes:++ + Fixed a serious bug in the markdown, LaTeX, and RST readers.+ These readers ran 'runParser' on processed chunks of text to handle+ embedded block lists in lists and quotation blocks. But then+ any changes made to the parser state in these chunks was lost,+ as the state is local to the parser. So, for example, footnotes+ didn't work in quotes or list items. The fix: instead of calling+ runParser on some raw text, use setInput to make it the input, then+ parse it, then use setInput to restore the input to what it was+ before. This is shorter and more elegant, and it fixes the problem.+ + Fixed bug in notFollowedBy' combinator (adding 'try' before+ 'parser'). Adjusted code that uses this combinator accordingly.+ + Fixed bug in RTF writer that caused improper indentation on+ footnotes occurring in indented blocks like lists.+ + Fixed parsing of metadata in LaTeX reader. Now the title, author,+ and date are parsed correctly. Everything else in the preamble+ is skipped.+ + Modified escapedChar in LaTeX reader to allow a '\' at the end of a+ line to count as escaped whitespace.+ + Modified LaTeX reader to produce inline links rather than reference+ links. Otherwise, links in footnotes aren't handled properly.+ + Fixed handling of titles in links in Markdown reader, so that+ embedded quotation marks are now handled properly.+ + Fixed Markdown reader's handling of embedded brackets in links.+ + Fixed Markdown reader so that it only parses bracketed material+ as a reference link if there is actually a corresponding key.+ + Revised inline code parsing in Markdown reader to conform to+ markdown standard. Now any number of `s can begin inline code,+ which will end with the same number of `s. For example, to+ have two backticks as code, write ``` `` ```. Modified Markdown+ writer accordingly.+ + Fixed bug in text-wrapping routine in Markdown and RST writers.+ Now LineBreaks no longer cause wrapping problems.+ + Supported hexadecimal numerical entity references as well as+ decimal ones.+ + Fixed bug in Markdown reader's handling of underscores and other+ inline formatting markers inside reference labels: for example,+ in '[A_B]: /url/a_b', the material between underscores was being+ parsed as emphasized inlines.+ + Changed Markdown reader's handling of backslash escapes so that+ only non-alphanumeric characters can be escaped. Strict mode+ follows Markdown.pl in only allowing a select group of punctuation+ characters to be escaped.+ + Modified HTML reader to skip a newline following a <br> tag.+ Otherwise the newline will be treated as a space at the beginning+ of the next line.++ * Made handling of code blocks more consistent. Previously, some+ readers allowed trailing newlines, while others stripped them.+ Now, all readers strip trailing newlines in code blocks. Writers+ insert a newline at the end of code blocks as needed.++ * Modified readers to make spacing at the end of output more consistent.++ * Minor improvements to LaTeX reader:++ + '\thanks' now treated like a footnote. + + Simplified parsing of LaTeX command arguments and options.+ commandArgs now returns a list of arguments OR options (in+ whatever order they appear). The brackets are included, and+ a new stripFirstAndLast function is provided to strip them off+ when needed. This fixes a problem in dealing with \newcommand+ and \newenvironment.++ * Revised RTF writer:++ + Default font is now Helvetica.+ + An '\f0' is added to each '\pard', so that font resizing works+ correctly.++ * Moved handling of "smart typography" from the writers to the Markdown+ and LaTeX readers. This allows great simplification of the writers+ and more accurate smart quotes, dashes, and ellipses. DocBook can+ now use '<quote>'. The '--smart' option now toggles an option in+ the parser state rather than a writer option. Several new kinds+ of inline elements have been added: Quoted, Ellipses, Apostrophe,+ EmDash, EnDash.++ * Changes in HTML writer:++ + Include title block in header even when title is null.+ + Made javascript obfuscation of emails even more obfuscatory,+ by combining it with entity obfuscation.++ * Changed default ASCIIMathML text color to black.++ * Test suite:++ + Added --strip-trailing-cr option to diff in runtests.pl, for+ compatibility with Windows.+ + Added regression tests with footnotes in quote blocks and lists.++ * Makefile changes:++ + osx-pkg target creates a Mac OS X package (directory). New osx+ directory contains files needed for construction of the package.+ + osx-dmg target creates a compressed disk image containing the package.+ + win-pkg target creates Windows binary package.+ + tarball target creates distribution source tarball.+ + website target generates pandoc's website automatically, including+ demos. New 'web' directory containts files needed for construction+ of the website (which will be created as the 'pandoc' subdirectory+ of 'web').+ + Makefile checks to see if we're running Windows/Cygwin; if so,+ a '.exe' extension is added to each executable in EXECS.++ * Removed all wrappers except markdown2pdf and html2markdown.++ * Added new wrapper hsmarkdown, to be used as a drop-in replacement+ for Markdown.pl. hsmarkdown calls pandoc with the '--strict'+ option and disables other options.++ * Added code to html2markdown that tries to determine the character + encoding of an HTML file, by parsing the "Content-type" meta tag.++ + If the encoding can't be determined, then if the content is local,+ the local encoding is used; if it comes from a URL, UTF-8 is used + by default.+ + If input is from STDIN, don't try to determine character encoding.+ + Encoding can be specified explicitly using '-e' option.++ * Improved warning messages in wrappers:++ + Print warning if iconv not available+ + More user-friendly error messages in markdown2pdf, when+ pdflatex fails.++ * Code cleanup:++ + Renamed 'Text/Pandoc/HtmlEntities' module to + 'Text/Pandoc/Entities'. Also changed function names so as+ not to be HTML-specific.+ + Refactored SGML string escaping functions from HTML and Docbook+ writers into Text/Pandoc/Shared. (escapeSGML, stringToSGML)+ + Removed 'BlockQuoteContext' from ParserContext, as it isn't+ used anywhere.+ + Removed splitBySpace and replaced it with a general, polymorphic+ splitBy function.+ + Refactored LaTeX reader for clarity (added isArg function).+ + Converted some CR's to LF's in src/ui/default/print.css.+ + Added license text to top of source files.+ + Added module data for haddock to source files.+ + Reformatted code for consistency.++ * Rewrote documentation and man pages. Split README into INSTALL+ and README.++ * Split LICENSE into COPYING and COPYRIGHT.++ * Removed TODO, since we now maintain ToDo on the wiki.++ * Made COPYRIGHT in top level a symlink to debian/copyright, to avoid+ duplication.++ [ Recai Oktaş ]++ * Revamped build process to conform to debian standards and created+ a proper debian package. Closes: #391666.++ * Modified build process to support GHC 6.6.++ + The package can still be compiled using GHC 6.4.2, though because+ of dependencies the "make deb" target works only with GHC 6.6+.+ + The script 'cabalize' is used to create an appropriate+ 'Pandoc.cabal' from 'Pandoc.cabal.in', depending on the GHC and+ Cabal versions.++ * Refactored template processing (fillTemplates.pl).++ * Modified wrapper scripts to make them more robust and portable.+ To avoid code duplication and ensure consistency, wrappers are + generated via a templating system from templates in src/wrappers.++ + Wrappers now accept multiple filenames, when appropriate.+ + Spaces and tabs allowed in filenames.+ + getopts shell builtin is used for portable option parsing.+ + Improved html2markdown's web grabber code, making it more robust,+ configurable and verbose. Added '-e', '-g' options.++ -- Recai Oktaş <roktas@debian.org> Fri, 05 Jan 2007 09:41:19 +0200++pandoc (0.2) unstable; urgency=low++ * Fixed unicode/utf-8 translation++ -- John MacFarlane <jgm@berkeley.edu> Mon, 14 Aug 2006 00:00:00 -0400++pandoc (0.1) unstable; urgency=low++ * Initial creation of debian package ++ -- John MacFarlane <jgm@berkeley.edu> Mon, 14 Aug 2006 00:00:00 -0400
+ debian/compat view
@@ -0,0 +1,1 @@+4
+ debian/control view
@@ -0,0 +1,90 @@+Source: pandoc+Section: text+Priority: optional+Maintainer: Recai Oktaş <roktas@debian.org>+Build-Depends: debhelper (>= 4.0.0), haskell-devscripts (>=0.5.12), ghc6 (>= 6.6-1), libghc6-xhtml-dev, libghc6-mtl-dev, perl+Build-Depends-Indep: haddock+Standards-Version: 3.7.2.0++Package: pandoc+Section: text+Architecture: any+Depends: ${shlibs:Depends}+Suggests: texlive-latex-recommended | tetex-extra, tidy, wget | w3m+Description: general markup converter+ Pandoc is a Haskell library for converting from one markup format to+ another, and a command-line tool that uses this library. It can read+ markdown and (subsets of) reStructuredText, HTML, and LaTeX, and it+ can write markdown, reStructuredText, HTML, LaTeX, ConTeXt, DocBook,+ RTF, groff man pages, and S5 HTML slide shows.+ .+ Pandoc extends standard markdown syntax with footnotes, embedded LaTeX,+ tables, definition lists, and other features. A compatibility mode is+ provided for those who need a drop-in replacement for Markdown.pl.+ Included wrapper scripts make it easy to convert markdown documents to+ PDFs and to convert web pages to markdown documents.+ .+ In contrast to existing tools for converting markdown to HTML, which+ use regex substitutions, pandoc has a modular design: it consists of a+ set of readers, which parse text in a given format and produce a native+ representation of the document, and a set of writers, which convert+ this native representation into a target format. Thus, adding an input+ or output format requires only adding a reader or writer.+ .+ Homepage: http://sophos.berkeley.edu/macfarlane/pandoc/++Package: libghc6-pandoc-dev+Section: libdevel+Architecture: any+Depends: ${haskell:Depends}+Suggests: pandoc-doc+Description: general markup converter+ Pandoc is a Haskell library for converting from one markup format to+ another, and a command-line tool that uses this library. It can read+ markdown and (subsets of) reStructuredText, HTML, and LaTeX, and it+ can write markdown, reStructuredText, HTML, LaTeX, ConTeXt, DocBook,+ RTF, groff man pages, and S5 HTML slide shows.+ .+ Pandoc extends standard markdown syntax with footnotes, embedded LaTeX,+ tables, definition lists, and other features. A compatibility mode is+ provided for those who need a drop-in replacement for Markdown.pl.+ Included wrapper scripts make it easy to convert markdown documents to+ PDFs and to convert web pages to markdown documents.+ .+ In contrast to existing tools for converting markdown to HTML, which+ use regex substitutions, pandoc has a modular design: it consists of a+ set of readers, which parse text in a given format and produce a native+ representation of the document, and a set of writers, which convert+ this native representation into a target format. Thus, adding an input+ or output format requires only adding a reader or writer.+ .+ This package contains the libraries compiled for GHC 6.+ .+ Homepage: http://sophos.berkeley.edu/macfarlane/pandoc/++Package: pandoc-doc+Section: doc+Architecture: all+Description: general markup converter+ Pandoc is a Haskell library for converting from one markup format to+ another, and a command-line tool that uses this library. It can read+ markdown and (subsets of) reStructuredText, HTML, and LaTeX, and it+ can write markdown, reStructuredText, HTML, LaTeX, ConTeXt, DocBook,+ RTF, groff man pages, and S5 HTML slide shows.+ .+ Pandoc extends standard markdown syntax with footnotes, embedded LaTeX,+ tables, definition lists, and other features. A compatibility mode is+ provided for those who need a drop-in replacement for Markdown.pl.+ Included wrapper scripts make it easy to convert markdown documents to+ PDFs and to convert web pages to markdown documents.+ .+ In contrast to existing tools for converting markdown to HTML, which+ use regex substitutions, pandoc has a modular design: it consists of a+ set of readers, which parse text in a given format and produce a native+ representation of the document, and a set of writers, which convert+ this native representation into a target format. Thus, adding an input+ or output format requires only adding a reader or writer.+ .+ This package contains the library documentation for Pandoc.+ .+ Homepage: http://sophos.berkeley.edu/macfarlane/pandoc/
+ debian/copyright view
@@ -0,0 +1,82 @@+Pandoc+Copyright (C) 2006-7 John MacFarlane <jgm at berkeley dot edu>++This code is released under the [GPL], version 2 or later:++ This program is free software; you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation; either version 2 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program; if not, write to the Free Software+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA++The GNU General Public License is available in the file COPYING in+the source distribution. On Debian systems, the complete text of the+GPL can be found in `/usr/share/common-licenses/GPL`.++[GPL]: http://www.gnu.org/copyleft/gpl.html++Pandoc's complete source code is available from the [Pandoc home page].++[Pandoc home page]: http://sophos.berkeley.edu/macfarlane/pandoc/ ++Pandoc includes some code from other authors. The copyright and license+statements for these sources are included below. All are GPL-compatible+licenses.++----------------------------------------------------------------------+UTF8.hs +Copyright (c) 2003, OGI School of Science & Engineering, Oregon Health &+Science University, All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++- Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++- Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++- Neither the name of OGI or OHSU nor the names of its+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++This version of UTF8.hs was Modified by Martin Norbäck, to pass illegal+utf-8 sequences through unchanged.++----------------------------------------------------------------------+ASCIIMathML.js+Copyright 2005, Peter Jipsen, Chapman University+<http://www1.chapman.edu/~jipsen/mathml/asciimath.html>++Released under the GPL.++----------------------------------------------------------------------+S5 slides.js and css files +by Eric A. Meyer+<http://meyerweb.com/eric/tools/s5++Released under an explicit Public Domain License
+ debian/pandoc-doc.doc-base view
@@ -0,0 +1,11 @@+Document: pandoc-doc+Title: Pandoc documentation+Author: John MacFarlane+Abstract: This is the documentation of Pandoc, which includes the API+ documentation of the Pandoc library and documentation for the Pandoc+ tools. +Section: Apps/Programming++Format: html+Index: /usr/share/doc/pandoc-doc/html/index.html+Files: /usr/share/doc/pandoc-doc/html/*.html
+ debian/pandoc-doc.docs view
@@ -0,0 +1,1 @@+html
+ debian/pandoc.dirs view
@@ -0,0 +1,1 @@+usr/bin
+ debian/rules view
@@ -0,0 +1,122 @@+#!/usr/bin/make -f+#+# debian/rules for pandoc.+# Copyright © 2006 Recai Oktaş <roktasATdebian.org>+#+# This file is based on John Goerzen's Cabal Debian template.+# See http://www.n-heptane.com/nhlab/repos/cabalDebianTemplate/+#+# Licensed under the GNU General Public License, version 2.+# See the file 'http://www.gnu.org/copyleft/gpl.txt'.++THIS := $(shell sed -ne 's/^Source: \(.*\)/\1/p' debian/control)+PREFIX := /usr+DESTDIR := debian/$(THIS)++# Uncomment this to turn on verbose mode.+#export DH_VERBOSE=1++ifeq (1,$(DH_VERBOSE))+HCFLAGS+=-v+endif++# Handle noopt in DEB_BUILD_OPTIONS. Emulate CFLAGS (as HCFLAGS).+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))+HCFLAGS+=-O0+else+# No optimisation seems optimum.+HCFLAGS+=-O0+endif++# Export all variables which will be used in various stages of build process.+export PREFIX DESTDIR HCFLAGS++configure: configure-stamp+configure-stamp:+ dh_testdir+ $(MAKE) configure++ touch configure-stamp++build: build-stamp+build-stamp: configure-stamp + dh_testdir++ touch build-stamp++clean:+ dh_testdir+ dh_testroot+ $(MAKE) clean+ rm -rf setup Setup.hi Setup.ho Setup.o .*config* dist html+ rm -f build-stamp configure-stamp++ dh_clean ++install: build+ dh_testdir+ dh_testroot+ dh_clean -k + dh_installdirs -a ++ dh_haskell -a++ # Hack! Cabal builds executables while building libraries. Move these+ # files to top dir where the Makefile install target expects to find.+ # See "BUGS" section at the following document:+ # http://www.n-heptane.com/nhlab/repos/cabalDebianTemplate/INSTRUCTIONS.txt+ find debian/libghc6-$(THIS)-dev -type d -name 'bin' -true | \+ while read bin; do mv $$bin/* .; rm -rf $$bin; done+ $(MAKE) install-program++build-indep: build-indep-stamp+build-indep-stamp:+ dh_testdir+ $(MAKE) build-lib-doc++install-indep: build-indep+ dh_testdir+ dh_testroot+ dh_clean -k+ dh_installdirs -i++ dh_haskell -i++# Build architecture-independent files here.+binary-indep: build-indep install-indep+ dh_testdir+ dh_testroot+ dh_installchangelogs -i+ dh_installdocs -i+ dh_installexamples -i+ dh_installman -i+ dh_link -i+ dh_strip -i+ dh_compress -i+ dh_fixperms -i+ dh_installdeb -i+ dh_shlibdeps -i+ dh_gencontrol -i+ dh_md5sums -i+ dh_builddeb -i++# Build architecture-dependent files here.+binary-arch: build install+ dh_testdir+ dh_testroot+ dh_installchangelogs -a+ dh_installdocs -a+ dh_installexamples -a+ dh_installman -a+ dh_link -a+ dh_strip -a -Xhtml2 -Xmarkdown2 -Xlatex2 -Xrst2+ dh_compress -a+ dh_fixperms -a+ dh_installdeb -a+ dh_shlibdeps -a+ dh_gencontrol -a+ dh_md5sums -a+ dh_builddeb -a++binary: binary-indep binary-arch+.PHONY: build clean binary-indep binary-arch binary install build-indep install-indep
+ freebsd/Makefile view
@@ -0,0 +1,44 @@+# New ports collection makefile for: pandoc+# Date created: 9 February 2007+# Whom: John MacFarlane <jgm@berkeley.edu>+#+# $FreeBSD: ports/textproc/pandoc/Makefile,v 1.1 2007/02/11 17:21:55 nox Exp $+#++PORTNAME= pandoc+PORTVERSION= 0.4+CATEGORIES= textproc haskell+MASTER_SITES= http://pandoc.googlecode.com/files/+DISTNAME= pandoc-${PORTVERSION}++MAINTAINER= jgm@berkeley.edu+COMMENT= A general markup converter++BUILD_DEPENDS= ghc>=6.6:${PORTSDIR}/lang/ghc++MANCOMPRESSED= no+MAN1= pandoc.1 markdown2pdf.1 html2markdown.1 hsmarkdown.1++USE_GMAKE= yes+USE_PERL5= yes++PLIST_FILES= bin/pandoc bin/markdown2pdf bin/html2markdown bin/hsmarkdown+PORTDOCS= BUGS README README.html+SCRIPTS= hsmarkdown html2markdown markdown2pdf++do-install:+ @${INSTALL_PROGRAM} ${WRKSRC}/dist/build/pandoc/pandoc ${PREFIX}/bin+.for script in ${SCRIPTS}+ @${INSTALL_SCRIPT} ${WRKSRC}/${script} ${PREFIX}/bin+.endfor+.for man in ${MAN1}+ @${INSTALL_MAN} ${WRKSRC}/man/man1/${man} ${PREFIX}/man/man1+.endfor+.if !defined(NOPORTDOCS)+ @${MKDIR} ${DOCSDIR}+.for doc in ${PORTDOCS}+ @${INSTALL_DATA} ${WRKSRC}/${doc} ${DOCSDIR}+.endfor+.endif++.include <bsd.port.mk>
+ freebsd/distinfo view
@@ -0,0 +1,3 @@+MD5 (pandoc-0.3.tar.gz) = 08ea5da564b721bd3cd52eee316143a1+SHA256 (pandoc-0.3.tar.gz) = b010436d325c8ec67e2f9c238474089f76c895bec3ef19ca13c82da5860a4b05+SIZE (pandoc-0.3.tar.gz) = 243335
+ freebsd/pkg-descr view
@@ -0,0 +1,19 @@+Pandoc is a command-line tool for converting from one markup format+to another. It can read markdown and (subsets of) reStructuredText,+HTML, and LaTeX, and it can write markdown, reStructuredText, HTML,+LaTeX, ConTeXt, DocBook, RTF, groff man pages, and S5 HTML slide shows.++Pandoc extends standard markdown syntax with footnotes, embedded LaTeX,+and other features. A compatibility mode is provided for those who+need a drop-in replacement for Markdown.pl. Included wrapper scripts+make it easy to convert markdown documents to PDFs and to convert web+pages to markdown documents.++In contrast to existing tools for converting markdown to HTML, which+use regex substitutions, pandoc has a modular design: it consists of a+set of readers, which parse text in a given format and produce a native+representation of the document, and a set of writers, which convert+this native representation into a target format. Thus, adding an input+or output format requires only adding a reader or writer.++WWW: http://sophos.berkeley.edu/macfarlane/pandoc/
+ hsmarkdown view
@@ -0,0 +1,5 @@+#!/bin/sh+# hsmarkdown - intended as a drop-in replacement for Markdown.pl.+# Uses pandoc to convert from markdown to HTML, using --strict mode+# for maximum compatibility with official markdown syntax.+exec pandoc --from markdown --to html --strict -- "$@"
+ html2markdown view
@@ -0,0 +1,216 @@+#!/bin/sh -e+# converts HTML from a URL, file, or stdin to markdown+# uses an available program to fetch URL and tidy to normalize it first++REQUIRED="tidy"+SYNOPSIS="converts HTML from a URL, file, or STDIN to markdown-formatted text."++THIS=${0##*/}++NEWLINE='+'++err () { echo "$*" | fold -s -w ${COLUMNS:-110} >&2; }+errn () { printf "$*" | fold -s -w ${COLUMNS:-110} >&2; }++usage () {+ err "$1 - $2" # short description+ err "See the $1(1) man page for usage."+}++# Portable which(1).+pathfind () {+ oldifs="$IFS"; IFS=':'+ for _p in $PATH; do+ if [ -x "$_p/$*" ] && [ -f "$_p/$*" ]; then+ IFS="$oldifs"+ return 0+ fi+ done+ IFS="$oldifs"+ return 1+}++for p in pandoc $REQUIRED; do+ pathfind $p || {+ err "You need '$p' to use this program!"+ exit 1+ }+done++CONF=$(pandoc --dump-args "$@" 2>&1) || {+ errcode=$?+ echo "$CONF" | sed -e '/^pandoc \[OPTIONS\] \[FILES\]/,$d' >&2+ [ $errcode -eq 2 ] && usage "$THIS" "$SYNOPSIS"+ exit $errcode+}++OUTPUT=$(echo "$CONF" | sed -ne '1p')+ARGS=$(echo "$CONF" | sed -e '1d')+++grab_url_with () {+ url="${1:?internal error: grab_url_with: url required}"++ shift+ cmdline="$@"++ prog=+ prog_opts=+ if [ -n "$cmdline" ]; then+ eval "set -- $cmdline"+ prog=$1+ shift+ prog_opts="$@"+ fi++ if [ -z "$prog" ]; then+ # Locate a sensible web grabber (note the order).+ for p in wget lynx w3m curl links w3c; do+ if pathfind $p; then+ prog=$p+ break+ fi+ done++ [ -n "$prog" ] || {+ errn "$THIS: Couldn't find a program to fetch the file from URL "+ err "(e.g. wget, w3m, lynx, w3c, or curl)."+ return 1+ }+ else+ pathfind "$prog" || {+ err "$THIS: No such web grabber '$prog' found; aborting."+ return 1+ }+ fi++ # Setup proper base options for known grabbers.+ base_opts=+ case "$prog" in+ wget) base_opts="-O-" ;;+ lynx) base_opts="-source" ;;+ w3m) base_opts="-dump_source" ;;+ curl) base_opts="" ;;+ links) base_opts="-source" ;;+ w3c) base_opts="-n -get" ;;+ *) err "$THIS: unhandled web grabber '$prog'; hope it succeeds."+ esac++ err "$THIS: invoking '$prog $base_opts $prog_opts $url'..."+ eval "set -- $base_opts $prog_opts"+ $prog "$@" "$url"+}++# Parse command-line arguments+parse_arguments () {+ while [ $# -gt 0 ]; do+ case "$1" in+ --encoding=*)+ wholeopt="$1"+ # extract encoding from after =+ encoding="${wholeopt#*=}" ;;+ -e|--encoding|-encoding)+ shift+ encoding="$1" ;; + --grabber=*)+ wholeopt="$1"+ # extract encoding from after =+ grabber="\"${wholeopt#*=}\"" ;;+ -g|--grabber|-grabber)+ shift+ grabber="$1" ;; + *)+ if [ -z "$argument" ]; then+ argument="$1"+ else+ err "Warning: extra argument '$1' will be ignored."+ fi ;;+ esac+ shift+ done+}++argument=+encoding=+grabber=++oldifs="$IFS"+IFS=$NEWLINE+parse_arguments $ARGS+IFS="$oldifs"++inurl=+if [ -n "$argument" ] && ! [ -f "$argument" ]; then+ # Treat given argument as an URL.+ inurl="$argument"+fi++if [ -n "$inurl" ]; then+ err "Attempting to fetch file from '$inurl'..."++ # As a security measure refuse to proceed if mktemp is not available.+ pathfind mktemp || { err "Couldn't find 'mktemp'; aborting."; exit 1; }+ + # Avoid issues with /tmp directory on Windows/Cygwin + cygwin=+ cygwin=$(uname | sed -ne '/^CYGWIN/p')+ if [ -n "$cygwin" ]; then+ TMPDIR=.+ export TMPDIR+ fi+ + THIS_TEMPDIR=+ THIS_TEMPDIR="$(mktemp -d -t $THIS.XXXXXXXX)" || exit 1+ readonly THIS_TEMPDIR+ + trap 'exitcode=$?+ [ -z "$THIS_TEMPDIR" ] || rm -rf "$THIS_TEMPDIR"+ exit $exitcode' 0 1 2 3 13 15++ grabber_out=$THIS_TEMPDIR/grabber.out+ grabber_log=$THIS_TEMPDIR/grabber.log+ if ! grab_url_with "$inurl" "$grabber" 1>$grabber_out 2>$grabber_log; then+ errn "grab_url_with failed"+ if [ -f $grabber_log ]; then+ err " with the following error log."+ err+ cat >&2 $grabber_log+ else+ err .+ fi+ exit 1+ fi++ argument="$grabber_out"+fi++if [ -z "$encoding" ] && [ "x$argument" != "x" ]; then+ # Try to determine character encoding if not specified+ # and input is not STDIN.+ encoding=$(+ head "$argument" |+ LC_ALL=C tr 'A-Z' 'a-z' |+ sed -ne '/<meta .*content-type.*charset=/ {+ s/.*charset=["'\'']*\([-a-zA-Z0-9]*\).*["'\'']*/\1/p+ }'+ )+fi++if [ -n "$encoding" ] && pathfind iconv; then+ alias to_utf8='iconv -f "$encoding" -t utf-8'+else # assume UTF-8+ alias to_utf8='cat'+fi ++if [ -z "$argument" ]; then+ tidy -asxhtml -utf8 2>/dev/null | pandoc --ignore-args -r html -w markdown "$@"+else+ if [ -f "$argument" ]; then+ to_utf8 "$argument" | + tidy -asxhtml -utf8 2>/dev/null | pandoc --ignore-args -r html -w markdown "$@"+ else+ err "File '$argument' not found."+ exit 1+ fi+fi
+ man/man1/hsmarkdown.1.md view
@@ -0,0 +1,42 @@+% HSMARKDOWN(1) Pandoc User Manuals+% John MacFarlane+% June 30, 2007++# NAME++hsmarkdown - convert markdown-formatted text to HTML++# SYNOPSIS++hsmarkdown [*input-file*]...++# DESCRIPTION++`hsmarkdown` converts markdown-formatted text to HTML. It is designed+to be usable as a drop-in replacement for John Gruber's `Markdown.pl`.++If no *input-file* is specified, input is read from STDIN.+Otherwise, the *input-files* are concatenated (with a blank+line between each) and used as input. Output goes to STDOUT by+default. For output to a file, use shell redirection:++ hsmarkdown input.txt > output.html++`hsmarkdown` uses the UTF-8 character encoding for both input and output.+If your local character encoding is not UTF-8, you should pipe input+and output through `iconv`:++ iconv -t utf-8 input.txt | hsmarkdown | iconv -f utf-8++`hsmarkdown` is implemented as a wrapper around `pandoc`(1). It+calls `pandoc` with the options `--from markdown --to html+--strict` and disables all other options. (Command-line options+will be interpreted as filenames, as they are by `Markdown.pl`.)++# SEE ALSO++`pandoc`(1). The *README*+file distributed with Pandoc contains full documentation.++The Pandoc source code and all documentation may be downloaded from+<http://sophos.berkeley.edu/macfarlane/pandoc/>.
+ man/man1/html2markdown.1.md view
@@ -0,0 +1,92 @@+% HTML2MARKDOWN(1) Pandoc User Manuals+% John MacFarlane and Recai Oktas+% June 30, 2007++# NAME++html2markdown - converts HTML to markdown-formatted text++# SYNOPSIS++html2markdown [*pandoc-options*] [\-- *special-options*] [*input-file* or+*URL*]++# DESCRIPTION++`html2markdown` converts *input-file* or *URL* (or text+from STDIN) from HTML to markdown-formatted plain text. +If a URL is specified, `html2markdown` uses an available program+(e.g. wget, w3m, lynx or curl) to fetch its contents. Output is sent+to STDOUT unless an output file is specified using the `-o`+option.++`html2markdown` uses the character encoding specified in the+"Content-type" meta tag. If this is not present, or if input comes+from STDIN, UTF-8 is assumed. A character encoding may be specified+explicitly using the `-e` special option.++# OPTIONS++`html2markdown` is a wrapper for `pandoc`, so all of+`pandoc`'s options may be used. See `pandoc`(1) for+a complete list. The following options are most relevant:++-s, \--standalone+: Include title, author, and date information (if present) at the+ top of markdown output.++-o *FILE*, \--output=*FILE*+: Write output to *FILE* instead of STDOUT. ++\--strict+: Use strict markdown syntax, with no extensions or variants.++\--reference-links+: Use reference-style links, rather than inline links, in writing markdown+ or reStructuredText.++-R, \--parse-raw+: Parse untranslatable HTML codes as raw HTML.++-H *FILE*, \--include-in-header=*FILE*+: Include contents of *FILE* at the end of the header. Implies+ `-s`.++-B *FILE*, \--include-before-body=*FILE*+: Include contents of *FILE* at the beginning of the document body.++-A *FILE*, \--include-after-body=*FILE*+: Include contents of *FILE* at the end of the document body.++-C *FILE*, \--custom-header=*FILE*+: Use contents of *FILE*+ as the document header (overriding the default header, which can be+ printed using `pandoc -D markdown`). Implies `-s`.++# SPECIAL OPTIONS++In addition, the following special options may be used. The special+options must be separated from the `html2markdown` command and any+regular `pandoc` options by the delimiter \``--`', as in++ html2markdown -o foo.txt -- -g 'curl -u bar:baz' -e latin1 \+ www.foo.com++-e *encoding*, \--encoding=*encoding* +: Assume the character encoding *encoding* in reading HTML.+ (Note: *encoding* will be passed to `iconv`; a list of+ available encodings may be obtained using `iconv -l`.)+ If this option is not specified and input is not from+ STDIN, `html2markdown` will try to extract the character encoding+ from the "Content-type" meta tag. If no character encoding is+ specified in this way, or if input is from STDIN, UTF-8 will be+ assumed.++-g *command*, \--grabber=*command*+: Use *command* to fetch the contents of a URL. (By default,+ `html2markdown` searches for an available program or text-based+ browser to fetch the contents of a URL.)++# SEE ALSO++`pandoc`(1), `iconv`(1)
+ man/man1/markdown2pdf.1.md view
@@ -0,0 +1,69 @@+% MARKDOWN2PDF(1) Pandoc User Manuals+% John MacFarlane and Recai Oktas+% June 30, 2007++# NAME++markdown2pdf - converts markdown-formatted text to PDF, using pdflatex ++# SYNOPSIS++markdown2pdf [*options*] [*input-file*]...++# DESCRIPTION++`markdown2pdf` converts *input-file* (or text from standard +input) from markdown-formatted plain text to PDF, using `pdflatex`.+If no output filename is specified (using the `-o` option),+the name of the output file is derived from the input file; thus, for+example, if the input file is *hello.txt*, the output file will be+*hello.pdf*. If the input is read from STDIN and no output filename+is specified, the output file will be named *stdin.pdf*. If multiple+input files are specified, they will be concatenated before conversion,+and the name of the output file will be derived from the first input file.++Input is assumed to be in the UTF-8 character encoding. If your+local character encoding is not UTF-8, you should pipe input and+output through `iconv`:++ iconv -t utf-8 input.txt | pandoc | iconv -f utf-8++`markdown2pdf` assumes that the `unicode`, `array`, `fancyvrb`,+`graphicx`, and `ulem` packages are in latex's search path. If these+packages are not included in your latex setup, they can be obtained from+<http://ctan.org>.++# OPTIONS++`markdown2pdf` is a wrapper around `pandoc`, so all of+`pandoc`'s options can be used with `markdown2pdf` as well.+See `pandoc`(1) for a complete list.+The following options are most relevant:++-o *FILE*, \--output=*FILE*+: Write output to *FILE*.++\--strict+: Use strict markdown syntax, with no extensions or variants.++-N, \--number-sections+: Number section headings in LaTeX output. (Default is not to number them.)++-H *FILE*, \--include-in-header=*FILE*+: Include (LaTeX) contents of *FILE* at the end of the header. Implies+ `-s`.++-B *FILE*, \--include-before-body=*FILE*+: Include (LaTeX) contents of *FILE* at the beginning of the document body.++-A *FILE*, \--include-after-body=*FILE*+: Include (LaTeX) contents of *FILE* at the end of the document body.++-C *FILE*, \--custom-header=*FILE*+: Use contents of *FILE*+ as the LaTeX document header (overriding the default header, which can be+ printed using `pandoc -D latex`). Implies `-s`.++# SEE ALSO++`pandoc`(1), `pdflatex`(1)
+ man/man1/pandoc.1.md view
@@ -0,0 +1,180 @@+% PANDOC(1) Pandoc User Manuals+% John MacFarlane+% June 30, 2007++# NAME++pandoc - general markup converter++# SYNOPSIS++pandoc [*options*] [*input-file*]...++# DESCRIPTION++Pandoc converts files from one markup format to another. It can+read markdown and (subsets of) reStructuredText, HTML, and LaTeX, and+it can write markdown, reStructuredText, HTML, LaTeX, ConTeXt, groff man,+RTF, DocBook XML, and S5 HTML slide shows.++If no *input-file* is specified, input is read from STDIN.+Otherwise, the *input-files* are concatenated (with a blank+line between each) and used as input. Output goes to STDOUT by+default. For output to a file, use the `-o` option:++ pandoc -o output.html input.txt++The input and output formats may be specified using command-line options+(see **OPTIONS**, below, for details). If these formats are not+specified explicitly, Pandoc will attempt to determine them+from the extensions of the input and output filenames. If input comes+from STDIN or from a file with an unknown extension, the input is assumed+to be markdown. If no output filename is specified using the `-o`+option, or if a filename is specified but its extension is unknown,+the output will default to HTML. Thus, for example,++ pandoc -o chap1.tex chap1.txt++converts *chap1.txt* from markdown to LaTeX. And++ pandoc README++converts *README* from markdown to HTML.++Pandoc's version of markdown is an extended variant of standard+markdown: the differences are described in the *README* file in+the user documentation. If standard markdown syntax is desired, the+`--strict` option may be used.++Pandoc uses the UTF-8 character encoding for both input and output.+If your local character encoding is not UTF-8, you should pipe input+and output through `iconv`:++ iconv -t utf-8 input.txt | pandoc | iconv -f utf-8++Pandoc's HTML parser is not very forgiving. If your input is+HTML, consider running it through `tidy`(1) before passing it+to Pandoc. Or use `html2markdown`(1), a wrapper around `pandoc`.++# OPTIONS++-f *FORMAT*, -r *FORMAT*, \--from=*FORMAT*, \--read=*FORMAT*+: Specify input format. *FORMAT* can be+ `native` (native Haskell), `markdown` (markdown or plain text),+ `rst` (reStructuredText), `html` (HTML), or `latex` (LaTeX).++-t *FORMAT*, -w *FORMAT*, \--to=*FORMAT*, \--write=*FORMAT*+: Specify output format. *FORMAT* can be `native` (native Haskell),+ `man` (groff man page),+ `markdown` (markdown or plain text), `rst` (reStructuredText),+ `html` (HTML), `latex` (LaTeX), `context` (ConTeXt), `man` (groff man), + `docbook` (DocBook XML), `s5` (S5 HTML and javascript slide show),+ or `rtf` (rich text format).++-s, \--standalone+: Produce output with an appropriate header and footer (e.g. a+ standalone HTML, LaTeX, or RTF file, not a fragment).++-o *FILE*, \--output=*FILE*+: Write output to *FILE* instead of STDOUT. If *FILE* is+ \``-`', output will go to STDOUT.++-p, \--preserve-tabs+: Preserve tabs instead of converting them to spaces.++\--tab-stop=*TABSTOP*+: Specify tab stop (default is 4).++\--strict+: Use strict markdown syntax, with no extensions or variants.++\--reference-links+: Use reference-style links, rather than inline links, in writing markdown+ or reStructuredText.++-R, \--parse-raw+: Parse untranslatable HTML codes and LaTeX environments as raw HTML+ or LaTeX, instead of ignoring them.++-S, \--smart+: Use smart quotes, dashes, and ellipses. (This option is significant+ only when the input format is `markdown`. It is selected automatically+ when the output format is `latex` or `context`.)++-m*URL*, \--asciimathml=*URL*+: Use ASCIIMathML to display embedded LaTeX math in HTML output.+ To insert a link to a local copy of the `ASCIIMathML.js` script,+ provide a *URL*. If no *URL* is provided, the contents of the+ script will be inserted directly into the HTML header.++-i, \--incremental+: Make list items in S5 display incrementally (one by one).++-N, \--number-sections+: Number section headings in LaTeX output. (Default is not to number+ them.)++\--toc, \--table-of-contents+: Include an automatically generated table of contents (HTML, markdown,+ RTF) or an instruction to create one (LaTeX, reStructuredText).+ This option has no effect on man, DocBook, or S5 output.++-c *CSS*, \--css=*CSS*+: Link to a CSS style sheet. *CSS* is the pathname of the style sheet.++-H *FILE*, \--include-in-header=*FILE*+: Include contents of *FILE* at the end of the header. Implies `-s`.++-B *FILE*, \--include-before-body=*FILE*+: Include contents of *FILE* at the beginning of the document body.++-A *FILE*, \--include-after-body=*FILE*+: Include contents of *FILE* at the end of the document body.++-C *FILE*, \--custom-header=*FILE*+: Use contents of *FILE* as the document header (overriding the+ default header, which can be printed by using the `-D` option).+ Implies `-s`.++-D *FORMAT*, \--print-default-header=*FORMAT*+: Print the default header for *FORMAT* (`html`, `s5`, `latex`,+ `context`, `docbook`, `man`, `markdown`, `rst`, `rtf`).++-T *STRING*, \--title-prefix=*STRING*+: Specify *STRING* as a prefix to the HTML window title.++\--dump-args+: Print information about command-line arguments to STDOUT, then exit.+ The first line of output contains the name of the output file specified+ with the `-o` option, or \``-`' (for STDOUT) if no output file was+ specified. The remaining lines contain the command-line arguments,+ one per line, in the order they appear. These do not include regular+ Pandoc options and their arguments, but do include any options appearing+ after a \``--`' separator at the end of the line.+ This option is intended primarily for use in wrapper scripts.++\--ignore-args+: Ignore command-line arguments (for use in wrapper scripts).+ Regular Pandoc options are not ignored. Thus, for example,++: pandoc --ignore-args -o foo.html -s foo.txt -- -e latin1++: is equivalent to++: pandoc -o foo.html -s++-v, \--version+: Print version.++-h, \--help+: Show usage message.++# SEE ALSO++`html2markdown`(1),+`markdown2pdf`(1).+The *README* file distributed with Pandoc contains full documentation.++The Pandoc source code and all documentation may be downloaded from+<http://sophos.berkeley.edu/macfarlane/pandoc/>.+
+ markdown2pdf view
@@ -0,0 +1,140 @@+#!/bin/sh -e++REQUIRED="pdflatex"+SYNOPSIS="converts markdown-formatted text to PDF, using pdflatex."++THIS=${0##*/}++NEWLINE='+'++err () { echo "$*" | fold -s -w ${COLUMNS:-110} >&2; }+errn () { printf "$*" | fold -s -w ${COLUMNS:-110} >&2; }++usage () {+ err "$1 - $2" # short description+ err "See the $1(1) man page for usage."+}++# Portable which(1).+pathfind () {+ oldifs="$IFS"; IFS=':'+ for _p in $PATH; do+ if [ -x "$_p/$*" ] && [ -f "$_p/$*" ]; then+ IFS="$oldifs"+ return 0+ fi+ done+ IFS="$oldifs"+ return 1+}++for p in pandoc $REQUIRED; do+ pathfind $p || {+ err "You need '$p' to use this program!"+ exit 1+ }+done++CONF=$(pandoc --dump-args "$@" 2>&1) || {+ errcode=$?+ echo "$CONF" | sed -e '/^pandoc \[OPTIONS\] \[FILES\]/,$d' >&2+ [ $errcode -eq 2 ] && usage "$THIS" "$SYNOPSIS"+ exit $errcode+}++OUTPUT=$(echo "$CONF" | sed -ne '1p')+ARGS=$(echo "$CONF" | sed -e '1d')+++# As a security measure refuse to proceed if mktemp is not available.+pathfind mktemp || { err "Couldn't find 'mktemp'; aborting."; exit 1; }++# Avoid issues with /tmp directory on Windows/Cygwin +cygwin=+cygwin=$(uname | sed -ne '/^CYGWIN/p')+if [ -n "$cygwin" ]; then+ TMPDIR=.+ export TMPDIR+fi++THIS_TEMPDIR=+THIS_TEMPDIR="$(mktemp -d -t $THIS.XXXXXXXX)" || exit 1+readonly THIS_TEMPDIR++trap 'exitcode=$?+ [ -z "$THIS_TEMPDIR" ] || rm -rf "$THIS_TEMPDIR"+ exit $exitcode' 0 1 2 3 13 15++texname=output+logfile=$THIS_TEMPDIR/log++pandoc -s -r markdown -w latex "$@" -o $THIS_TEMPDIR/$texname.tex++if [ "$OUTPUT" = "-" ]; then+ firstinfile="$(echo $ARGS | sed -ne '1p')"+ firstinfilebase="${firstinfile%.*}"+ destname="${firstinfilebase:-stdin}.pdf"+else+ destname="$OUTPUT"+fi++(+ origdir=$(pwd)+ cd $THIS_TEMPDIR+ TEXINPUTS=$origdir:$TEXINPUTS:+ export TEXINPUTS+ finished=no+ runs=0+ while [ $finished = "no" ]; do+ pdflatex -interaction=batchmode $texname.tex >/dev/null || {+ errcode=$?+ err "${THIS}: pdfLaTeX failed with error code $errcode"+ [ -f $texname.log ] && {+ err "${THIS}: error context:"+ sed -ne '/^!/,/^[[:space:]]*$/p' \+ -ne '/^[Ll]a[Tt]e[Xx] [Ww]arning/,/^[[:space:]]*$/p' \+ -ne '/^[Ee]rror/,/^[[:space:]]*$/p' $texname.log >&2+ if grep -q "File \`ucs.sty' not found" $texname.log; then+ err "${THIS}: Please install the 'unicode' package from CTAN:"+ err " http://www.ctan.org/tex-archive/macros/latex/contrib/unicode/"+ fi+ if grep -q "File \`ulem.sty' not found" $texname.log; then+ err "${THIS}: Please install the 'ulem' package from CTAN:"+ err " http://www.ctan.org/tex-archive/macros/latex/contrib/misc/ulem.sty"+ fi+ }+ exit $errcode+ }+ if [ $runs -lt 3 ] && + ((grep -q "LaTeX Warning: There were undefined references." $texname.log) ||+ (echo "$@" | grep -q -- "--toc\|--table-of-contents")); then+ runs=$(($runs + 1))+ if grep -q "LaTeX Warning:.*[Cc]itation" $texname.log; then+ bibtex $texname 2>&1 >bibtex.err+ if [ $runs -gt 2 ]; then+ if grep -q "error message" bibtex.err ||+ grep -q "Warning" bibtex.err; then+ cat bibtex.err >&2+ fi+ fi+ fi+ else+ finished=yes+ fi+ done+) || exit $?++is_target_exists=+if [ -f "$destname" ]; then+ is_target_exists=1+ mv "$destname" "$destname~" +fi++mv -f $THIS_TEMPDIR/$texname.pdf "$destname"++errn "Created $destname"+[ -z "$is_target_exists" ] || {+ errn " (previous file has been backed up as $destname~)"+}+err .
+ osx/Description.plist view
@@ -0,0 +1,10 @@+<?xml version="1.0" encoding="UTF-8"?>+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">+<plist version="1.0">+<dict>+ <key>IFPkgDescriptionDescription</key>+ <string></string>+ <key>IFPkgDescriptionTitle</key>+ <string>Pandoc</string>+</dict>+</plist>
+ osx/Info.plist view
@@ -0,0 +1,42 @@+<?xml version="1.0" encoding="UTF-8"?>+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">+<plist version="1.0">+<dict>+ <key>CFBundleGetInfoString</key>+ <string>@VERSION@, (c) 2006 John MacFarlane (released under GPL)</string>+ <key>CFBundleIdentifier</key>+ <string>pandoc</string>+ <key>CFBundleShortVersionString</key>+ <string>@VERSION@</string>+ <key>IFPkgFlagAllowBackRev</key>+ <false/>+ <key>IFPkgFlagAuthorizationAction</key>+ <string>RootAuthorization</string>+ <key>IFPkgFlagBackgroundAlignment</key>+ <string>topleft</string>+ <key>IFPkgFlagBackgroundScaling</key>+ <string>none</string>+ <key>IFPkgFlagDefaultLocation</key>+ <string>/</string>+ <key>IFPkgFlagFollowLinks</key>+ <true/>+ <key>IFPkgFlagInstallFat</key>+ <false/>+ <key>IFPkgFlagInstalledSize</key>+ <integer>1788</integer>+ <key>IFPkgFlagIsRequired</key>+ <false/>+ <key>IFPkgFlagOverwritePermissions</key>+ <false/>+ <key>IFPkgFlagRelocatable</key>+ <false/>+ <key>IFPkgFlagRestartAction</key>+ <string>NoRestart</string>+ <key>IFPkgFlagRootVolumeOnly</key>+ <false/>+ <key>IFPkgFlagUpdateInstalledLanguages</key>+ <false/>+ <key>IFPkgFormatVersion</key>+ <real>0.10000000149011612</real>+</dict>+</plist>
+ osx/Welcome view
@@ -0,0 +1,18 @@+% OS X Installation Notes++Pandoc will be installed into your `@PREFIX@` directory. In order+to use `pandoc` and the associated wrapper scripts, you must have+`@PREFIX@/bin` in your `PATH.` To add `@PREFIX@/bin` to your+default path, add these lines to the end of `.profile` in your home+directory:++ export PATH=$PATH:@PREFIX@/bin+ export MANPATH=$MANPATH:@PREFIX@/share/man++You will have to open a new terminal window for these changes+to take effect.++To uninstall Pandoc at any time, use the following command:++ sudo @PREFIX@/bin/uninstall-pandoc+
+ osx/uninstall-pandoc view
@@ -0,0 +1,43 @@+#!/bin/sh -e+# This script (when run with root permissions) uninstalls+# everything installed by the Pandoc Mac OS X installer.++if [ "`id -u`" != 0 ]; then \+ echo "This script must be run with root privileges:"; \+ echo "sudo /usr/local/bin/uninstall-pandoc"; \+ exit 1; \+fi++MAN_PAGES="pandoc.1 markdown2pdf.1 html2markdown.1 hsmarkdown.1"+EXECUTABLES=`echo $MAN_PAGES | sed -e 's#\.1##g'`+EXECUTABLES="$EXECUTABLES uninstall-pandoc"+DOCUMENTS="`ls /usr/local/share/doc/pandoc`"+TOREMOVE=""+for F in $EXECUTABLES; do+ TOREMOVE="$TOREMOVE /usr/local/bin/$F";+done+for F in $MAN_PAGES; do+ TOREMOVE="$TOREMOVE /usr/local/share/man/man1/$F"; +done+for F in $DOCUMENTS; do+ TOREMOVE="$TOREMOVE /usr/local/share/doc/pandoc/$F";+done+TOREMOVE="$TOREMOVE /usr/local/share/doc/pandoc"++echo "This script will remove all of the files installed"+echo "by the Pandoc Mac OS X installer: $TOREMOVE"+echo "Are you sure you want to continue with this?"++OPTIONS="Continue Quit"+select opt in $OPTIONS; do+ if [ "$opt" = "Quit" ]; then+ exit 0+ elif [ "$opt" = "Continue" ]; then+ echo "Removing..."+ rm -rv $TOREMOVE+ echo "Successfully removed Pandoc."+ exit 0+ else+ echo "Bad option."+ fi+done
+ pandoc.cabal view
@@ -0,0 +1,61 @@+Name: pandoc+Version: 0.4+License: GPL+License-File: COPYING+Copyright: (c) 2006-2007 John MacFarlane+Author: John MacFarlane <jgm@berkeley.edu>+Maintainer: John MacFarlane <jgm@berkeley.edu>+Stability: alpha+Homepage: http://sophos.berkeley.edu/macfarlane/pandoc+Package-URL: http://pandoc.googlecode.com/files/pandoc-0.4.tar.gz+Category: Text+Tested-With: GHC+Synopsis: Conversion between markup formats+Description: Pandoc is a Haskell library for converting from one markup+ format to another, and a command-line tool that uses+ this library. It can read markdown and (subsets of)+ reStructuredText, HTML, and LaTeX, and it can write+ markdown, reStructuredText, HTML, LaTeX, ConTeXt, Docbook,+ RTF, groff man pages, and S5 HTML slide shows.+ .+ Pandoc extends standard markdown syntax with footnotes,+ embedded LaTeX, definition lists, tables, and other+ features. A compatibility mode is provided for those+ who need a drop-in replacement for Markdown.pl.+ .+ In contrast to existing tools for converting markdown+ to HTML, which use regex substitutions, pandoc has+ a modular design: it consists of a set of readers,+ which parse text in a given format and produce a native+ representation of the document, and a set of writers,+ which convert this native representation into a target+ format. Thus, adding an input or output format requires+ only adding a reader or writer.+Build-Depends: base, parsec, xhtml, mtl, regex-compat+Hs-Source-Dirs: src+Exposed-Modules: Text.Pandoc,+ Text.Pandoc.Blocks,+ Text.Pandoc.Definition,+ Text.Pandoc.CharacterReferences,+ Text.Pandoc.Shared,+ Text.Pandoc.UTF8,+ Text.Pandoc.Readers.HTML,+ Text.Pandoc.Readers.LaTeX,+ Text.Pandoc.Readers.Markdown,+ Text.Pandoc.Readers.RST,+ Text.Pandoc.Writers.DefaultHeaders,+ Text.Pandoc.Writers.Docbook,+ Text.Pandoc.Writers.HTML,+ Text.Pandoc.Writers.LaTeX,+ Text.Pandoc.Writers.ConTeXt,+ Text.Pandoc.Writers.Man,+ Text.Pandoc.Writers.Markdown,+ Text.Pandoc.Writers.RST,+ Text.Pandoc.Writers.RTF,+ Text.Pandoc.Writers.S5+Ghc-Options: -O0++Executable: pandoc+Hs-Source-Dirs: src+Main-Is: Main.hs+Ghc-Options: -O0
+ src/ASCIIMathML.js view
@@ -0,0 +1,945 @@+/*+ASCIIMathML.js+==============+This file contains JavaScript functions to convert ASCII math notation+to Presentation MathML. The conversion is done while the (X)HTML page +loads, and should work with Firefox/Mozilla/Netscape 7+ and Internet +Explorer 6+MathPlayer (http://www.dessci.com/en/products/mathplayer/).+Just add the next line to your (X)HTML page with this file in the same folder:+<script type="text/javascript" src="ASCIIMathML.js"></script>+This is a convenient and inexpensive solution for authoring MathML.++Version 1.4.7 Dec 15, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen+Latest version at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML.js+For changes see http://www.chapman.edu/~jipsen/mathml/asciimathchanges.txt+If you use it on a webpage, please send the URL to jipsen@chapman.edu++Modified July 2006 by John MacFarlane (added CODE to list of contexts+in which replacement does not occur, modified AMisMathMLAvailable+to better identify Safari browser, changed mathcolor to "").++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or (at+your option) any later version.++This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU+General Public License (at http://www.gnu.org/copyleft/gpl.html) +for more details.+*/++var checkForMathML = true; // check if browser can display MathML+var notifyIfNoMathML = true; // display note if no MathML capability+var alertIfNoMathML = false; // show alert box if no MathML capability+var mathcolor = ""; // change it to "" (to inherit) or any other color+var mathfontfamily = "serif"; // change to "" to inherit (works in IE) + // or another family (e.g. "arial")+var displaystyle = true; // puts limits above and below large operators+var showasciiformulaonhover = true; // helps students learn ASCIIMath+var decimalsign = "."; // change to "," if you like, beware of `(1,2)`!+var AMdelimiter1 = "`", AMescape1 = "\\\\`"; // can use other characters+var AMdelimiter2 = "$", AMescape2 = "\\\\\\$", AMdelimiter2regexp = "\\$";+var doubleblankmathdelimiter = false; // if true, x+1 is equal to `x+1`+ // for IE this works only in <!-- -->+//var separatetokens;// has been removed (email me if this is a problem)+var isIE = document.createElementNS==null;++if (document.getElementById==null) + alert("This webpage requires a recent browser such as\+\nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer")++// all further global variables start with "AM"++function AMcreateElementXHTML(t) {+ if (isIE) return document.createElement(t);+ else return document.createElementNS("http://www.w3.org/1999/xhtml",t);+}++function AMnoMathMLNote() {+ var nd = AMcreateElementXHTML("h3");+ nd.setAttribute("align","center")+ nd.appendChild(AMcreateElementXHTML("p"));+ nd.appendChild(document.createTextNode("To view the "));+ var an = AMcreateElementXHTML("a");+ an.appendChild(document.createTextNode("ASCIIMathML"));+ an.setAttribute("href","http://www.chapman.edu/~jipsen/asciimath.html");+ nd.appendChild(an);+ nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+")); + an = AMcreateElementXHTML("a");+ an.appendChild(document.createTextNode("MathPlayer"));+ an.setAttribute("href","http://www.dessci.com/en/products/mathplayer/download.htm");+ nd.appendChild(an);+ nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox"));+ nd.appendChild(AMcreateElementXHTML("p"));+ return nd;+}++function AMisMathMLavailable() {+ var regex = /KHTML/; /* This line and the next two modified by JM for better Safari detection */+ if (navigator.appName.slice(0,8)=="Netscape")+ if (navigator.appVersion.slice(0,1)>="5" && !regex.test(navigator.userAgent)) return null;+ else return AMnoMathMLNote();+ else if (navigator.appName.slice(0,9)=="Microsoft")+ try {+ var ActiveX = new ActiveXObject("MathPlayer.Factory.1");+ return null;+ } catch (e) {+ return AMnoMathMLNote();+ }+ else return AMnoMathMLNote();+}++// character lists for Mozilla/Netscape fonts+var AMcal = [0xEF35,0x212C,0xEF36,0xEF37,0x2130,0x2131,0xEF38,0x210B,0x2110,0xEF39,0xEF3A,0x2112,0x2133,0xEF3B,0xEF3C,0xEF3D,0xEF3E,0x211B,0xEF3F,0xEF40,0xEF41,0xEF42,0xEF43,0xEF44,0xEF45,0xEF46];+var AMfrk = [0xEF5D,0xEF5E,0x212D,0xEF5F,0xEF60,0xEF61,0xEF62,0x210C,0x2111,0xEF63,0xEF64,0xEF65,0xEF66,0xEF67,0xEF68,0xEF69,0xEF6A,0x211C,0xEF6B,0xEF6C,0xEF6D,0xEF6E,0xEF6F,0xEF70,0xEF71,0x2128];+var AMbbb = [0xEF8C,0xEF8D,0x2102,0xEF8E,0xEF8F,0xEF90,0xEF91,0x210D,0xEF92,0xEF93,0xEF94,0xEF95,0xEF96,0x2115,0xEF97,0x2119,0x211A,0x211D,0xEF98,0xEF99,0xEF9A,0xEF9B,0xEF9C,0xEF9D,0xEF9E,0x2124];++var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4, + RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8,+ LEFTRIGHT = 9, TEXT = 10; // token types++var AMsqrt = {input:"sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY},+ AMroot = {input:"root", tag:"mroot", output:"root", tex:null, ttype:BINARY},+ AMfrac = {input:"frac", tag:"mfrac", output:"/", tex:null, ttype:BINARY},+ AMdiv = {input:"/", tag:"mfrac", output:"/", tex:null, ttype:INFIX},+ AMover = {input:"stackrel", tag:"mover", output:"stackrel", tex:null, ttype:BINARY},+ AMsub = {input:"_", tag:"msub", output:"_", tex:null, ttype:INFIX},+ AMsup = {input:"^", tag:"msup", output:"^", tex:null, ttype:INFIX},+ AMtext = {input:"text", tag:"mtext", output:"text", tex:null, ttype:TEXT},+ AMmbox = {input:"mbox", tag:"mtext", output:"mbox", tex:null, ttype:TEXT},+ AMquote = {input:"\"", tag:"mtext", output:"mbox", tex:null, ttype:TEXT};++var AMsymbols = [+//some greek symbols+{input:"alpha", tag:"mi", output:"\u03B1", tex:null, ttype:CONST},+{input:"beta", tag:"mi", output:"\u03B2", tex:null, ttype:CONST},+{input:"chi", tag:"mi", output:"\u03C7", tex:null, ttype:CONST},+{input:"delta", tag:"mi", output:"\u03B4", tex:null, ttype:CONST},+{input:"Delta", tag:"mo", output:"\u0394", tex:null, ttype:CONST},+{input:"epsi", tag:"mi", output:"\u03B5", tex:"epsilon", ttype:CONST},+{input:"varepsilon", tag:"mi", output:"\u025B", tex:null, ttype:CONST},+{input:"eta", tag:"mi", output:"\u03B7", tex:null, ttype:CONST},+{input:"gamma", tag:"mi", output:"\u03B3", tex:null, ttype:CONST},+{input:"Gamma", tag:"mo", output:"\u0393", tex:null, ttype:CONST},+{input:"iota", tag:"mi", output:"\u03B9", tex:null, ttype:CONST},+{input:"kappa", tag:"mi", output:"\u03BA", tex:null, ttype:CONST},+{input:"lambda", tag:"mi", output:"\u03BB", tex:null, ttype:CONST},+{input:"Lambda", tag:"mo", output:"\u039B", tex:null, ttype:CONST},+{input:"mu", tag:"mi", output:"\u03BC", tex:null, ttype:CONST},+{input:"nu", tag:"mi", output:"\u03BD", tex:null, ttype:CONST},+{input:"omega", tag:"mi", output:"\u03C9", tex:null, ttype:CONST},+{input:"Omega", tag:"mo", output:"\u03A9", tex:null, ttype:CONST},+{input:"phi", tag:"mi", output:"\u03C6", tex:null, ttype:CONST},+{input:"varphi", tag:"mi", output:"\u03D5", tex:null, ttype:CONST},+{input:"Phi", tag:"mo", output:"\u03A6", tex:null, ttype:CONST},+{input:"pi", tag:"mi", output:"\u03C0", tex:null, ttype:CONST},+{input:"Pi", tag:"mo", output:"\u03A0", tex:null, ttype:CONST},+{input:"psi", tag:"mi", output:"\u03C8", tex:null, ttype:CONST},+{input:"Psi", tag:"mi", output:"\u03A8", tex:null, ttype:CONST},+{input:"rho", tag:"mi", output:"\u03C1", tex:null, ttype:CONST},+{input:"sigma", tag:"mi", output:"\u03C3", tex:null, ttype:CONST},+{input:"Sigma", tag:"mo", output:"\u03A3", tex:null, ttype:CONST},+{input:"tau", tag:"mi", output:"\u03C4", tex:null, ttype:CONST},+{input:"theta", tag:"mi", output:"\u03B8", tex:null, ttype:CONST},+{input:"vartheta", tag:"mi", output:"\u03D1", tex:null, ttype:CONST},+{input:"Theta", tag:"mo", output:"\u0398", tex:null, ttype:CONST},+{input:"upsilon", tag:"mi", output:"\u03C5", tex:null, ttype:CONST},+{input:"xi", tag:"mi", output:"\u03BE", tex:null, ttype:CONST},+{input:"Xi", tag:"mo", output:"\u039E", tex:null, ttype:CONST},+{input:"zeta", tag:"mi", output:"\u03B6", tex:null, ttype:CONST},++//binary operation symbols+{input:"*", tag:"mo", output:"\u22C5", tex:"cdot", ttype:CONST},+{input:"**", tag:"mo", output:"\u22C6", tex:"star", ttype:CONST},+{input:"//", tag:"mo", output:"/", tex:null, ttype:CONST},+{input:"\\\\", tag:"mo", output:"\\", tex:"backslash", ttype:CONST},+{input:"setminus", tag:"mo", output:"\\", tex:null, ttype:CONST},+{input:"xx", tag:"mo", output:"\u00D7", tex:"times", ttype:CONST},+{input:"-:", tag:"mo", output:"\u00F7", tex:"divide", ttype:CONST},+{input:"@", tag:"mo", output:"\u2218", tex:"circ", ttype:CONST},+{input:"o+", tag:"mo", output:"\u2295", tex:"oplus", ttype:CONST},+{input:"ox", tag:"mo", output:"\u2297", tex:"otimes", ttype:CONST},+{input:"o.", tag:"mo", output:"\u2299", tex:"odot", ttype:CONST},+{input:"sum", tag:"mo", output:"\u2211", tex:null, ttype:UNDEROVER},+{input:"prod", tag:"mo", output:"\u220F", tex:null, ttype:UNDEROVER},+{input:"^^", tag:"mo", output:"\u2227", tex:"wedge", ttype:CONST},+{input:"^^^", tag:"mo", output:"\u22C0", tex:"bigwedge", ttype:UNDEROVER},+{input:"vv", tag:"mo", output:"\u2228", tex:"vee", ttype:CONST},+{input:"vvv", tag:"mo", output:"\u22C1", tex:"bigvee", ttype:UNDEROVER},+{input:"nn", tag:"mo", output:"\u2229", tex:"cap", ttype:CONST},+{input:"nnn", tag:"mo", output:"\u22C2", tex:"bigcap", ttype:UNDEROVER},+{input:"uu", tag:"mo", output:"\u222A", tex:"cup", ttype:CONST},+{input:"uuu", tag:"mo", output:"\u22C3", tex:"bigcup", ttype:UNDEROVER},++//binary relation symbols+{input:"!=", tag:"mo", output:"\u2260", tex:"ne", ttype:CONST},+{input:":=", tag:"mo", output:":=", tex:null, ttype:CONST},+{input:"lt", tag:"mo", output:"<", tex:null, ttype:CONST},+{input:"<=", tag:"mo", output:"\u2264", tex:"le", ttype:CONST},+{input:"lt=", tag:"mo", output:"\u2264", tex:"leq", ttype:CONST},+{input:">=", tag:"mo", output:"\u2265", tex:"ge", ttype:CONST},+{input:"geq", tag:"mo", output:"\u2265", tex:null, ttype:CONST},+{input:"-<", tag:"mo", output:"\u227A", tex:"prec", ttype:CONST},+{input:"-lt", tag:"mo", output:"\u227A", tex:null, ttype:CONST},+{input:">-", tag:"mo", output:"\u227B", tex:"succ", ttype:CONST},+{input:"-<=", tag:"mo", output:"\u2AAF", tex:"preceq", ttype:CONST},+{input:">-=", tag:"mo", output:"\u2AB0", tex:"succeq", ttype:CONST},+{input:"in", tag:"mo", output:"\u2208", tex:null, ttype:CONST},+{input:"!in", tag:"mo", output:"\u2209", tex:"notin", ttype:CONST},+{input:"sub", tag:"mo", output:"\u2282", tex:"subset", ttype:CONST},+{input:"sup", tag:"mo", output:"\u2283", tex:"supset", ttype:CONST},+{input:"sube", tag:"mo", output:"\u2286", tex:"subseteq", ttype:CONST},+{input:"supe", tag:"mo", output:"\u2287", tex:"supseteq", ttype:CONST},+{input:"-=", tag:"mo", output:"\u2261", tex:"equiv", ttype:CONST},+{input:"~=", tag:"mo", output:"\u2245", tex:"cong", ttype:CONST},+{input:"~~", tag:"mo", output:"\u2248", tex:"approx", ttype:CONST},+{input:"prop", tag:"mo", output:"\u221D", tex:"propto", ttype:CONST},++//logical symbols+{input:"and", tag:"mtext", output:"and", tex:null, ttype:SPACE},+{input:"or", tag:"mtext", output:"or", tex:null, ttype:SPACE},+{input:"not", tag:"mo", output:"\u00AC", tex:"neg", ttype:CONST},+{input:"=>", tag:"mo", output:"\u21D2", tex:"implies", ttype:CONST},+{input:"if", tag:"mo", output:"if", tex:null, ttype:SPACE},+{input:"<=>", tag:"mo", output:"\u21D4", tex:"iff", ttype:CONST},+{input:"AA", tag:"mo", output:"\u2200", tex:"forall", ttype:CONST},+{input:"EE", tag:"mo", output:"\u2203", tex:"exists", ttype:CONST},+{input:"_|_", tag:"mo", output:"\u22A5", tex:"bot", ttype:CONST},+{input:"TT", tag:"mo", output:"\u22A4", tex:"top", ttype:CONST},+{input:"|--", tag:"mo", output:"\u22A2", tex:"vdash", ttype:CONST},+{input:"|==", tag:"mo", output:"\u22A8", tex:"models", ttype:CONST},++//grouping brackets+{input:"(", tag:"mo", output:"(", tex:null, ttype:LEFTBRACKET},+{input:")", tag:"mo", output:")", tex:null, ttype:RIGHTBRACKET},+{input:"[", tag:"mo", output:"[", tex:null, ttype:LEFTBRACKET},+{input:"]", tag:"mo", output:"]", tex:null, ttype:RIGHTBRACKET},+{input:"{", tag:"mo", output:"{", tex:null, ttype:LEFTBRACKET},+{input:"}", tag:"mo", output:"}", tex:null, ttype:RIGHTBRACKET},+{input:"|", tag:"mo", output:"|", tex:null, ttype:LEFTRIGHT},+//{input:"||", tag:"mo", output:"||", tex:null, ttype:LEFTRIGHT},+{input:"(:", tag:"mo", output:"\u2329", tex:"langle", ttype:LEFTBRACKET},+{input:":)", tag:"mo", output:"\u232A", tex:"rangle", ttype:RIGHTBRACKET},+{input:"<<", tag:"mo", output:"\u2329", tex:null, ttype:LEFTBRACKET},+{input:">>", tag:"mo", output:"\u232A", tex:null, ttype:RIGHTBRACKET},+{input:"{:", tag:"mo", output:"{:", tex:null, ttype:LEFTBRACKET, invisible:true},+{input:":}", tag:"mo", output:":}", tex:null, ttype:RIGHTBRACKET, invisible:true},++//miscellaneous symbols+{input:"int", tag:"mo", output:"\u222B", tex:null, ttype:CONST},+{input:"dx", tag:"mi", output:"{:d x:}", tex:null, ttype:DEFINITION},+{input:"dy", tag:"mi", output:"{:d y:}", tex:null, ttype:DEFINITION},+{input:"dz", tag:"mi", output:"{:d z:}", tex:null, ttype:DEFINITION},+{input:"dt", tag:"mi", output:"{:d t:}", tex:null, ttype:DEFINITION},+{input:"oint", tag:"mo", output:"\u222E", tex:null, ttype:CONST},+{input:"del", tag:"mo", output:"\u2202", tex:"partial", ttype:CONST},+{input:"grad", tag:"mo", output:"\u2207", tex:"nabla", ttype:CONST},+{input:"+-", tag:"mo", output:"\u00B1", tex:"pm", ttype:CONST},+{input:"O/", tag:"mo", output:"\u2205", tex:"emptyset", ttype:CONST},+{input:"oo", tag:"mo", output:"\u221E", tex:"infty", ttype:CONST},+{input:"aleph", tag:"mo", output:"\u2135", tex:null, ttype:CONST},+{input:"...", tag:"mo", output:"...", tex:"ldots", ttype:CONST},+{input:":.", tag:"mo", output:"\u2234", tex:"therefore", ttype:CONST},+{input:"/_", tag:"mo", output:"\u2220", tex:"angle", ttype:CONST},+{input:"\\ ", tag:"mo", output:"\u00A0", tex:null, ttype:CONST},+{input:"quad", tag:"mo", output:"\u00A0\u00A0", tex:null, ttype:CONST},+{input:"qquad", tag:"mo", output:"\u00A0\u00A0\u00A0\u00A0", tex:null, ttype:CONST},+{input:"cdots", tag:"mo", output:"\u22EF", tex:null, ttype:CONST},+{input:"vdots", tag:"mo", output:"\u22EE", tex:null, ttype:CONST},+{input:"ddots", tag:"mo", output:"\u22F1", tex:null, ttype:CONST},+{input:"diamond", tag:"mo", output:"\u22C4", tex:null, ttype:CONST},+{input:"square", tag:"mo", output:"\u25A1", tex:null, ttype:CONST},+{input:"|__", tag:"mo", output:"\u230A", tex:"lfloor", ttype:CONST},+{input:"__|", tag:"mo", output:"\u230B", tex:"rfloor", ttype:CONST},+{input:"|~", tag:"mo", output:"\u2308", tex:"lceiling", ttype:CONST},+{input:"~|", tag:"mo", output:"\u2309", tex:"rceiling", ttype:CONST},+{input:"CC", tag:"mo", output:"\u2102", tex:null, ttype:CONST},+{input:"NN", tag:"mo", output:"\u2115", tex:null, ttype:CONST},+{input:"QQ", tag:"mo", output:"\u211A", tex:null, ttype:CONST},+{input:"RR", tag:"mo", output:"\u211D", tex:null, ttype:CONST},+{input:"ZZ", tag:"mo", output:"\u2124", tex:null, ttype:CONST},+{input:"f", tag:"mi", output:"f", tex:null, ttype:UNARY, func:true},+{input:"g", tag:"mi", output:"g", tex:null, ttype:UNARY, func:true},++//standard functions+{input:"lim", tag:"mo", output:"lim", tex:null, ttype:UNDEROVER},+{input:"Lim", tag:"mo", output:"Lim", tex:null, ttype:UNDEROVER},+{input:"sin", tag:"mo", output:"sin", tex:null, ttype:UNARY, func:true},+{input:"cos", tag:"mo", output:"cos", tex:null, ttype:UNARY, func:true},+{input:"tan", tag:"mo", output:"tan", tex:null, ttype:UNARY, func:true},+{input:"sinh", tag:"mo", output:"sinh", tex:null, ttype:UNARY, func:true},+{input:"cosh", tag:"mo", output:"cosh", tex:null, ttype:UNARY, func:true},+{input:"tanh", tag:"mo", output:"tanh", tex:null, ttype:UNARY, func:true},+{input:"cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true},+{input:"sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true},+{input:"csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true},+{input:"log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true},+{input:"ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true},+{input:"det", tag:"mo", output:"det", tex:null, ttype:UNARY, func:true},+{input:"dim", tag:"mo", output:"dim", tex:null, ttype:CONST},+{input:"mod", tag:"mo", output:"mod", tex:null, ttype:CONST},+{input:"gcd", tag:"mo", output:"gcd", tex:null, ttype:UNARY, func:true},+{input:"lcm", tag:"mo", output:"lcm", tex:null, ttype:UNARY, func:true},+{input:"lub", tag:"mo", output:"lub", tex:null, ttype:CONST},+{input:"glb", tag:"mo", output:"glb", tex:null, ttype:CONST},+{input:"min", tag:"mo", output:"min", tex:null, ttype:UNDEROVER},+{input:"max", tag:"mo", output:"max", tex:null, ttype:UNDEROVER},++//arrows+{input:"uarr", tag:"mo", output:"\u2191", tex:"uparrow", ttype:CONST},+{input:"darr", tag:"mo", output:"\u2193", tex:"downarrow", ttype:CONST},+{input:"rarr", tag:"mo", output:"\u2192", tex:"rightarrow", ttype:CONST},+{input:"->", tag:"mo", output:"\u2192", tex:"to", ttype:CONST},+{input:"|->", tag:"mo", output:"\u21A6", tex:"mapsto", ttype:CONST},+{input:"larr", tag:"mo", output:"\u2190", tex:"leftarrow", ttype:CONST},+{input:"harr", tag:"mo", output:"\u2194", tex:"leftrightarrow", ttype:CONST},+{input:"rArr", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST},+{input:"lArr", tag:"mo", output:"\u21D0", tex:"Leftarrow", ttype:CONST},+{input:"hArr", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST},++//commands with argument+AMsqrt, AMroot, AMfrac, AMdiv, AMover, AMsub, AMsup,+{input:"hat", tag:"mover", output:"\u005E", tex:null, ttype:UNARY, acc:true},+{input:"bar", tag:"mover", output:"\u00AF", tex:"overline", ttype:UNARY, acc:true},+{input:"vec", tag:"mover", output:"\u2192", tex:null, ttype:UNARY, acc:true},+{input:"dot", tag:"mover", output:".", tex:null, ttype:UNARY, acc:true},+{input:"ddot", tag:"mover", output:"..", tex:null, ttype:UNARY, acc:true},+{input:"ul", tag:"munder", output:"\u0332", tex:"underline", ttype:UNARY, acc:true},+AMtext, AMmbox, AMquote,+{input:"bb", tag:"mstyle", atname:"fontweight", atval:"bold", output:"bb", tex:null, ttype:UNARY},+{input:"mathbf", tag:"mstyle", atname:"fontweight", atval:"bold", output:"mathbf", tex:null, ttype:UNARY},+{input:"sf", tag:"mstyle", atname:"fontfamily", atval:"sans-serif", output:"sf", tex:null, ttype:UNARY},+{input:"mathsf", tag:"mstyle", atname:"fontfamily", atval:"sans-serif", output:"mathsf", tex:null, ttype:UNARY},+{input:"bbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"bbb", tex:null, ttype:UNARY, codes:AMbbb},+{input:"mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"mathbb", tex:null, ttype:UNARY, codes:AMbbb},+{input:"cc", tag:"mstyle", atname:"mathvariant", atval:"script", output:"cc", tex:null, ttype:UNARY, codes:AMcal},+{input:"mathcal", tag:"mstyle", atname:"mathvariant", atval:"script", output:"mathcal", tex:null, ttype:UNARY, codes:AMcal},+{input:"tt", tag:"mstyle", atname:"fontfamily", atval:"monospace", output:"tt", tex:null, ttype:UNARY},+{input:"mathtt", tag:"mstyle", atname:"fontfamily", atval:"monospace", output:"mathtt", tex:null, ttype:UNARY},+{input:"fr", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"fr", tex:null, ttype:UNARY, codes:AMfrk},+{input:"mathfrak", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"mathfrak", tex:null, ttype:UNARY, codes:AMfrk}+];++function compareNames(s1,s2) {+ if (s1.input > s2.input) return 1+ else return -1;+}++var AMnames = []; //list of input symbols++function AMinitSymbols() {+ var texsymbols = [], i;+ for (i=0; i<AMsymbols.length; i++)+ if (AMsymbols[i].tex) + texsymbols[texsymbols.length] = {input:AMsymbols[i].tex, + tag:AMsymbols[i].tag, output:AMsymbols[i].output, ttype:AMsymbols[i].ttype};+ AMsymbols = AMsymbols.concat(texsymbols);+ AMsymbols.sort(compareNames);+ for (i=0; i<AMsymbols.length; i++) AMnames[i] = AMsymbols[i].input;+}++var AMmathml = "http://www.w3.org/1998/Math/MathML";++function AMcreateElementMathML(t) {+ if (isIE) return document.createElement("m:"+t);+ else return document.createElementNS(AMmathml,t);+}++function AMcreateMmlNode(t,frag) {+// var node = AMcreateElementMathML(name);+ if (isIE) var node = document.createElement("m:"+t);+ else var node = document.createElementNS(AMmathml,t);+ node.appendChild(frag);+ return node;+}++function newcommand(oldstr,newstr) {+ AMsymbols = AMsymbols.concat([{input:oldstr, tag:"mo", output:newstr, + tex:null, ttype:DEFINITION}]);+}++function AMremoveCharsAndBlanks(str,n) {+//remove n characters and any following blanks+ var st;+ if (str.charAt(n)=="\\" && str.charAt(n+1)!="\\" && str.charAt(n+1)!=" ") + st = str.slice(n+1);+ else st = str.slice(n);+ for (var i=0; i<st.length && st.charCodeAt(i)<=32; i=i+1);+ return st.slice(i);+}++function AMposition(arr, str, n) { +// return position >=n where str appears or would be inserted+// assumes arr is sorted+ if (n==0) {+ var h,m;+ n = -1;+ h = arr.length;+ while (n+1<h) {+ m = (n+h) >> 1;+ if (arr[m]<str) n = m; else h = m;+ }+ return h;+ } else+ for (var i=n; i<arr.length && arr[i]<str; i++);+ return i; // i=arr.length || arr[i]>=str+}++function AMgetSymbol(str) {+//return maximal initial substring of str that appears in names+//return null if there is none+ var k = 0; //new pos+ var j = 0; //old pos+ var mk; //match pos+ var st;+ var tagst;+ var match = "";+ var more = true;+ for (var i=1; i<=str.length && more; i++) {+ st = str.slice(0,i); //initial substring of length i+ j = k;+ k = AMposition(AMnames, st, j);+ if (k<AMnames.length && str.slice(0,AMnames[k].length)==AMnames[k]){+ match = AMnames[k];+ mk = k;+ i = match.length;+ }+ more = k<AMnames.length && str.slice(0,AMnames[k].length)>=AMnames[k];+ }+ AMpreviousSymbol=AMcurrentSymbol;+ if (match!=""){+ AMcurrentSymbol=AMsymbols[mk].ttype;+ return AMsymbols[mk]; + }+// if str[0] is a digit or - return maxsubstring of digits.digits+ AMcurrentSymbol=CONST;+ k = 1;+ st = str.slice(0,1);+ var integ = true;+ while ("0"<=st && st<="9" && k<=str.length) {+ st = str.slice(k,k+1);+ k++;+ }+ if (st == decimalsign) {+ st = str.slice(k,k+1);+ if ("0"<=st && st<="9") {+ integ = false;+ k++;+ while ("0"<=st && st<="9" && k<=str.length) {+ st = str.slice(k,k+1);+ k++;+ }+ }+ }+ if ((integ && k>1) || k>2) {+ st = str.slice(0,k-1);+ tagst = "mn";+ } else {+ k = 2;+ st = str.slice(0,1); //take 1 character+ tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi");+ }+ if (st=="-" && AMpreviousSymbol==INFIX) {+ AMcurrentSymbol = INFIX; //trick "/" into recognizing "-" on second parse+ return {input:st, tag:tagst, output:st, ttype:UNARY, func:true};+ }+ return {input:st, tag:tagst, output:st, ttype:CONST};+}++function AMremoveBrackets(node) {+ var st;+ if (node.nodeName=="mrow") {+ st = node.firstChild.firstChild.nodeValue;+ if (st=="(" || st=="[" || st=="{") node.removeChild(node.firstChild);+ }+ if (node.nodeName=="mrow") {+ st = node.lastChild.firstChild.nodeValue;+ if (st==")" || st=="]" || st=="}") node.removeChild(node.lastChild);+ }+}++/*Parsing ASCII math expressions with the following grammar+v ::= [A-Za-z] | greek letters | numbers | other constant symbols+u ::= sqrt | text | bb | other unary symbols for font commands+b ::= frac | root | stackrel binary symbols+l ::= ( | [ | { | (: | {: left brackets+r ::= ) | ] | } | :) | :} right brackets+S ::= v | lEr | uS | bSS Simple expression+I ::= S_S | S^S | S_S^S | S Intermediate expression+E ::= IE | I/I Expression+Each terminal symbol is translated into a corresponding mathml node.*/++var AMnestingDepth,AMpreviousSymbol,AMcurrentSymbol;++function AMparseSexpr(str) { //parses str and returns [node,tailstr]+ var symbol, node, result, i, st,// rightvert = false,+ newFrag = document.createDocumentFragment();+ str = AMremoveCharsAndBlanks(str,0);+ symbol = AMgetSymbol(str); //either a token or a bracket or empty+ if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) {+ return [null,str];+ }+ if (symbol.ttype == DEFINITION) {+ str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length); + symbol = AMgetSymbol(str);+ }+ switch (symbol.ttype) {+ case UNDEROVER:+ case CONST:+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [AMcreateMmlNode(symbol.tag, //its a constant+ document.createTextNode(symbol.output)),str];+ case LEFTBRACKET: //read (expr+)+ AMnestingDepth++;+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseExpr(str,true);+ AMnestingDepth--;+ if (typeof symbol.invisible == "boolean" && symbol.invisible) + node = AMcreateMmlNode("mrow",result[0]);+ else {+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));+ node = AMcreateMmlNode("mrow",node);+ node.appendChild(result[0]);+ }+ return [node,result[1]];+ case TEXT:+ if (symbol!=AMquote) str = AMremoveCharsAndBlanks(str,symbol.input.length);+ if (str.charAt(0)=="{") i=str.indexOf("}");+ else if (str.charAt(0)=="(") i=str.indexOf(")");+ else if (str.charAt(0)=="[") i=str.indexOf("]");+ else if (symbol==AMquote) i=str.slice(1).indexOf("\"")+1;+ else i = 0;+ if (i==-1) i = str.length;+ st = str.slice(1,i);+ if (st.charAt(0) == " ") {+ node = AMcreateElementMathML("mspace");+ node.setAttribute("width","1ex");+ newFrag.appendChild(node);+ }+ newFrag.appendChild(+ AMcreateMmlNode(symbol.tag,document.createTextNode(st)));+ if (st.charAt(st.length-1) == " ") {+ node = AMcreateElementMathML("mspace");+ node.setAttribute("width","1ex");+ newFrag.appendChild(node);+ }+ str = AMremoveCharsAndBlanks(str,i+1);+ return [AMcreateMmlNode("mrow",newFrag),str];+ case UNARY:+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseSexpr(str);+ if (result[0]==null) return [AMcreateMmlNode(symbol.tag,+ document.createTextNode(symbol.output)),str];+ if (typeof symbol.func == "boolean" && symbol.func) { // functions hack+ st = str.charAt(0);+ if (st=="^" || st=="_" || st=="/" || st=="|" || st==",") {+ return [AMcreateMmlNode(symbol.tag,+ document.createTextNode(symbol.output)),str];+ } else {+ node = AMcreateMmlNode("mrow",+ AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));+ node.appendChild(result[0]);+ return [node,result[1]];+ }+ }+ AMremoveBrackets(result[0]);+ if (symbol.input == "sqrt") { // sqrt+ return [AMcreateMmlNode(symbol.tag,result[0]),result[1]];+ } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent+ node = AMcreateMmlNode(symbol.tag,result[0]);+ node.appendChild(AMcreateMmlNode("mo",document.createTextNode(symbol.output)));+ return [node,result[1]];+ } else { // font change command+ if (!isIE && typeof symbol.codes != "undefined") {+ for (i=0; i<result[0].childNodes.length; i++)+ if (result[0].childNodes[i].nodeName=="mi" || result[0].nodeName=="mi") {+ st = (result[0].nodeName=="mi"?result[0].firstChild.nodeValue:+ result[0].childNodes[i].firstChild.nodeValue);+ var newst = [];+ for (var j=0; j<st.length; j++)+ if (st.charCodeAt(j)>64 && st.charCodeAt(j)<91) newst = newst ++ String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]);+ else newst = newst + st.charAt(j);+ if (result[0].nodeName=="mi")+ result[0]=AMcreateElementMathML("mo").+ appendChild(document.createTextNode(newst));+ else result[0].replaceChild(AMcreateElementMathML("mo").+ appendChild(document.createTextNode(newst)),result[0].childNodes[i]);+ }+ }+ node = AMcreateMmlNode(symbol.tag,result[0]);+ node.setAttribute(symbol.atname,symbol.atval);+ return [node,result[1]];+ }+ case BINARY:+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseSexpr(str);+ if (result[0]==null) return [AMcreateMmlNode("mo",+ document.createTextNode(symbol.input)),str];+ AMremoveBrackets(result[0]);+ var result2 = AMparseSexpr(result[1]);+ if (result2[0]==null) return [AMcreateMmlNode("mo",+ document.createTextNode(symbol.input)),str];+ AMremoveBrackets(result2[0]);+ if (symbol.input=="root" || symbol.input=="stackrel") + newFrag.appendChild(result2[0]);+ newFrag.appendChild(result[0]);+ if (symbol.input=="frac") newFrag.appendChild(result2[0]);+ return [AMcreateMmlNode(symbol.tag,newFrag),result2[1]];+ case INFIX:+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [AMcreateMmlNode("mo",document.createTextNode(symbol.output)),str];+ case SPACE:+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + node = AMcreateElementMathML("mspace");+ node.setAttribute("width","1ex");+ newFrag.appendChild(node);+ newFrag.appendChild(+ AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));+ node = AMcreateElementMathML("mspace");+ node.setAttribute("width","1ex");+ newFrag.appendChild(node);+ return [AMcreateMmlNode("mrow",newFrag),str];+ case LEFTRIGHT:+// if (rightvert) return [null,str]; else rightvert = true;+ AMnestingDepth++;+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseExpr(str,false);+ AMnestingDepth--;+ var st = "";+ if (result[0].lastChild!=null)+ st = result[0].lastChild.firstChild.nodeValue;+ if (st == "|") { // its an absolute value subterm+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));+ node = AMcreateMmlNode("mrow",node);+ node.appendChild(result[0]);+ return [node,result[1]];+ } else { // the "|" is a \mid+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));+ node = AMcreateMmlNode("mrow",node);+ return [node,str];+ }+ default:+//alert("default");+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [AMcreateMmlNode(symbol.tag, //its a constant+ document.createTextNode(symbol.output)),str];+ }+}++function AMparseIexpr(str) {+ var symbol, sym1, sym2, node, result, underover;+ str = AMremoveCharsAndBlanks(str,0);+ sym1 = AMgetSymbol(str);+ result = AMparseSexpr(str);+ node = result[0];+ str = result[1];+ symbol = AMgetSymbol(str);+ if (symbol.ttype == INFIX && symbol.input != "/") {+ str = AMremoveCharsAndBlanks(str,symbol.input.length);+// if (symbol.input == "/") result = AMparseIexpr(str); else ...+ result = AMparseSexpr(str);+ if (result[0] == null) // show box in place of missing argument+ result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1"));+ else AMremoveBrackets(result[0]);+ str = result[1];+// if (symbol.input == "/") AMremoveBrackets(node);+ if (symbol.input == "_") {+ sym2 = AMgetSymbol(str);+ underover = (sym1.ttype == UNDEROVER);+ if (sym2.input == "^") {+ str = AMremoveCharsAndBlanks(str,sym2.input.length);+ var res2 = AMparseSexpr(str);+ AMremoveBrackets(res2[0]);+ str = res2[1];+ node = AMcreateMmlNode((underover?"munderover":"msubsup"),node);+ node.appendChild(result[0]);+ node.appendChild(res2[0]);+ node = AMcreateMmlNode("mrow",node); // so sum does not stretch+ } else {+ node = AMcreateMmlNode((underover?"munder":"msub"),node);+ node.appendChild(result[0]);+ }+ } else {+ node = AMcreateMmlNode(symbol.tag,node);+ node.appendChild(result[0]);+ }+ }+ return [node,str];+}++function AMparseExpr(str,rightbracket) {+ var symbol, node, result, i, nodeList = [],+ newFrag = document.createDocumentFragment();+ do {+ str = AMremoveCharsAndBlanks(str,0);+ result = AMparseIexpr(str);+ node = result[0];+ str = result[1];+ symbol = AMgetSymbol(str);+ if (symbol.ttype == INFIX && symbol.input == "/") {+ str = AMremoveCharsAndBlanks(str,symbol.input.length);+ result = AMparseIexpr(str);+ if (result[0] == null) // show box in place of missing argument+ result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1"));+ else AMremoveBrackets(result[0]);+ str = result[1];+ AMremoveBrackets(node);+ node = AMcreateMmlNode(symbol.tag,node);+ node.appendChild(result[0]);+ newFrag.appendChild(node);+ symbol = AMgetSymbol(str);+ } + else if (node!=undefined) newFrag.appendChild(node);+ } while ((symbol.ttype != RIGHTBRACKET && + (symbol.ttype != LEFTRIGHT || rightbracket)+ || AMnestingDepth == 0) && symbol!=null && symbol.output!="");+ if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) {+// if (AMnestingDepth > 0) AMnestingDepth--;+ var len = newFrag.childNodes.length;+ if (len>0 && newFrag.childNodes[len-1].nodeName == "mrow" && len>1 &&+ newFrag.childNodes[len-2].nodeName == "mo" &&+ newFrag.childNodes[len-2].firstChild.nodeValue == ",") { //matrix+ var right = newFrag.childNodes[len-1].lastChild.firstChild.nodeValue;+ if (right==")" || right=="]") {+ var left = newFrag.childNodes[len-1].firstChild.firstChild.nodeValue;+ if (left=="(" && right==")" && symbol.output != "}" || + left=="[" && right=="]") {+ var pos = []; // positions of commas+ var matrix = true;+ var m = newFrag.childNodes.length;+ for (i=0; matrix && i<m; i=i+2) {+ pos[i] = [];+ node = newFrag.childNodes[i];+ if (matrix) matrix = node.nodeName=="mrow" && + (i==m-1 || node.nextSibling.nodeName=="mo" && + node.nextSibling.firstChild.nodeValue==",")&&+ node.firstChild.firstChild.nodeValue==left &&+ node.lastChild.firstChild.nodeValue==right;+ if (matrix) + for (var j=0; j<node.childNodes.length; j++)+ if (node.childNodes[j].firstChild.nodeValue==",")+ pos[i][pos[i].length]=j;+ if (matrix && i>1) matrix = pos[i].length == pos[i-2].length;+ }+ if (matrix) {+ var row, frag, n, k, table = document.createDocumentFragment();+ for (i=0; i<m; i=i+2) {+ row = document.createDocumentFragment();+ frag = document.createDocumentFragment();+ node = newFrag.firstChild; // <mrow>(-,-,...,-,-)</mrow>+ n = node.childNodes.length;+ k = 0;+ node.removeChild(node.firstChild); //remove (+ for (j=1; j<n-1; j++) {+ if (typeof pos[i][k] != "undefined" && j==pos[i][k]){+ node.removeChild(node.firstChild); //remove ,+ row.appendChild(AMcreateMmlNode("mtd",frag));+ k++;+ } else frag.appendChild(node.firstChild);+ }+ row.appendChild(AMcreateMmlNode("mtd",frag));+ if (newFrag.childNodes.length>2) {+ newFrag.removeChild(newFrag.firstChild); //remove <mrow>)</mrow>+ newFrag.removeChild(newFrag.firstChild); //remove <mo>,</mo>+ }+ table.appendChild(AMcreateMmlNode("mtr",row));+ }+ node = AMcreateMmlNode("mtable",table);+ if (typeof symbol.invisible == "boolean" && symbol.invisible) node.setAttribute("columnalign","left");+ newFrag.replaceChild(node,newFrag.firstChild);+ }+ }+ }+ }+ str = AMremoveCharsAndBlanks(str,symbol.input.length);+ if (typeof symbol.invisible != "boolean" || !symbol.invisible) {+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));+ newFrag.appendChild(node);+ }+ }+ return [newFrag,str];+}++function AMparseMath(str) {+ var result, node = AMcreateElementMathML("mstyle");+ if (mathcolor != "") node.setAttribute("mathcolor",mathcolor);+ if (displaystyle) node.setAttribute("displaystyle","true");+ if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily);+ AMnestingDepth = 0;+ node.appendChild(AMparseExpr(str.replace(/^\s+/g,""),false)[0]);+ node = AMcreateMmlNode("math",node);+ if (showasciiformulaonhover) //fixed by djhsu so newline+ node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko+ if (mathfontfamily != "" && (isIE || mathfontfamily != "serif")) {+ var fnode = AMcreateElementXHTML("font");+ fnode.setAttribute("face",mathfontfamily);+ fnode.appendChild(node);+ return fnode;+ }+ return node;+}++function AMstrarr2docFrag(arr, linebreaks) {+ var newFrag=document.createDocumentFragment();+ var expr = false;+ for (var i=0; i<arr.length; i++) {+ if (expr) newFrag.appendChild(AMparseMath(arr[i]));+ else {+ var arri = (linebreaks ? arr[i].split("\n\n") : [arr[i]]);+ newFrag.appendChild(AMcreateElementXHTML("span").+ appendChild(document.createTextNode(arri[0])));+ for (var j=1; j<arri.length; j++) {+ newFrag.appendChild(AMcreateElementXHTML("p"));+ newFrag.appendChild(AMcreateElementXHTML("span").+ appendChild(document.createTextNode(arri[j])));+ }+ }+ expr = !expr;+ }+ return newFrag;+}++function AMprocessNodeR(n, linebreaks) {+ var mtch, str, arr, frg, i;+ if (n.childNodes.length == 0) {+ if ((n.nodeType!=8 || linebreaks) &&+ n.parentNode.nodeName!="form" && n.parentNode.nodeName!="FORM" &&+ n.parentNode.nodeName!="textarea" && n.parentNode.nodeName!="TEXTAREA" &&+ n.parentNode.nodeName!="code" && n.parentNode.nodeName!="CODE" && /* added by JM */+ n.parentNode.nodeName!="pre" && n.parentNode.nodeName!="PRE") {+ str = n.nodeValue;+ if (!(str == null)) {+ str = str.replace(/\r\n\r\n/g,"\n\n");+ if (doubleblankmathdelimiter) {+ str = str.replace(/\x20\x20\./g," "+AMdelimiter1+".");+ str = str.replace(/\x20\x20,/g," "+AMdelimiter1+",");+ str = str.replace(/\x20\x20/g," "+AMdelimiter1+" ");+ }+ str = str.replace(/\x20+/g," ");+ str = str.replace(/\s*\r\n/g," ");+ mtch = false;+ str = str.replace(new RegExp(AMescape2, "g"),+ function(st){mtch=true;return "AMescape2"});+ str = str.replace(new RegExp(AMescape1, "g"),+ function(st){mtch=true;return "AMescape1"});+ str = str.replace(new RegExp(AMdelimiter2regexp, "g"),AMdelimiter1);+ arr = str.split(AMdelimiter1);+ for (i=0; i<arr.length; i++)+ arr[i]=arr[i].replace(/AMescape2/g,AMdelimiter2).+ replace(/AMescape1/g,AMdelimiter1);+ if (arr.length>1 || mtch) {+ if (checkForMathML) {+ checkForMathML = false;+ var nd = AMisMathMLavailable();+ AMnoMathML = nd != null;+ if (AMnoMathML && notifyIfNoMathML) + if (alertIfNoMathML)+ alert("To view the ASCIIMathML notation use Internet Explorer 6 +\nMathPlayer (free from www.dessci.com)\n\+ or Firefox/Mozilla/Netscape");+ else AMbody.insertBefore(nd,AMbody.childNodes[0]);+ }+ if (!AMnoMathML) {+ frg = AMstrarr2docFrag(arr,n.nodeType==8);+ var len = frg.childNodes.length;+ n.parentNode.replaceChild(frg,n);+ return len-1;+ } else return 0;+ }+ }+ } else return 0;+ } else if (n.nodeName!="math") {+ for (i=0; i<n.childNodes.length; i++)+ i += AMprocessNodeR(n.childNodes[i], linebreaks);+ }+ return 0;+}++function AMprocessNode(n, linebreaks, spanclassAM) {+ var frag,st;+ if (spanclassAM!=null) {+ frag = document.getElementsByTagName("span")+ for (var i=0;i<frag.length;i++)+ if (frag[i].className == "AM")+ AMprocessNodeR(frag[i],linebreaks);+ } else {+ try {+ st = n.innerHTML;+ } catch(err) {}+ if (st==null || + st.indexOf(AMdelimiter1)!=-1 || st.indexOf(AMdelimiter2)!=-1) + AMprocessNodeR(n,linebreaks);+ }+ if (isIE) { //needed to match size and font of formula to surrounding text+ frag = document.getElementsByTagName('math');+ for (var i=0;i<frag.length;i++) frag[i].update()+ }+}++var AMbody;+var AMnoMathML = false, AMtranslated = false;++function translate(spanclassAM) {+ if (!AMtranslated) { // run this only once+ AMtranslated = true;+ AMinitSymbols();+ AMbody = document.getElementsByTagName("body")[0];+ AMprocessNode(AMbody, false, spanclassAM);+ }+}++if (isIE) { // avoid adding MathPlayer info explicitly to each webpage+ document.write("<object id=\"mathplayer\"\+ classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>");+ document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>");+}++// GO1.1 Generic onload by Brothercake +// http://www.brothercake.com/+//onload function (replaces the onload="translate()" in the <body> tag)+function generic()+{+ translate();+};+//setup onload function+if(typeof window.addEventListener != 'undefined')+{+ //.. gecko, safari, konqueror and standard+ window.addEventListener('load', generic, false);+}+else if(typeof document.addEventListener != 'undefined')+{+ //.. opera 7+ document.addEventListener('load', generic, false);+}+else if(typeof window.attachEvent != 'undefined')+{+ //.. win/ie+ window.attachEvent('onload', generic);+}+//** remove this condition to degrade older browsers+else+{+ //.. mac/ie5 and anything else that gets this far+ //if there's an existing onload function+ if(typeof window.onload == 'function')+ {+ //store it+ var existing = onload;+ //add new onload handler+ window.onload = function()+ {+ //call existing onload function+ existing();+ //call generic onload function+ generic();+ };+ }+ else+ {+ //setup onload function+ window.onload = generic;+ }+}
+ src/Main.hs view
@@ -0,0 +1,494 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Main+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley@edu>+ Stability : alpha + Portability : portable++Parses command-line options and calls the appropriate readers and+writers.+-}+module Main where+import Text.Pandoc+import Text.Pandoc.UTF8+import Text.Pandoc.Shared ( joinWithSep, tabsToSpaces )+import Text.Regex ( mkRegex, matchRegex )+import System.Environment ( getArgs, getProgName, getEnvironment )+import System.Exit ( exitWith, ExitCode (..) )+import System.Console.GetOpt+import System.IO+import Data.Maybe ( fromMaybe )+import Data.List ( isPrefixOf )+import Data.Char ( toLower )+import Control.Monad ( (>>=) )++version :: String+version = "0.4"++copyrightMessage :: String+copyrightMessage = "\nCopyright (C) 2006-7 John MacFarlane\n\+ \Web: http://sophos.berkeley.edu/macfarlane/pandoc\n\+ \This is free software; see the source for copying conditions. There is no\n\+ \warranty, not even for merchantability or fitness for a particular purpose."++-- | Association list of formats and readers.+readers :: [(String, ParserState -> String -> Pandoc)]+readers = [("native" , readPandoc)+ ,("markdown" , readMarkdown)+ ,("rst" , readRST)+ ,("html" , readHtml)+ ,("latex" , readLaTeX)+ ]++-- | Reader for native Pandoc format.+readPandoc :: ParserState -> String -> Pandoc+readPandoc state input = read input+ +-- | Association list of formats and pairs of writers and default headers.+writers :: [ ( String, ( WriterOptions -> Pandoc -> String, String ) ) ]+writers = [("native" , (writeDoc, ""))+ ,("html" , (writeHtmlString, ""))+ ,("s5" , (writeS5String, defaultS5Header))+ ,("docbook" , (writeDocbook, defaultDocbookHeader))+ ,("latex" , (writeLaTeX, defaultLaTeXHeader))+ ,("context" , (writeConTeXt, defaultConTeXtHeader))+ ,("man" , (writeMan, ""))+ ,("markdown" , (writeMarkdown, ""))+ ,("rst" , (writeRST, ""))+ ,("rtf" , (writeRTF, defaultRTFHeader))+ ]++-- | Writer for Pandoc native format.+writeDoc :: WriterOptions -> Pandoc -> String+writeDoc options = prettyPandoc ++-- | Data structure for command line options.+data Opt = Opt+ { optPreserveTabs :: Bool -- ^ Convert tabs to spaces+ , optTabStop :: Int -- ^ Number of spaces per tab+ , optStandalone :: Bool -- ^ Include header, footer+ , optReader :: String -- ^ Reader format+ , optWriter :: String -- ^ Writer format+ , optParseRaw :: Bool -- ^ Parse unconvertable HTML and TeX+ , optCSS :: String -- ^ CSS file to link to+ , optTableOfContents :: Bool -- ^ Include table of contents+ , optIncludeInHeader :: String -- ^ File to include in header+ , optIncludeBeforeBody :: String -- ^ File to include at top of body+ , optIncludeAfterBody :: String -- ^ File to include at end of body+ , optCustomHeader :: String -- ^ Custom header to use, or "DEFAULT"+ , optTitlePrefix :: String -- ^ Optional prefix for HTML title+ , optOutputFile :: String -- ^ Name of output file+ , optNumberSections :: Bool -- ^ Number sections in LaTeX+ , optIncremental :: Bool -- ^ Use incremental lists in S5+ , optSmart :: Bool -- ^ Use smart typography+ , optUseASCIIMathML :: Bool -- ^ Use ASCIIMathML+ , optASCIIMathMLURL :: Maybe String -- ^ URL to ASCIIMathML.js+ , optDumpArgs :: Bool -- ^ Output command-line arguments+ , optIgnoreArgs :: Bool -- ^ Ignore command-line arguments+ , optStrict :: Bool -- ^ Use strict markdown syntax+ , optReferenceLinks :: Bool -- ^ Use reference links in writing markdown, rst+ }++-- | Defaults for command-line options.+defaultOpts :: Opt+defaultOpts = Opt+ { optPreserveTabs = False+ , optTabStop = 4+ , optStandalone = False+ , optReader = "" -- null for default reader+ , optWriter = "" -- null for default writer+ , optParseRaw = False+ , optCSS = ""+ , optTableOfContents = False+ , optIncludeInHeader = ""+ , optIncludeBeforeBody = ""+ , optIncludeAfterBody = ""+ , optCustomHeader = "DEFAULT"+ , optTitlePrefix = ""+ , optOutputFile = "-" -- "-" means stdout+ , optNumberSections = False+ , optIncremental = False+ , optSmart = False+ , optUseASCIIMathML = False+ , optASCIIMathMLURL = Nothing+ , optDumpArgs = False+ , optIgnoreArgs = False+ , optStrict = False+ , optReferenceLinks = False+ }++-- | A list of functions, each transforming the options data structure+-- in response to a command-line option.+options :: [OptDescr (Opt -> IO Opt)]+options =+ [ Option "fr" ["from","read"]+ (ReqArg+ (\arg opt -> return opt { optReader = map toLower arg })+ "FORMAT")+ "" -- ("(" ++ (joinWithSep ", " $ map fst readers) ++ ")")++ , Option "tw" ["to","write"]+ (ReqArg+ (\arg opt -> return opt { optWriter = map toLower arg })+ "FORMAT")+ "" -- ("(" ++ (joinWithSep ", " $ map fst writers) ++ ")")+ + , Option "s" ["standalone"]+ (NoArg+ (\opt -> return opt { optStandalone = True }))+ "" -- "Include needed header and footer on output"++ , Option "o" ["output"]+ (ReqArg+ (\arg opt -> return opt { optOutputFile = arg })+ "FILENAME")+ "" -- "Name of output file"++ , Option "p" ["preserve-tabs"]+ (NoArg+ (\opt -> return opt { optPreserveTabs = True }))+ "" -- "Preserve tabs instead of converting to spaces"++ , Option "" ["tab-stop"]+ (ReqArg+ (\arg opt -> return opt { optTabStop = (read arg) } )+ "TABSTOP")+ "" -- "Tab stop (default 4)"++ , Option "" ["strict"]+ (NoArg+ (\opt -> return opt { optStrict = True } ))+ "" -- "Disable markdown syntax extensions"++ , Option "" ["reference-links"]+ (NoArg+ (\opt -> return opt { optReferenceLinks = True } ))+ "" -- "Use reference links in parsing HTML"++ , Option "R" ["parse-raw"]+ (NoArg+ (\opt -> return opt { optParseRaw = True }))+ "" -- "Parse untranslatable HTML codes and LaTeX environments as raw"++ , Option "S" ["smart"]+ (NoArg+ (\opt -> return opt { optSmart = True }))+ "" -- "Use smart quotes, dashes, and ellipses"++ , Option "m" ["asciimathml"]+ (OptArg+ (\arg opt -> return opt { optUseASCIIMathML = True,+ optASCIIMathMLURL = arg, + optStandalone = True })+ "URL")+ "" -- "Use ASCIIMathML script in html output"++ , Option "i" ["incremental"]+ (NoArg+ (\opt -> return opt { optIncremental = True }))+ "" -- "Make list items display incrementally in S5"++ , Option "N" ["number-sections"]+ (NoArg+ (\opt -> return opt { optNumberSections = True }))+ "" -- "Number sections in LaTeX"++ , Option "" ["toc", "table-of-contents"]+ (NoArg+ (\opt -> return opt { optTableOfContents = True }))+ "" -- "Include table of contents" ++ , Option "c" ["css"]+ (ReqArg+ (\arg opt -> return opt { optCSS = arg, + optStandalone = True })+ "CSS")+ "" -- "Link to CSS style sheet"++ , Option "H" ["include-in-header"]+ (ReqArg+ (\arg opt -> do+ text <- readFile arg+ return opt { optIncludeInHeader = text, + optStandalone = True })+ "FILENAME")+ "" -- "File to include at end of header (implies -s)"++ , Option "B" ["include-before-body"]+ (ReqArg+ (\arg opt -> do+ text <- readFile arg+ return opt { optIncludeBeforeBody = text })+ "FILENAME")+ "" -- "File to include before document body"++ , Option "A" ["include-after-body"]+ (ReqArg+ (\arg opt -> do+ text <- readFile arg+ return opt { optIncludeAfterBody = text })+ "FILENAME")+ "" -- "File to include after document body"++ , Option "C" ["custom-header"]+ (ReqArg+ (\arg opt -> do+ text <- readFile arg+ return opt { optCustomHeader = text, + optStandalone = True })+ "FILENAME")+ "" -- "File to use for custom header (implies -s)"++ , Option "T" ["title-prefix"]+ (ReqArg+ (\arg opt -> return opt { optTitlePrefix = arg, + optStandalone = True })+ "STRING")+ "" -- "String to prefix to HTML window title"+ + , Option "D" ["print-default-header"]+ (ReqArg+ (\arg opt -> do+ let header = case (lookup arg writers) of+ Just (writer, head) -> head+ Nothing -> error ("Unknown reader: " ++ arg) + hPutStr stdout header+ exitWith ExitSuccess)+ "FORMAT")+ "" -- "Print default header for FORMAT"++ , Option "" ["dump-args"]+ (NoArg+ (\opt -> return opt { optDumpArgs = True }))+ "" -- "Print output filename and arguments to stdout."++ , Option "" ["ignore-args"]+ (NoArg+ (\opt -> return opt { optIgnoreArgs = True }))+ "" -- "Ignore command-line arguments."+ + , Option "v" ["version"]+ (NoArg+ (\_ -> do+ prg <- getProgName+ hPutStrLn stderr (prg ++ " " ++ version ++ + copyrightMessage)+ exitWith $ ExitFailure 4))+ "" -- "Print version"++ , Option "h" ["help"]+ (NoArg+ (\_ -> do+ prg <- getProgName+ hPutStr stderr (usageMessage prg options)+ exitWith $ ExitFailure 2))+ "" -- "Show help"+ ]++-- Returns usage message+usageMessage :: String -> [OptDescr (Opt -> IO Opt)] -> String+usageMessage programName options = usageInfo + (programName ++ " [OPTIONS] [FILES]" ++ "\nInput formats: " ++ + (joinWithSep ", " $ map fst readers) ++ "\nOutput formats: " ++ + (joinWithSep ", " $ map fst writers) ++ "\nOptions:")+ options+ +-- Determine default reader based on source file extensions+defaultReaderName :: [String] -> String+defaultReaderName [] = "markdown"+defaultReaderName (x:xs) = + let x' = map toLower x in+ case (matchRegex (mkRegex ".*\\.(.*)") x') of+ Nothing -> defaultReaderName xs -- no extension+ Just ["xhtml"] -> "html"+ Just ["html"] -> "html"+ Just ["htm"] -> "html"+ Just ["tex"] -> "latex"+ Just ["latex"] -> "latex"+ Just ["ltx"] -> "latex"+ Just ["rst"] -> "rst"+ Just ["native"] -> "native"+ Just _ -> "markdown"++-- Determine default writer based on output file extension+defaultWriterName :: String -> String+defaultWriterName "-" = "html" -- no output file+defaultWriterName x =+ let x' = map toLower x in+ case (matchRegex (mkRegex ".*\\.(.*)") x') of+ Nothing -> "markdown" -- no extension+ Just [""] -> "markdown" -- empty extension + Just ["tex"] -> "latex"+ Just ["latex"] -> "latex"+ Just ["ltx"] -> "latex"+ Just ["context"] -> "context"+ Just ["ctx"] -> "context"+ Just ["rtf"] -> "rtf"+ Just ["rst"] -> "rst"+ Just ["s5"] -> "s5"+ Just ["native"] -> "native"+ Just ["txt"] -> "markdown"+ Just ["text"] -> "markdown"+ Just ["md"] -> "markdown"+ Just ["markdown"] -> "markdown"+ Just ["db"] -> "docbook"+ Just ["xml"] -> "docbook"+ Just ["sgml"] -> "docbook"+ Just [[x]] | x `elem` ['1'..'9'] -> "man"+ Just _ -> "html"++main = do++ rawArgs <- getArgs+ prg <- getProgName+ let compatMode = (prg == "hsmarkdown")++ let (actions, args, errors) = if compatMode+ then ([], rawArgs, [])+ else getOpt Permute options rawArgs++ if (not (null errors))+ then do+ name <- getProgName+ mapM (\e -> hPutStrLn stderr e) errors+ hPutStr stderr (usageMessage name options)+ exitWith $ ExitFailure 2+ else+ return ()++ let defaultOpts' = if compatMode + then defaultOpts { optReader = "markdown"+ , optWriter = "html"+ , optStrict = True }+ else defaultOpts++ -- thread option data structure through all supplied option actions+ opts <- foldl (>>=) (return defaultOpts') actions++ let Opt { optPreserveTabs = preserveTabs+ , optTabStop = tabStop+ , optStandalone = standalone+ , optReader = readerName+ , optWriter = writerName+ , optParseRaw = parseRaw+ , optCSS = css+ , optTableOfContents = toc+ , optIncludeInHeader = includeHeader+ , optIncludeBeforeBody = includeBefore+ , optIncludeAfterBody = includeAfter+ , optCustomHeader = customHeader+ , optTitlePrefix = titlePrefix+ , optOutputFile = outputFile+ , optNumberSections = numberSections+ , optIncremental = incremental+ , optSmart = smart+ , optUseASCIIMathML = useAsciiMathML+ , optASCIIMathMLURL = asciiMathMLURL+ , optDumpArgs = dumpArgs+ , optIgnoreArgs = ignoreArgs+ , optStrict = strict+ , optReferenceLinks = referenceLinks+ } = opts++ if dumpArgs+ then do+ hPutStrLn stdout outputFile+ mapM (\arg -> hPutStrLn stdout arg) args+ exitWith $ ExitSuccess+ else return ()++ let sources = if ignoreArgs then [] else args++ -- assign reader and writer based on options and filenames+ let readerName' = if null readerName + then defaultReaderName sources+ else readerName++ let writerName' = if null writerName + then defaultWriterName outputFile+ else writerName++ reader <- case (lookup readerName' readers) of+ Just r -> return r+ Nothing -> error ("Unknown reader: " ++ readerName')++ (writer, defaultHeader) <- case (lookup writerName' writers) of+ Just (w,h) -> return (w, h)+ Nothing -> error ("Unknown writer: " ++ writerName')++ output <- if (outputFile == "-")+ then return stdout + else openFile outputFile WriteMode++ environment <- getEnvironment+ let columns = case lookup "COLUMNS" environment of+ Just cols -> read cols+ Nothing -> stateColumns defaultParserState++ let tabFilter = if preserveTabs then id else (tabsToSpaces tabStop)+ let removeCRs str = filter (/= '\r') str -- remove DOS-style line endings+ let startParserState = + defaultParserState { stateParseRaw = parseRaw,+ stateTabStop = tabStop, + stateStandalone = standalone && (not strict),+ stateSmart = smart || writerName' `elem` + ["latex", "context"],+ stateColumns = columns,+ stateStrict = strict }+ let csslink = if (css == "")+ then "" + else "<link rel=\"stylesheet\" href=\"" ++ css ++ + "\" type=\"text/css\" media=\"all\" />\n"+ let header = (if (customHeader == "DEFAULT") + then defaultHeader+ else customHeader) ++ csslink ++ includeHeader+ let writerOptions = WriterOptions { writerStandalone = standalone &&+ (not strict), + writerHeader = header, + writerTitlePrefix = titlePrefix,+ writerTabStop = tabStop, + writerTableOfContents = toc &&+ (not strict) &&+ writerName/="s5",+ writerUseASCIIMathML = useAsciiMathML,+ writerASCIIMathMLURL = asciiMathMLURL,+ writerS5 = (writerName=="s5"),+ writerIgnoreNotes = False,+ writerIncremental = incremental, + writerNumberSections = numberSections,+ writerIncludeBefore = includeBefore, + writerIncludeAfter = includeAfter,+ writerStrictMarkdown = strict,+ writerReferenceLinks = referenceLinks }++ (readSources sources) >>= (hPutStrLn output . toUTF8 . + (writer writerOptions) . + (reader startParserState) . tabFilter .+ removeCRs . fromUTF8 . (joinWithSep "\n")) >> + hClose output++ where + readSources [] = mapM readSource ["-"]+ readSources sources = mapM readSource sources+ readSource "-" = getContents+ readSource source = readFile source
+ src/Text/Pandoc.hs view
@@ -0,0 +1,105 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha + Portability : portable++This helper module exports the main writers, readers, and data+structure definitions from the Pandoc libraries.++A typical application will chain together a reader and a writer+to convert strings from one format to another. For example, the+following simple program will act as a filter converting markdown+fragments to reStructuredText, using reference-style links instead of+inline links:++> module Main where+> import Text.Pandoc+> +> markdownToRST :: String -> String+> markdownToRST = toUTF8 .+> (writeRST defaultWriterOptions {writerReferenceLinks = True}) .+> (readMarkdown defaultParserState) . fromUTF8+> +> main = interact markdownToRST++-}++module Text.Pandoc+ ( + -- * Definitions+ module Text.Pandoc.Definition+ -- * Readers: converting /to/ Pandoc format+ , readMarkdown+ , readRST+ , readLaTeX+ , readHtml+ -- * Parser state used in readers+ , ParserState (..)+ , defaultParserState+ , ParserContext (..)+ , QuoteContext (..)+ , KeyTable+ , NoteTable+ , HeaderType (..)+ -- * Writers: converting /from/ Pandoc format+ , writeMarkdown+ , writeRST+ , writeLaTeX+ , writeConTeXt+ , writeHtml+ , writeHtmlString+ , writeS5+ , writeS5String+ , writeDocbook+ , writeMan+ , writeRTF+ , prettyPandoc+ -- * Writer options used in writers + , WriterOptions (..)+ , defaultWriterOptions+ -- * Default headers for various output formats+ , module Text.Pandoc.Writers.DefaultHeaders+ -- * Functions for converting to and from UTF-8+ , module Text.Pandoc.UTF8+ ) where++import Text.Pandoc.Definition+import Text.Pandoc.Readers.Markdown+import Text.Pandoc.Readers.RST+import Text.Pandoc.Readers.LaTeX+import Text.Pandoc.Readers.HTML+import Text.Pandoc.Writers.Markdown+import Text.Pandoc.Writers.RST +import Text.Pandoc.Writers.LaTeX+import Text.Pandoc.Writers.ConTeXt+import Text.Pandoc.Writers.HTML+import Text.Pandoc.Writers.S5+import Text.Pandoc.Writers.Docbook+import Text.Pandoc.Writers.Man+import Text.Pandoc.Writers.RTF +import Text.Pandoc.Writers.DefaultHeaders+import Text.Pandoc.UTF8+import Text.Pandoc.Shared+
+ src/Text/Pandoc/ASCIIMathML.hs view
@@ -0,0 +1,14 @@+----------------------------------------------------+-- Do not edit this file by hand. Edit +-- 'templates/ASCIIMathML.hs'+-- and run ./fillTemplates.pl Text/Pandoc/ASCIIMathML.hs+----------------------------------------------------++-- | Definitions for use of ASCIIMathML in HTML. +-- (See <http://www1.chapman.edu/~jipsen/mathml/asciimath.html>.)+module Text.Pandoc.ASCIIMathML ( asciiMathMLScript ) where++-- | String containing ASCIIMathML javascript.+asciiMathMLScript :: String+asciiMathMLScript = "<script type=\"text/javascript\">\n/* ASCIIMathML.js - copyright Peter Jipsen, released under the GPL\nSee http://www1.chapman.edu/~jipsen/mathml/asciimath.html/ */\n\nvar checkForMathML = true; // check if browser can display MathML\nvar notifyIfNoMathML = true; // display note if no MathML capability\nvar alertIfNoMathML = false; // show alert box if no MathML capability\nvar mathcolor = \"\"; // change it to \"\" (to inherit) or any other color\nvar mathfontfamily = \"serif\"; // change to \"\" to inherit (works in IE) \n // or another family (e.g. \"arial\")\nvar displaystyle = true; // puts limits above and below large operators\nvar showasciiformulaonhover = true; // helps students learn ASCIIMath\nvar decimalsign = \".\"; // change to \",\" if you like, beware of `(1,2)`!\nvar AMdelimiter1 = \"`\", AMescape1 = \"\\\\\\\\`\"; // can use other characters\nvar AMdelimiter2 = \"$\", AMescape2 = \"\\\\\\\\\\\\$\", AMdelimiter2regexp = \"\\\\$\";\nvar doubleblankmathdelimiter = false; // if true, x+1 is equal to `x+1`\n // for IE this works only in <!-- -->\n//var separatetokens;// has been removed (email me if this is a problem)\nvar isIE = document.createElementNS==null;\n\nif (document.getElementById==null) \n alert(\"This webpage requires a recent browser such as\\\n\\nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer\")\n\n// all further global variables start with \"AM\"\n\nfunction AMcreateElementXHTML(t) {\n if (isIE) return document.createElement(t);\n else return document.createElementNS(\"http://www.w3.org/1999/xhtml\",t);\n}\n\nfunction AMnoMathMLNote() {\n var nd = AMcreateElementXHTML(\"h3\");\n nd.setAttribute(\"align\",\"center\")\n nd.appendChild(AMcreateElementXHTML(\"p\"));\n nd.appendChild(document.createTextNode(\"To view the \"));\n var an = AMcreateElementXHTML(\"a\");\n an.appendChild(document.createTextNode(\"ASCIIMathML\"));\n an.setAttribute(\"href\",\"http://www.chapman.edu/~jipsen/asciimath.html\");\n nd.appendChild(an);\n nd.appendChild(document.createTextNode(\" notation use Internet Explorer 6+\")); \n an = AMcreateElementXHTML(\"a\");\n an.appendChild(document.createTextNode(\"MathPlayer\"));\n an.setAttribute(\"href\",\"http://www.dessci.com/en/products/mathplayer/download.htm\");\n nd.appendChild(an);\n nd.appendChild(document.createTextNode(\" or Netscape/Mozilla/Firefox\"));\n nd.appendChild(AMcreateElementXHTML(\"p\"));\n return nd;\n}\n\nfunction AMisMathMLavailable() {\n var regex = /KHTML/; /* ASCIIMathML.js - copyright Peter Jipsen, released under the GPL\nSee http://www1.chapman.edu/~jipsen/mathml/asciimath.html/ */\n if (navigator.appName.slice(0,8)==\"Netscape\")\n if (navigator.appVersion.slice(0,1)>=\"5\" && !regex.test(navigator.userAgent)) return null;\n else return AMnoMathMLNote();\n else if (navigator.appName.slice(0,9)==\"Microsoft\")\n try {\n var ActiveX = new ActiveXObject(\"MathPlayer.Factory.1\");\n return null;\n } catch (e) {\n return AMnoMathMLNote();\n }\n else return AMnoMathMLNote();\n}\n\n// character lists for Mozilla/Netscape fonts\nvar AMcal = [0xEF35,0x212C,0xEF36,0xEF37,0x2130,0x2131,0xEF38,0x210B,0x2110,0xEF39,0xEF3A,0x2112,0x2133,0xEF3B,0xEF3C,0xEF3D,0xEF3E,0x211B,0xEF3F,0xEF40,0xEF41,0xEF42,0xEF43,0xEF44,0xEF45,0xEF46];\nvar AMfrk = [0xEF5D,0xEF5E,0x212D,0xEF5F,0xEF60,0xEF61,0xEF62,0x210C,0x2111,0xEF63,0xEF64,0xEF65,0xEF66,0xEF67,0xEF68,0xEF69,0xEF6A,0x211C,0xEF6B,0xEF6C,0xEF6D,0xEF6E,0xEF6F,0xEF70,0xEF71,0x2128];\nvar AMbbb = [0xEF8C,0xEF8D,0x2102,0xEF8E,0xEF8F,0xEF90,0xEF91,0x210D,0xEF92,0xEF93,0xEF94,0xEF95,0xEF96,0x2115,0xEF97,0x2119,0x211A,0x211D,0xEF98,0xEF99,0xEF9A,0xEF9B,0xEF9C,0xEF9D,0xEF9E,0x2124];\n\nvar CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4, \n RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8,\n LEFTRIGHT = 9, TEXT = 10; // token types\n\nvar AMsqrt = {input:\"sqrt\", tag:\"msqrt\", output:\"sqrt\", tex:null, ttype:UNARY},\n AMroot = {input:\"root\", tag:\"mroot\", output:\"root\", tex:null, ttype:BINARY},\n AMfrac = {input:\"frac\", tag:\"mfrac\", output:\"/\", tex:null, ttype:BINARY},\n AMdiv = {input:\"/\", tag:\"mfrac\", output:\"/\", tex:null, ttype:INFIX},\n AMover = {input:\"stackrel\", tag:\"mover\", output:\"stackrel\", tex:null, ttype:BINARY},\n AMsub = {input:\"_\", tag:\"msub\", output:\"_\", tex:null, ttype:INFIX},\n AMsup = {input:\"^\", tag:\"msup\", output:\"^\", tex:null, ttype:INFIX},\n AMtext = {input:\"text\", tag:\"mtext\", output:\"text\", tex:null, ttype:TEXT},\n AMmbox = {input:\"mbox\", tag:\"mtext\", output:\"mbox\", tex:null, ttype:TEXT},\n AMquote = {input:\"\\\"\", tag:\"mtext\", output:\"mbox\", tex:null, ttype:TEXT};\n\nvar AMsymbols = [\n//some greek symbols\n{input:\"alpha\", tag:\"mi\", output:\"\\u03B1\", tex:null, ttype:CONST},\n{input:\"beta\", tag:\"mi\", output:\"\\u03B2\", tex:null, ttype:CONST},\n{input:\"chi\", tag:\"mi\", output:\"\\u03C7\", tex:null, ttype:CONST},\n{input:\"delta\", tag:\"mi\", output:\"\\u03B4\", tex:null, ttype:CONST},\n{input:\"Delta\", tag:\"mo\", output:\"\\u0394\", tex:null, ttype:CONST},\n{input:\"epsi\", tag:\"mi\", output:\"\\u03B5\", tex:\"epsilon\", ttype:CONST},\n{input:\"varepsilon\", tag:\"mi\", output:\"\\u025B\", tex:null, ttype:CONST},\n{input:\"eta\", tag:\"mi\", output:\"\\u03B7\", tex:null, ttype:CONST},\n{input:\"gamma\", tag:\"mi\", output:\"\\u03B3\", tex:null, ttype:CONST},\n{input:\"Gamma\", tag:\"mo\", output:\"\\u0393\", tex:null, ttype:CONST},\n{input:\"iota\", tag:\"mi\", output:\"\\u03B9\", tex:null, ttype:CONST},\n{input:\"kappa\", tag:\"mi\", output:\"\\u03BA\", tex:null, ttype:CONST},\n{input:\"lambda\", tag:\"mi\", output:\"\\u03BB\", tex:null, ttype:CONST},\n{input:\"Lambda\", tag:\"mo\", output:\"\\u039B\", tex:null, ttype:CONST},\n{input:\"mu\", tag:\"mi\", output:\"\\u03BC\", tex:null, ttype:CONST},\n{input:\"nu\", tag:\"mi\", output:\"\\u03BD\", tex:null, ttype:CONST},\n{input:\"omega\", tag:\"mi\", output:\"\\u03C9\", tex:null, ttype:CONST},\n{input:\"Omega\", tag:\"mo\", output:\"\\u03A9\", tex:null, ttype:CONST},\n{input:\"phi\", tag:\"mi\", output:\"\\u03C6\", tex:null, ttype:CONST},\n{input:\"varphi\", tag:\"mi\", output:\"\\u03D5\", tex:null, ttype:CONST},\n{input:\"Phi\", tag:\"mo\", output:\"\\u03A6\", tex:null, ttype:CONST},\n{input:\"pi\", tag:\"mi\", output:\"\\u03C0\", tex:null, ttype:CONST},\n{input:\"Pi\", tag:\"mo\", output:\"\\u03A0\", tex:null, ttype:CONST},\n{input:\"psi\", tag:\"mi\", output:\"\\u03C8\", tex:null, ttype:CONST},\n{input:\"Psi\", tag:\"mi\", output:\"\\u03A8\", tex:null, ttype:CONST},\n{input:\"rho\", tag:\"mi\", output:\"\\u03C1\", tex:null, ttype:CONST},\n{input:\"sigma\", tag:\"mi\", output:\"\\u03C3\", tex:null, ttype:CONST},\n{input:\"Sigma\", tag:\"mo\", output:\"\\u03A3\", tex:null, ttype:CONST},\n{input:\"tau\", tag:\"mi\", output:\"\\u03C4\", tex:null, ttype:CONST},\n{input:\"theta\", tag:\"mi\", output:\"\\u03B8\", tex:null, ttype:CONST},\n{input:\"vartheta\", tag:\"mi\", output:\"\\u03D1\", tex:null, ttype:CONST},\n{input:\"Theta\", tag:\"mo\", output:\"\\u0398\", tex:null, ttype:CONST},\n{input:\"upsilon\", tag:\"mi\", output:\"\\u03C5\", tex:null, ttype:CONST},\n{input:\"xi\", tag:\"mi\", output:\"\\u03BE\", tex:null, ttype:CONST},\n{input:\"Xi\", tag:\"mo\", output:\"\\u039E\", tex:null, ttype:CONST},\n{input:\"zeta\", tag:\"mi\", output:\"\\u03B6\", tex:null, ttype:CONST},\n\n//binary operation symbols\n{input:\"*\", tag:\"mo\", output:\"\\u22C5\", tex:\"cdot\", ttype:CONST},\n{input:\"**\", tag:\"mo\", output:\"\\u22C6\", tex:\"star\", ttype:CONST},\n{input:\"//\", tag:\"mo\", output:\"/\", tex:null, ttype:CONST},\n{input:\"\\\\\\\\\", tag:\"mo\", output:\"\\\\\", tex:\"backslash\", ttype:CONST},\n{input:\"setminus\", tag:\"mo\", output:\"\\\\\", tex:null, ttype:CONST},\n{input:\"xx\", tag:\"mo\", output:\"\\u00D7\", tex:\"times\", ttype:CONST},\n{input:\"-:\", tag:\"mo\", output:\"\\u00F7\", tex:\"divide\", ttype:CONST},\n{input:\"@\", tag:\"mo\", output:\"\\u2218\", tex:\"circ\", ttype:CONST},\n{input:\"o+\", tag:\"mo\", output:\"\\u2295\", tex:\"oplus\", ttype:CONST},\n{input:\"ox\", tag:\"mo\", output:\"\\u2297\", tex:\"otimes\", ttype:CONST},\n{input:\"o.\", tag:\"mo\", output:\"\\u2299\", tex:\"odot\", ttype:CONST},\n{input:\"sum\", tag:\"mo\", output:\"\\u2211\", tex:null, ttype:UNDEROVER},\n{input:\"prod\", tag:\"mo\", output:\"\\u220F\", tex:null, ttype:UNDEROVER},\n{input:\"^^\", tag:\"mo\", output:\"\\u2227\", tex:\"wedge\", ttype:CONST},\n{input:\"^^^\", tag:\"mo\", output:\"\\u22C0\", tex:\"bigwedge\", ttype:UNDEROVER},\n{input:\"vv\", tag:\"mo\", output:\"\\u2228\", tex:\"vee\", ttype:CONST},\n{input:\"vvv\", tag:\"mo\", output:\"\\u22C1\", tex:\"bigvee\", ttype:UNDEROVER},\n{input:\"nn\", tag:\"mo\", output:\"\\u2229\", tex:\"cap\", ttype:CONST},\n{input:\"nnn\", tag:\"mo\", output:\"\\u22C2\", tex:\"bigcap\", ttype:UNDEROVER},\n{input:\"uu\", tag:\"mo\", output:\"\\u222A\", tex:\"cup\", ttype:CONST},\n{input:\"uuu\", tag:\"mo\", output:\"\\u22C3\", tex:\"bigcup\", ttype:UNDEROVER},\n\n//binary relation symbols\n{input:\"!=\", tag:\"mo\", output:\"\\u2260\", tex:\"ne\", ttype:CONST},\n{input:\":=\", tag:\"mo\", output:\":=\", tex:null, ttype:CONST},\n{input:\"lt\", tag:\"mo\", output:\"<\", tex:null, ttype:CONST},\n{input:\"<=\", tag:\"mo\", output:\"\\u2264\", tex:\"le\", ttype:CONST},\n{input:\"lt=\", tag:\"mo\", output:\"\\u2264\", tex:\"leq\", ttype:CONST},\n{input:\">=\", tag:\"mo\", output:\"\\u2265\", tex:\"ge\", ttype:CONST},\n{input:\"geq\", tag:\"mo\", output:\"\\u2265\", tex:null, ttype:CONST},\n{input:\"-<\", tag:\"mo\", output:\"\\u227A\", tex:\"prec\", ttype:CONST},\n{input:\"-lt\", tag:\"mo\", output:\"\\u227A\", tex:null, ttype:CONST},\n{input:\">-\", tag:\"mo\", output:\"\\u227B\", tex:\"succ\", ttype:CONST},\n{input:\"-<=\", tag:\"mo\", output:\"\\u2AAF\", tex:\"preceq\", ttype:CONST},\n{input:\">-=\", tag:\"mo\", output:\"\\u2AB0\", tex:\"succeq\", ttype:CONST},\n{input:\"in\", tag:\"mo\", output:\"\\u2208\", tex:null, ttype:CONST},\n{input:\"!in\", tag:\"mo\", output:\"\\u2209\", tex:\"notin\", ttype:CONST},\n{input:\"sub\", tag:\"mo\", output:\"\\u2282\", tex:\"subset\", ttype:CONST},\n{input:\"sup\", tag:\"mo\", output:\"\\u2283\", tex:\"supset\", ttype:CONST},\n{input:\"sube\", tag:\"mo\", output:\"\\u2286\", tex:\"subseteq\", ttype:CONST},\n{input:\"supe\", tag:\"mo\", output:\"\\u2287\", tex:\"supseteq\", ttype:CONST},\n{input:\"-=\", tag:\"mo\", output:\"\\u2261\", tex:\"equiv\", ttype:CONST},\n{input:\"~=\", tag:\"mo\", output:\"\\u2245\", tex:\"cong\", ttype:CONST},\n{input:\"~~\", tag:\"mo\", output:\"\\u2248\", tex:\"approx\", ttype:CONST},\n{input:\"prop\", tag:\"mo\", output:\"\\u221D\", tex:\"propto\", ttype:CONST},\n\n//logical symbols\n{input:\"and\", tag:\"mtext\", output:\"and\", tex:null, ttype:SPACE},\n{input:\"or\", tag:\"mtext\", output:\"or\", tex:null, ttype:SPACE},\n{input:\"not\", tag:\"mo\", output:\"\\u00AC\", tex:\"neg\", ttype:CONST},\n{input:\"=>\", tag:\"mo\", output:\"\\u21D2\", tex:\"implies\", ttype:CONST},\n{input:\"if\", tag:\"mo\", output:\"if\", tex:null, ttype:SPACE},\n{input:\"<=>\", tag:\"mo\", output:\"\\u21D4\", tex:\"iff\", ttype:CONST},\n{input:\"AA\", tag:\"mo\", output:\"\\u2200\", tex:\"forall\", ttype:CONST},\n{input:\"EE\", tag:\"mo\", output:\"\\u2203\", tex:\"exists\", ttype:CONST},\n{input:\"_|_\", tag:\"mo\", output:\"\\u22A5\", tex:\"bot\", ttype:CONST},\n{input:\"TT\", tag:\"mo\", output:\"\\u22A4\", tex:\"top\", ttype:CONST},\n{input:\"|--\", tag:\"mo\", output:\"\\u22A2\", tex:\"vdash\", ttype:CONST},\n{input:\"|==\", tag:\"mo\", output:\"\\u22A8\", tex:\"models\", ttype:CONST},\n\n//grouping brackets\n{input:\"(\", tag:\"mo\", output:\"(\", tex:null, ttype:LEFTBRACKET},\n{input:\")\", tag:\"mo\", output:\")\", tex:null, ttype:RIGHTBRACKET},\n{input:\"[\", tag:\"mo\", output:\"[\", tex:null, ttype:LEFTBRACKET},\n{input:\"]\", tag:\"mo\", output:\"]\", tex:null, ttype:RIGHTBRACKET},\n{input:\"{\", tag:\"mo\", output:\"{\", tex:null, ttype:LEFTBRACKET},\n{input:\"}\", tag:\"mo\", output:\"}\", tex:null, ttype:RIGHTBRACKET},\n{input:\"|\", tag:\"mo\", output:\"|\", tex:null, ttype:LEFTRIGHT},\n//{input:\"||\", tag:\"mo\", output:\"||\", tex:null, ttype:LEFTRIGHT},\n{input:\"(:\", tag:\"mo\", output:\"\\u2329\", tex:\"langle\", ttype:LEFTBRACKET},\n{input:\":)\", tag:\"mo\", output:\"\\u232A\", tex:\"rangle\", ttype:RIGHTBRACKET},\n{input:\"<<\", tag:\"mo\", output:\"\\u2329\", tex:null, ttype:LEFTBRACKET},\n{input:\">>\", tag:\"mo\", output:\"\\u232A\", tex:null, ttype:RIGHTBRACKET},\n{input:\"{:\", tag:\"mo\", output:\"{:\", tex:null, ttype:LEFTBRACKET, invisible:true},\n{input:\":}\", tag:\"mo\", output:\":}\", tex:null, ttype:RIGHTBRACKET, invisible:true},\n\n//miscellaneous symbols\n{input:\"int\", tag:\"mo\", output:\"\\u222B\", tex:null, ttype:CONST},\n{input:\"dx\", tag:\"mi\", output:\"{:d x:}\", tex:null, ttype:DEFINITION},\n{input:\"dy\", tag:\"mi\", output:\"{:d y:}\", tex:null, ttype:DEFINITION},\n{input:\"dz\", tag:\"mi\", output:\"{:d z:}\", tex:null, ttype:DEFINITION},\n{input:\"dt\", tag:\"mi\", output:\"{:d t:}\", tex:null, ttype:DEFINITION},\n{input:\"oint\", tag:\"mo\", output:\"\\u222E\", tex:null, ttype:CONST},\n{input:\"del\", tag:\"mo\", output:\"\\u2202\", tex:\"partial\", ttype:CONST},\n{input:\"grad\", tag:\"mo\", output:\"\\u2207\", tex:\"nabla\", ttype:CONST},\n{input:\"+-\", tag:\"mo\", output:\"\\u00B1\", tex:\"pm\", ttype:CONST},\n{input:\"O/\", tag:\"mo\", output:\"\\u2205\", tex:\"emptyset\", ttype:CONST},\n{input:\"oo\", tag:\"mo\", output:\"\\u221E\", tex:\"infty\", ttype:CONST},\n{input:\"aleph\", tag:\"mo\", output:\"\\u2135\", tex:null, ttype:CONST},\n{input:\"...\", tag:\"mo\", output:\"...\", tex:\"ldots\", ttype:CONST},\n{input:\":.\", tag:\"mo\", output:\"\\u2234\", tex:\"therefore\", ttype:CONST},\n{input:\"/_\", tag:\"mo\", output:\"\\u2220\", tex:\"angle\", ttype:CONST},\n{input:\"\\\\ \", tag:\"mo\", output:\"\\u00A0\", tex:null, ttype:CONST},\n{input:\"quad\", tag:\"mo\", output:\"\\u00A0\\u00A0\", tex:null, ttype:CONST},\n{input:\"qquad\", tag:\"mo\", output:\"\\u00A0\\u00A0\\u00A0\\u00A0\", tex:null, ttype:CONST},\n{input:\"cdots\", tag:\"mo\", output:\"\\u22EF\", tex:null, ttype:CONST},\n{input:\"vdots\", tag:\"mo\", output:\"\\u22EE\", tex:null, ttype:CONST},\n{input:\"ddots\", tag:\"mo\", output:\"\\u22F1\", tex:null, ttype:CONST},\n{input:\"diamond\", tag:\"mo\", output:\"\\u22C4\", tex:null, ttype:CONST},\n{input:\"square\", tag:\"mo\", output:\"\\u25A1\", tex:null, ttype:CONST},\n{input:\"|__\", tag:\"mo\", output:\"\\u230A\", tex:\"lfloor\", ttype:CONST},\n{input:\"__|\", tag:\"mo\", output:\"\\u230B\", tex:\"rfloor\", ttype:CONST},\n{input:\"|~\", tag:\"mo\", output:\"\\u2308\", tex:\"lceiling\", ttype:CONST},\n{input:\"~|\", tag:\"mo\", output:\"\\u2309\", tex:\"rceiling\", ttype:CONST},\n{input:\"CC\", tag:\"mo\", output:\"\\u2102\", tex:null, ttype:CONST},\n{input:\"NN\", tag:\"mo\", output:\"\\u2115\", tex:null, ttype:CONST},\n{input:\"QQ\", tag:\"mo\", output:\"\\u211A\", tex:null, ttype:CONST},\n{input:\"RR\", tag:\"mo\", output:\"\\u211D\", tex:null, ttype:CONST},\n{input:\"ZZ\", tag:\"mo\", output:\"\\u2124\", tex:null, ttype:CONST},\n{input:\"f\", tag:\"mi\", output:\"f\", tex:null, ttype:UNARY, func:true},\n{input:\"g\", tag:\"mi\", output:\"g\", tex:null, ttype:UNARY, func:true},\n\n//standard functions\n{input:\"lim\", tag:\"mo\", output:\"lim\", tex:null, ttype:UNDEROVER},\n{input:\"Lim\", tag:\"mo\", output:\"Lim\", tex:null, ttype:UNDEROVER},\n{input:\"sin\", tag:\"mo\", output:\"sin\", tex:null, ttype:UNARY, func:true},\n{input:\"cos\", tag:\"mo\", output:\"cos\", tex:null, ttype:UNARY, func:true},\n{input:\"tan\", tag:\"mo\", output:\"tan\", tex:null, ttype:UNARY, func:true},\n{input:\"sinh\", tag:\"mo\", output:\"sinh\", tex:null, ttype:UNARY, func:true},\n{input:\"cosh\", tag:\"mo\", output:\"cosh\", tex:null, ttype:UNARY, func:true},\n{input:\"tanh\", tag:\"mo\", output:\"tanh\", tex:null, ttype:UNARY, func:true},\n{input:\"cot\", tag:\"mo\", output:\"cot\", tex:null, ttype:UNARY, func:true},\n{input:\"sec\", tag:\"mo\", output:\"sec\", tex:null, ttype:UNARY, func:true},\n{input:\"csc\", tag:\"mo\", output:\"csc\", tex:null, ttype:UNARY, func:true},\n{input:\"log\", tag:\"mo\", output:\"log\", tex:null, ttype:UNARY, func:true},\n{input:\"ln\", tag:\"mo\", output:\"ln\", tex:null, ttype:UNARY, func:true},\n{input:\"det\", tag:\"mo\", output:\"det\", tex:null, ttype:UNARY, func:true},\n{input:\"dim\", tag:\"mo\", output:\"dim\", tex:null, ttype:CONST},\n{input:\"mod\", tag:\"mo\", output:\"mod\", tex:null, ttype:CONST},\n{input:\"gcd\", tag:\"mo\", output:\"gcd\", tex:null, ttype:UNARY, func:true},\n{input:\"lcm\", tag:\"mo\", output:\"lcm\", tex:null, ttype:UNARY, func:true},\n{input:\"lub\", tag:\"mo\", output:\"lub\", tex:null, ttype:CONST},\n{input:\"glb\", tag:\"mo\", output:\"glb\", tex:null, ttype:CONST},\n{input:\"min\", tag:\"mo\", output:\"min\", tex:null, ttype:UNDEROVER},\n{input:\"max\", tag:\"mo\", output:\"max\", tex:null, ttype:UNDEROVER},\n\n//arrows\n{input:\"uarr\", tag:\"mo\", output:\"\\u2191\", tex:\"uparrow\", ttype:CONST},\n{input:\"darr\", tag:\"mo\", output:\"\\u2193\", tex:\"downarrow\", ttype:CONST},\n{input:\"rarr\", tag:\"mo\", output:\"\\u2192\", tex:\"rightarrow\", ttype:CONST},\n{input:\"->\", tag:\"mo\", output:\"\\u2192\", tex:\"to\", ttype:CONST},\n{input:\"|->\", tag:\"mo\", output:\"\\u21A6\", tex:\"mapsto\", ttype:CONST},\n{input:\"larr\", tag:\"mo\", output:\"\\u2190\", tex:\"leftarrow\", ttype:CONST},\n{input:\"harr\", tag:\"mo\", output:\"\\u2194\", tex:\"leftrightarrow\", ttype:CONST},\n{input:\"rArr\", tag:\"mo\", output:\"\\u21D2\", tex:\"Rightarrow\", ttype:CONST},\n{input:\"lArr\", tag:\"mo\", output:\"\\u21D0\", tex:\"Leftarrow\", ttype:CONST},\n{input:\"hArr\", tag:\"mo\", output:\"\\u21D4\", tex:\"Leftrightarrow\", ttype:CONST},\n\n//commands with argument\nAMsqrt, AMroot, AMfrac, AMdiv, AMover, AMsub, AMsup,\n{input:\"hat\", tag:\"mover\", output:\"\\u005E\", tex:null, ttype:UNARY, acc:true},\n{input:\"bar\", tag:\"mover\", output:\"\\u00AF\", tex:\"overline\", ttype:UNARY, acc:true},\n{input:\"vec\", tag:\"mover\", output:\"\\u2192\", tex:null, ttype:UNARY, acc:true},\n{input:\"dot\", tag:\"mover\", output:\".\", tex:null, ttype:UNARY, acc:true},\n{input:\"ddot\", tag:\"mover\", output:\"..\", tex:null, ttype:UNARY, acc:true},\n{input:\"ul\", tag:\"munder\", output:\"\\u0332\", tex:\"underline\", ttype:UNARY, acc:true},\nAMtext, AMmbox, AMquote,\n{input:\"bb\", tag:\"mstyle\", atname:\"fontweight\", atval:\"bold\", output:\"bb\", tex:null, ttype:UNARY},\n{input:\"mathbf\", tag:\"mstyle\", atname:\"fontweight\", atval:\"bold\", output:\"mathbf\", tex:null, ttype:UNARY},\n{input:\"sf\", tag:\"mstyle\", atname:\"fontfamily\", atval:\"sans-serif\", output:\"sf\", tex:null, ttype:UNARY},\n{input:\"mathsf\", tag:\"mstyle\", atname:\"fontfamily\", atval:\"sans-serif\", output:\"mathsf\", tex:null, ttype:UNARY},\n{input:\"bbb\", tag:\"mstyle\", atname:\"mathvariant\", atval:\"double-struck\", output:\"bbb\", tex:null, ttype:UNARY, codes:AMbbb},\n{input:\"mathbb\", tag:\"mstyle\", atname:\"mathvariant\", atval:\"double-struck\", output:\"mathbb\", tex:null, ttype:UNARY, codes:AMbbb},\n{input:\"cc\", tag:\"mstyle\", atname:\"mathvariant\", atval:\"script\", output:\"cc\", tex:null, ttype:UNARY, codes:AMcal},\n{input:\"mathcal\", tag:\"mstyle\", atname:\"mathvariant\", atval:\"script\", output:\"mathcal\", tex:null, ttype:UNARY, codes:AMcal},\n{input:\"tt\", tag:\"mstyle\", atname:\"fontfamily\", atval:\"monospace\", output:\"tt\", tex:null, ttype:UNARY},\n{input:\"mathtt\", tag:\"mstyle\", atname:\"fontfamily\", atval:\"monospace\", output:\"mathtt\", tex:null, ttype:UNARY},\n{input:\"fr\", tag:\"mstyle\", atname:\"mathvariant\", atval:\"fraktur\", output:\"fr\", tex:null, ttype:UNARY, codes:AMfrk},\n{input:\"mathfrak\", tag:\"mstyle\", atname:\"mathvariant\", atval:\"fraktur\", output:\"mathfrak\", tex:null, ttype:UNARY, codes:AMfrk}\n];\n\nfunction compareNames(s1,s2) {\n if (s1.input > s2.input) return 1\n else return -1;\n}\n\nvar AMnames = []; //list of input symbols\n\nfunction AMinitSymbols() {\n var texsymbols = [], i;\n for (i=0; i<AMsymbols.length; i++)\n if (AMsymbols[i].tex) \n texsymbols[texsymbols.length] = {input:AMsymbols[i].tex, \n tag:AMsymbols[i].tag, output:AMsymbols[i].output, ttype:AMsymbols[i].ttype};\n AMsymbols = AMsymbols.concat(texsymbols);\n AMsymbols.sort(compareNames);\n for (i=0; i<AMsymbols.length; i++) AMnames[i] = AMsymbols[i].input;\n}\n\nvar AMmathml = \"http://www.w3.org/1998/Math/MathML\";\n\nfunction AMcreateElementMathML(t) {\n if (isIE) return document.createElement(\"m:\"+t);\n else return document.createElementNS(AMmathml,t);\n}\n\nfunction AMcreateMmlNode(t,frag) {\n// var node = AMcreateElementMathML(name);\n if (isIE) var node = document.createElement(\"m:\"+t);\n else var node = document.createElementNS(AMmathml,t);\n node.appendChild(frag);\n return node;\n}\n\nfunction newcommand(oldstr,newstr) {\n AMsymbols = AMsymbols.concat([{input:oldstr, tag:\"mo\", output:newstr, \n tex:null, ttype:DEFINITION}]);\n}\n\nfunction AMremoveCharsAndBlanks(str,n) {\n//remove n characters and any following blanks\n var st;\n if (str.charAt(n)==\"\\\\\" && str.charAt(n+1)!=\"\\\\\" && str.charAt(n+1)!=\" \") \n st = str.slice(n+1);\n else st = str.slice(n);\n for (var i=0; i<st.length && st.charCodeAt(i)<=32; i=i+1);\n return st.slice(i);\n}\n\nfunction AMposition(arr, str, n) { \n// return position >=n where str appears or would be inserted\n// assumes arr is sorted\n if (n==0) {\n var h,m;\n n = -1;\n h = arr.length;\n while (n+1<h) {\n m = (n+h) >> 1;\n if (arr[m]<str) n = m; else h = m;\n }\n return h;\n } else\n for (var i=n; i<arr.length && arr[i]<str; i++);\n return i; // i=arr.length || arr[i]>=str\n}\n\nfunction AMgetSymbol(str) {\n//return maximal initial substring of str that appears in names\n//return null if there is none\n var k = 0; //new pos\n var j = 0; //old pos\n var mk; //match pos\n var st;\n var tagst;\n var match = \"\";\n var more = true;\n for (var i=1; i<=str.length && more; i++) {\n st = str.slice(0,i); //initial substring of length i\n j = k;\n k = AMposition(AMnames, st, j);\n if (k<AMnames.length && str.slice(0,AMnames[k].length)==AMnames[k]){\n match = AMnames[k];\n mk = k;\n i = match.length;\n }\n more = k<AMnames.length && str.slice(0,AMnames[k].length)>=AMnames[k];\n }\n AMpreviousSymbol=AMcurrentSymbol;\n if (match!=\"\"){\n AMcurrentSymbol=AMsymbols[mk].ttype;\n return AMsymbols[mk]; \n }\n// if str[0] is a digit or - return maxsubstring of digits.digits\n AMcurrentSymbol=CONST;\n k = 1;\n st = str.slice(0,1);\n var integ = true;\n while (\"0\"<=st && st<=\"9\" && k<=str.length) {\n st = str.slice(k,k+1);\n k++;\n }\n if (st == decimalsign) {\n st = str.slice(k,k+1);\n if (\"0\"<=st && st<=\"9\") {\n integ = false;\n k++;\n while (\"0\"<=st && st<=\"9\" && k<=str.length) {\n st = str.slice(k,k+1);\n k++;\n }\n }\n }\n if ((integ && k>1) || k>2) {\n st = str.slice(0,k-1);\n tagst = \"mn\";\n } else {\n k = 2;\n st = str.slice(0,1); //take 1 character\n tagst = ((\"A\">st || st>\"Z\") && (\"a\">st || st>\"z\")?\"mo\":\"mi\");\n }\n if (st==\"-\" && AMpreviousSymbol==INFIX) {\n AMcurrentSymbol = INFIX; //trick \"/\" into recognizing \"-\" on second parse\n return {input:st, tag:tagst, output:st, ttype:UNARY, func:true};\n }\n return {input:st, tag:tagst, output:st, ttype:CONST};\n}\n\nfunction AMremoveBrackets(node) {\n var st;\n if (node.nodeName==\"mrow\") {\n st = node.firstChild.firstChild.nodeValue;\n if (st==\"(\" || st==\"[\" || st==\"{\") node.removeChild(node.firstChild);\n }\n if (node.nodeName==\"mrow\") {\n st = node.lastChild.firstChild.nodeValue;\n if (st==\")\" || st==\"]\" || st==\"}\") node.removeChild(node.lastChild);\n }\n}\n\n/* ASCIIMathML.js - copyright Peter Jipsen, released under the GPL\nSee http://www1.chapman.edu/~jipsen/mathml/asciimath.html/ */\n\nvar AMnestingDepth,AMpreviousSymbol,AMcurrentSymbol;\n\nfunction AMparseSexpr(str) { //parses str and returns [node,tailstr]\n var symbol, node, result, i, st,// rightvert = false,\n newFrag = document.createDocumentFragment();\n str = AMremoveCharsAndBlanks(str,0);\n symbol = AMgetSymbol(str); //either a token or a bracket or empty\n if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) {\n return [null,str];\n }\n if (symbol.ttype == DEFINITION) {\n str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length); \n symbol = AMgetSymbol(str);\n }\n switch (symbol.ttype) {\n case UNDEROVER:\n case CONST:\n str = AMremoveCharsAndBlanks(str,symbol.input.length); \n return [AMcreateMmlNode(symbol.tag, //its a constant\n document.createTextNode(symbol.output)),str];\n case LEFTBRACKET: //read (expr+)\n AMnestingDepth++;\n str = AMremoveCharsAndBlanks(str,symbol.input.length); \n result = AMparseExpr(str,true);\n AMnestingDepth--;\n if (typeof symbol.invisible == \"boolean\" && symbol.invisible) \n node = AMcreateMmlNode(\"mrow\",result[0]);\n else {\n node = AMcreateMmlNode(\"mo\",document.createTextNode(symbol.output));\n node = AMcreateMmlNode(\"mrow\",node);\n node.appendChild(result[0]);\n }\n return [node,result[1]];\n case TEXT:\n if (symbol!=AMquote) str = AMremoveCharsAndBlanks(str,symbol.input.length);\n if (str.charAt(0)==\"{\") i=str.indexOf(\"}\");\n else if (str.charAt(0)==\"(\") i=str.indexOf(\")\");\n else if (str.charAt(0)==\"[\") i=str.indexOf(\"]\");\n else if (symbol==AMquote) i=str.slice(1).indexOf(\"\\\"\")+1;\n else i = 0;\n if (i==-1) i = str.length;\n st = str.slice(1,i);\n if (st.charAt(0) == \" \") {\n node = AMcreateElementMathML(\"mspace\");\n node.setAttribute(\"width\",\"1ex\");\n newFrag.appendChild(node);\n }\n newFrag.appendChild(\n AMcreateMmlNode(symbol.tag,document.createTextNode(st)));\n if (st.charAt(st.length-1) == \" \") {\n node = AMcreateElementMathML(\"mspace\");\n node.setAttribute(\"width\",\"1ex\");\n newFrag.appendChild(node);\n }\n str = AMremoveCharsAndBlanks(str,i+1);\n return [AMcreateMmlNode(\"mrow\",newFrag),str];\n case UNARY:\n str = AMremoveCharsAndBlanks(str,symbol.input.length); \n result = AMparseSexpr(str);\n if (result[0]==null) return [AMcreateMmlNode(symbol.tag,\n document.createTextNode(symbol.output)),str];\n if (typeof symbol.func == \"boolean\" && symbol.func) { // functions hack\n st = str.charAt(0);\n if (st==\"^\" || st==\"_\" || st==\"/\" || st==\"|\" || st==\",\") {\n return [AMcreateMmlNode(symbol.tag,\n document.createTextNode(symbol.output)),str];\n } else {\n node = AMcreateMmlNode(\"mrow\",\n AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));\n node.appendChild(result[0]);\n return [node,result[1]];\n }\n }\n AMremoveBrackets(result[0]);\n if (symbol.input == \"sqrt\") { // sqrt\n return [AMcreateMmlNode(symbol.tag,result[0]),result[1]];\n } else if (typeof symbol.acc == \"boolean\" && symbol.acc) { // accent\n node = AMcreateMmlNode(symbol.tag,result[0]);\n node.appendChild(AMcreateMmlNode(\"mo\",document.createTextNode(symbol.output)));\n return [node,result[1]];\n } else { // font change command\n if (!isIE && typeof symbol.codes != \"undefined\") {\n for (i=0; i<result[0].childNodes.length; i++)\n if (result[0].childNodes[i].nodeName==\"mi\" || result[0].nodeName==\"mi\") {\n st = (result[0].nodeName==\"mi\"?result[0].firstChild.nodeValue:\n result[0].childNodes[i].firstChild.nodeValue);\n var newst = [];\n for (var j=0; j<st.length; j++)\n if (st.charCodeAt(j)>64 && st.charCodeAt(j)<91) newst = newst +\n String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]);\n else newst = newst + st.charAt(j);\n if (result[0].nodeName==\"mi\")\n result[0]=AMcreateElementMathML(\"mo\").\n appendChild(document.createTextNode(newst));\n else result[0].replaceChild(AMcreateElementMathML(\"mo\").\n appendChild(document.createTextNode(newst)),result[0].childNodes[i]);\n }\n }\n node = AMcreateMmlNode(symbol.tag,result[0]);\n node.setAttribute(symbol.atname,symbol.atval);\n return [node,result[1]];\n }\n case BINARY:\n str = AMremoveCharsAndBlanks(str,symbol.input.length); \n result = AMparseSexpr(str);\n if (result[0]==null) return [AMcreateMmlNode(\"mo\",\n document.createTextNode(symbol.input)),str];\n AMremoveBrackets(result[0]);\n var result2 = AMparseSexpr(result[1]);\n if (result2[0]==null) return [AMcreateMmlNode(\"mo\",\n document.createTextNode(symbol.input)),str];\n AMremoveBrackets(result2[0]);\n if (symbol.input==\"root\" || symbol.input==\"stackrel\") \n newFrag.appendChild(result2[0]);\n newFrag.appendChild(result[0]);\n if (symbol.input==\"frac\") newFrag.appendChild(result2[0]);\n return [AMcreateMmlNode(symbol.tag,newFrag),result2[1]];\n case INFIX:\n str = AMremoveCharsAndBlanks(str,symbol.input.length); \n return [AMcreateMmlNode(\"mo\",document.createTextNode(symbol.output)),str];\n case SPACE:\n str = AMremoveCharsAndBlanks(str,symbol.input.length); \n node = AMcreateElementMathML(\"mspace\");\n node.setAttribute(\"width\",\"1ex\");\n newFrag.appendChild(node);\n newFrag.appendChild(\n AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));\n node = AMcreateElementMathML(\"mspace\");\n node.setAttribute(\"width\",\"1ex\");\n newFrag.appendChild(node);\n return [AMcreateMmlNode(\"mrow\",newFrag),str];\n case LEFTRIGHT:\n// if (rightvert) return [null,str]; else rightvert = true;\n AMnestingDepth++;\n str = AMremoveCharsAndBlanks(str,symbol.input.length); \n result = AMparseExpr(str,false);\n AMnestingDepth--;\n var st = \"\";\n if (result[0].lastChild!=null)\n st = result[0].lastChild.firstChild.nodeValue;\n if (st == \"|\") { // its an absolute value subterm\n node = AMcreateMmlNode(\"mo\",document.createTextNode(symbol.output));\n node = AMcreateMmlNode(\"mrow\",node);\n node.appendChild(result[0]);\n return [node,result[1]];\n } else { // the \"|\" is a \\mid\n node = AMcreateMmlNode(\"mo\",document.createTextNode(symbol.output));\n node = AMcreateMmlNode(\"mrow\",node);\n return [node,str];\n }\n default:\n//alert(\"default\");\n str = AMremoveCharsAndBlanks(str,symbol.input.length); \n return [AMcreateMmlNode(symbol.tag, //its a constant\n document.createTextNode(symbol.output)),str];\n }\n}\n\nfunction AMparseIexpr(str) {\n var symbol, sym1, sym2, node, result, underover;\n str = AMremoveCharsAndBlanks(str,0);\n sym1 = AMgetSymbol(str);\n result = AMparseSexpr(str);\n node = result[0];\n str = result[1];\n symbol = AMgetSymbol(str);\n if (symbol.ttype == INFIX && symbol.input != \"/\") {\n str = AMremoveCharsAndBlanks(str,symbol.input.length);\n// if (symbol.input == \"/\") result = AMparseIexpr(str); else ...\n result = AMparseSexpr(str);\n if (result[0] == null) // show box in place of missing argument\n result[0] = AMcreateMmlNode(\"mo\",document.createTextNode(\"\\u25A1\"));\n else AMremoveBrackets(result[0]);\n str = result[1];\n// if (symbol.input == \"/\") AMremoveBrackets(node);\n if (symbol.input == \"_\") {\n sym2 = AMgetSymbol(str);\n underover = (sym1.ttype == UNDEROVER);\n if (sym2.input == \"^\") {\n str = AMremoveCharsAndBlanks(str,sym2.input.length);\n var res2 = AMparseSexpr(str);\n AMremoveBrackets(res2[0]);\n str = res2[1];\n node = AMcreateMmlNode((underover?\"munderover\":\"msubsup\"),node);\n node.appendChild(result[0]);\n node.appendChild(res2[0]);\n node = AMcreateMmlNode(\"mrow\",node); // so sum does not stretch\n } else {\n node = AMcreateMmlNode((underover?\"munder\":\"msub\"),node);\n node.appendChild(result[0]);\n }\n } else {\n node = AMcreateMmlNode(symbol.tag,node);\n node.appendChild(result[0]);\n }\n }\n return [node,str];\n}\n\nfunction AMparseExpr(str,rightbracket) {\n var symbol, node, result, i, nodeList = [],\n newFrag = document.createDocumentFragment();\n do {\n str = AMremoveCharsAndBlanks(str,0);\n result = AMparseIexpr(str);\n node = result[0];\n str = result[1];\n symbol = AMgetSymbol(str);\n if (symbol.ttype == INFIX && symbol.input == \"/\") {\n str = AMremoveCharsAndBlanks(str,symbol.input.length);\n result = AMparseIexpr(str);\n if (result[0] == null) // show box in place of missing argument\n result[0] = AMcreateMmlNode(\"mo\",document.createTextNode(\"\\u25A1\"));\n else AMremoveBrackets(result[0]);\n str = result[1];\n AMremoveBrackets(node);\n node = AMcreateMmlNode(symbol.tag,node);\n node.appendChild(result[0]);\n newFrag.appendChild(node);\n symbol = AMgetSymbol(str);\n } \n else if (node!=undefined) newFrag.appendChild(node);\n } while ((symbol.ttype != RIGHTBRACKET && \n (symbol.ttype != LEFTRIGHT || rightbracket)\n || AMnestingDepth == 0) && symbol!=null && symbol.output!=\"\");\n if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) {\n// if (AMnestingDepth > 0) AMnestingDepth--;\n var len = newFrag.childNodes.length;\n if (len>0 && newFrag.childNodes[len-1].nodeName == \"mrow\" && len>1 &&\n newFrag.childNodes[len-2].nodeName == \"mo\" &&\n newFrag.childNodes[len-2].firstChild.nodeValue == \",\") { //matrix\n var right = newFrag.childNodes[len-1].lastChild.firstChild.nodeValue;\n if (right==\")\" || right==\"]\") {\n var left = newFrag.childNodes[len-1].firstChild.firstChild.nodeValue;\n if (left==\"(\" && right==\")\" && symbol.output != \"}\" || \n left==\"[\" && right==\"]\") {\n var pos = []; // positions of commas\n var matrix = true;\n var m = newFrag.childNodes.length;\n for (i=0; matrix && i<m; i=i+2) {\n pos[i] = [];\n node = newFrag.childNodes[i];\n if (matrix) matrix = node.nodeName==\"mrow\" && \n (i==m-1 || node.nextSibling.nodeName==\"mo\" && \n node.nextSibling.firstChild.nodeValue==\",\")&&\n node.firstChild.firstChild.nodeValue==left &&\n node.lastChild.firstChild.nodeValue==right;\n if (matrix) \n for (var j=0; j<node.childNodes.length; j++)\n if (node.childNodes[j].firstChild.nodeValue==\",\")\n pos[i][pos[i].length]=j;\n if (matrix && i>1) matrix = pos[i].length == pos[i-2].length;\n }\n if (matrix) {\n var row, frag, n, k, table = document.createDocumentFragment();\n for (i=0; i<m; i=i+2) {\n row = document.createDocumentFragment();\n frag = document.createDocumentFragment();\n node = newFrag.firstChild; // <mrow>(-,-,...,-,-)</mrow>\n n = node.childNodes.length;\n k = 0;\n node.removeChild(node.firstChild); //remove (\n for (j=1; j<n-1; j++) {\n if (typeof pos[i][k] != \"undefined\" && j==pos[i][k]){\n node.removeChild(node.firstChild); //remove ,\n row.appendChild(AMcreateMmlNode(\"mtd\",frag));\n k++;\n } else frag.appendChild(node.firstChild);\n }\n row.appendChild(AMcreateMmlNode(\"mtd\",frag));\n if (newFrag.childNodes.length>2) {\n newFrag.removeChild(newFrag.firstChild); //remove <mrow>)</mrow>\n newFrag.removeChild(newFrag.firstChild); //remove <mo>,</mo>\n }\n table.appendChild(AMcreateMmlNode(\"mtr\",row));\n }\n node = AMcreateMmlNode(\"mtable\",table);\n if (typeof symbol.invisible == \"boolean\" && symbol.invisible) node.setAttribute(\"columnalign\",\"left\");\n newFrag.replaceChild(node,newFrag.firstChild);\n }\n }\n }\n }\n str = AMremoveCharsAndBlanks(str,symbol.input.length);\n if (typeof symbol.invisible != \"boolean\" || !symbol.invisible) {\n node = AMcreateMmlNode(\"mo\",document.createTextNode(symbol.output));\n newFrag.appendChild(node);\n }\n }\n return [newFrag,str];\n}\n\nfunction AMparseMath(str) {\n var result, node = AMcreateElementMathML(\"mstyle\");\n if (mathcolor != \"\") node.setAttribute(\"mathcolor\",mathcolor);\n if (displaystyle) node.setAttribute(\"displaystyle\",\"true\");\n if (mathfontfamily != \"\") node.setAttribute(\"fontfamily\",mathfontfamily);\n AMnestingDepth = 0;\n node.appendChild(AMparseExpr(str.replace(/^\\s+/g,\"\"),false)[0]);\n node = AMcreateMmlNode(\"math\",node);\n if (showasciiformulaonhover) //fixed by djhsu so newline\n node.setAttribute(\"title\",str.replace(/\\s+/g,\" \"));//does not show in Gecko\n if (mathfontfamily != \"\" && (isIE || mathfontfamily != \"serif\")) {\n var fnode = AMcreateElementXHTML(\"font\");\n fnode.setAttribute(\"face\",mathfontfamily);\n fnode.appendChild(node);\n return fnode;\n }\n return node;\n}\n\nfunction AMstrarr2docFrag(arr, linebreaks) {\n var newFrag=document.createDocumentFragment();\n var expr = false;\n for (var i=0; i<arr.length; i++) {\n if (expr) newFrag.appendChild(AMparseMath(arr[i]));\n else {\n var arri = (linebreaks ? arr[i].split(\"\\n\\n\") : [arr[i]]);\n newFrag.appendChild(AMcreateElementXHTML(\"span\").\n appendChild(document.createTextNode(arri[0])));\n for (var j=1; j<arri.length; j++) {\n newFrag.appendChild(AMcreateElementXHTML(\"p\"));\n newFrag.appendChild(AMcreateElementXHTML(\"span\").\n appendChild(document.createTextNode(arri[j])));\n }\n }\n expr = !expr;\n }\n return newFrag;\n}\n\nfunction AMprocessNodeR(n, linebreaks) {\n var mtch, str, arr, frg, i;\n if (n.childNodes.length == 0) {\n if ((n.nodeType!=8 || linebreaks) &&\n n.parentNode.nodeName!=\"form\" && n.parentNode.nodeName!=\"FORM\" &&\n n.parentNode.nodeName!=\"textarea\" && n.parentNode.nodeName!=\"TEXTAREA\" &&\n n.parentNode.nodeName!=\"code\" && n.parentNode.nodeName!=\"CODE\" && /* ASCIIMathML.js - copyright Peter Jipsen, released under the GPL\nSee http://www1.chapman.edu/~jipsen/mathml/asciimath.html/ */\n n.parentNode.nodeName!=\"pre\" && n.parentNode.nodeName!=\"PRE\") {\n str = n.nodeValue;\n if (!(str == null)) {\n str = str.replace(/\\r\\n\\r\\n/g,\"\\n\\n\");\n if (doubleblankmathdelimiter) {\n str = str.replace(/\\x20\\x20\\./g,\" \"+AMdelimiter1+\".\");\n str = str.replace(/\\x20\\x20,/g,\" \"+AMdelimiter1+\",\");\n str = str.replace(/\\x20\\x20/g,\" \"+AMdelimiter1+\" \");\n }\n str = str.replace(/\\x20+/g,\" \");\n str = str.replace(/\\s*\\r\\n/g,\" \");\n mtch = false;\n str = str.replace(new RegExp(AMescape2, \"g\"),\n function(st){mtch=true;return \"AMescape2\"});\n str = str.replace(new RegExp(AMescape1, \"g\"),\n function(st){mtch=true;return \"AMescape1\"});\n str = str.replace(new RegExp(AMdelimiter2regexp, \"g\"),AMdelimiter1);\n arr = str.split(AMdelimiter1);\n for (i=0; i<arr.length; i++)\n arr[i]=arr[i].replace(/AMescape2/g,AMdelimiter2).\n replace(/AMescape1/g,AMdelimiter1);\n if (arr.length>1 || mtch) {\n if (checkForMathML) {\n checkForMathML = false;\n var nd = AMisMathMLavailable();\n AMnoMathML = nd != null;\n if (AMnoMathML && notifyIfNoMathML) \n if (alertIfNoMathML)\n alert(\"To view the ASCIIMathML notation use Internet Explorer 6 +\\nMathPlayer (free from www.dessci.com)\\n\\\n or Firefox/Mozilla/Netscape\");\n else AMbody.insertBefore(nd,AMbody.childNodes[0]);\n }\n if (!AMnoMathML) {\n frg = AMstrarr2docFrag(arr,n.nodeType==8);\n var len = frg.childNodes.length;\n n.parentNode.replaceChild(frg,n);\n return len-1;\n } else return 0;\n }\n }\n } else return 0;\n } else if (n.nodeName!=\"math\") {\n for (i=0; i<n.childNodes.length; i++)\n i += AMprocessNodeR(n.childNodes[i], linebreaks);\n }\n return 0;\n}\n\nfunction AMprocessNode(n, linebreaks, spanclassAM) {\n var frag,st;\n if (spanclassAM!=null) {\n frag = document.getElementsByTagName(\"span\")\n for (var i=0;i<frag.length;i++)\n if (frag[i].className == \"AM\")\n AMprocessNodeR(frag[i],linebreaks);\n } else {\n try {\n st = n.innerHTML;\n } catch(err) {}\n if (st==null || \n st.indexOf(AMdelimiter1)!=-1 || st.indexOf(AMdelimiter2)!=-1) \n AMprocessNodeR(n,linebreaks);\n }\n if (isIE) { //needed to match size and font of formula to surrounding text\n frag = document.getElementsByTagName('math');\n for (var i=0;i<frag.length;i++) frag[i].update()\n }\n}\n\nvar AMbody;\nvar AMnoMathML = false, AMtranslated = false;\n\nfunction translate(spanclassAM) {\n if (!AMtranslated) { // run this only once\n AMtranslated = true;\n AMinitSymbols();\n AMbody = document.getElementsByTagName(\"body\")[0];\n AMprocessNode(AMbody, false, spanclassAM);\n }\n}\n\nif (isIE) { // avoid adding MathPlayer info explicitly to each webpage\n document.write(\"<object id=\\\"mathplayer\\\"\\\n classid=\\\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\\\"></object>\");\n document.write(\"<?import namespace=\\\"m\\\" implementation=\\\"#mathplayer\\\"?>\");\n}\n\n// GO1.1 Generic onload by Brothercake \n// http://www.brothercake.com/\n//onload function (replaces the onload=\"translate()\" in the <body> tag)\nfunction generic()\n{\n translate();\n};\n//setup onload function\nif(typeof window.addEventListener != 'undefined')\n{\n //.. gecko, safari, konqueror and standard\n window.addEventListener('load', generic, false);\n}\nelse if(typeof document.addEventListener != 'undefined')\n{\n //.. opera 7\n document.addEventListener('load', generic, false);\n}\nelse if(typeof window.attachEvent != 'undefined')\n{\n //.. win/ie\n window.attachEvent('onload', generic);\n}\n//** remove this condition to degrade older browsers\nelse\n{\n //.. mac/ie5 and anything else that gets this far\n //if there's an existing onload function\n if(typeof window.onload == 'function')\n {\n //store it\n var existing = onload;\n //add new onload handler\n window.onload = function()\n {\n //call existing onload function\n existing();\n //call generic onload function\n generic();\n };\n }\n else\n {\n //setup onload function\n window.onload = generic;\n }\n}\n</script>\n"+
+ src/Text/Pandoc/Blocks.hs view
@@ -0,0 +1,145 @@+{-+Copyright (C) 2007 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Blocks+ Copyright : Copyright (C) 2007 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Functions for the manipulation of fixed-width blocks of text.+These are used in the construction of plain-text tables.+-}++module Text.Pandoc.Blocks+ ( + TextBlock (..),+ docToBlock,+ blockToDoc,+ widthOfBlock,+ heightOfBlock,+ hcatBlocks,+ hsepBlocks,+ centerAlignBlock,+ leftAlignBlock,+ rightAlignBlock+ )+where+import Text.PrettyPrint+import Data.List ( intersperse )++-- | A fixed-width block of text. Parameters are width of block,+-- height of block, and list of lines.+data TextBlock = TextBlock Int Int [String]+instance Show TextBlock where+ show x = show $ blockToDoc x++-- | Break lines in a list of lines so that none are greater than+-- a given width.+breakLines :: Int -- ^ Maximum length of lines.+ -> [String] -- ^ List of lines.+ -> [String]+breakLines width [] = []+breakLines width (l:ls) =+ if length l > width+ then (take width l):(breakLines width ((drop width l):ls))+ else l:(breakLines width ls)++-- | Convert a @Doc@ element into a @TextBlock@ with a specified width. +docToBlock :: Int -- ^ Width of text block.+ -> Doc -- ^ @Doc@ to convert.+ -> TextBlock+docToBlock width doc =+ let rendered = renderStyle (style {lineLength = width, + ribbonsPerLine = 1}) doc+ lns = breakLines width $ lines rendered+ in TextBlock width (length lns) lns++-- | Convert a @TextBlock@ to a @Doc@ element.+blockToDoc :: TextBlock -> Doc+blockToDoc (TextBlock _ _ lns) = + if null lns+ then empty+ else vcat $ map text lns++-- | Returns width of a @TextBlock@ (number of columns).+widthOfBlock :: TextBlock -> Int+widthOfBlock (TextBlock width _ _) = width++-- | Returns height of a @TextBlock@ (number of rows).+heightOfBlock :: TextBlock -> Int+heightOfBlock (TextBlock _ height _) = height++-- | Pads a string out to a given width using spaces.+hPad :: Int -- ^ Desired width.+ -> String -- ^ String to pad.+ -> String+hPad width line = + let lineLength = length line+ in if lineLength <= width + then line ++ replicate (width - lineLength) ' '+ else take width line++-- | Concatenates a list of @TextBlock@s into a new @TextBlock@ in+-- which they appear side by side.+hcatBlocks :: [TextBlock] -> TextBlock+hcatBlocks [] = TextBlock 0 0 []+hcatBlocks [x] = x -- This is not redundant! We don't want last item hPad'd.+hcatBlocks ((TextBlock width1 height1 lns1):xs) = + let (TextBlock width2 height2 lns2) = hcatBlocks xs+ height = max height1 height2+ width = width1 + width2+ lns1' = map (hPad width1) $ lns1 ++ replicate (height - height1) ""+ lns2' = lns2 ++ replicate (height - height2) ""+ lns = zipWith (++) lns1' lns2'+ in TextBlock width height lns ++-- | Like @hcatBlocks@, but inserts space between the @TextBlock@s.+hsepBlocks :: [TextBlock] -> TextBlock+hsepBlocks = hcatBlocks . (intersperse (TextBlock 1 1 [" "]))++isWhitespace x = x `elem` " \t"++-- | Left-aligns the contents of a @TextBlock@ within the block.+leftAlignBlock :: TextBlock -> TextBlock+leftAlignBlock (TextBlock width height lns) =+ TextBlock width height $ map (dropWhile isWhitespace) lns++-- | Right-aligns the contents of a @TextBlock@ within the block.+rightAlignBlock :: TextBlock -> TextBlock+rightAlignBlock (TextBlock width height lns) =+ let rightAlignLine ln = + let (spaces, rest) = span isWhitespace $ reverse $ hPad width ln+ in reverse (rest ++ spaces)+ in TextBlock width height $ map rightAlignLine lns++-- | Centers the contents of a @TextBlock@ within the block.+centerAlignBlock :: TextBlock -> TextBlock+centerAlignBlock (TextBlock width height lns) = + let centerAlignLine ln =+ let ln' = hPad width ln+ (startSpaces, rest) = span isWhitespace ln'+ endSpaces = takeWhile isWhitespace (reverse ln')+ numSpaces = length (startSpaces ++ endSpaces)+ startSpaces' = replicate (quot numSpaces 2) ' '+ in startSpaces' ++ rest + in TextBlock width height $ map centerAlignLine lns+
+ src/Text/Pandoc/CharacterReferences.hs view
@@ -0,0 +1,335 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.CharacterReferences+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Functions for parsing character references.+-}+module Text.Pandoc.CharacterReferences (+ characterReference,+ decodeCharacterReferences,+ ) where+import Data.Char ( chr )+import Text.ParserCombinators.Parsec+import qualified Data.Map as Map++-- | Parse character entity.+characterReference :: GenParser Char st Char+characterReference = characterEntity <|> + hexadecimalCharacterReference <|> + decimalCharacterReference <?> + "character entity"++-- | Parse character entity.+characterEntity :: GenParser Char st Char+characterEntity = try $ do+ st <- char '&'+ body <- many1 alphaNum+ end <- char ';'+ let entity = "&" ++ body ++ ";"+ return $ Map.findWithDefault '?' entity entityTable+ +-- | Parse hexadecimal entity.+hexadecimalCharacterReference :: GenParser Char st Char+hexadecimalCharacterReference = try $ do+ st <- string "&#"+ hex <- oneOf "Xx"+ body <- many1 (oneOf "0123456789ABCDEFabcdef")+ end <- char ';'+ return $ chr $ read ('0':'x':body)++-- | Parse decimal entity.+decimalCharacterReference :: GenParser Char st Char+decimalCharacterReference = try $ do+ st <- string "&#"+ body <- many1 digit+ end <- char ';'+ return $ chr $ read body++-- | Convert entities in a string to characters.+decodeCharacterReferences :: String -> String+decodeCharacterReferences str = + case parse (many (characterReference <|> anyChar)) str str of+ Left err -> error $ "\nError: " ++ show err+ Right result -> result++entityTable :: Map.Map String Char+entityTable = Map.fromList entityTableList++entityTableList :: [(String, Char)]+entityTableList = [+ (""", chr 34),+ ("&", chr 38),+ ("<", chr 60),+ (">", chr 62),+ (" ", chr 160),+ ("¡", chr 161),+ ("¢", chr 162),+ ("£", chr 163),+ ("¤", chr 164),+ ("¥", chr 165),+ ("¦", chr 166),+ ("§", chr 167),+ ("¨", chr 168),+ ("©", chr 169),+ ("ª", chr 170),+ ("«", chr 171),+ ("¬", chr 172),+ ("­", chr 173),+ ("®", chr 174),+ ("¯", chr 175),+ ("°", chr 176),+ ("±", chr 177),+ ("²", chr 178),+ ("³", chr 179),+ ("´", chr 180),+ ("µ", chr 181),+ ("¶", chr 182),+ ("·", chr 183),+ ("¸", chr 184),+ ("¹", chr 185),+ ("º", chr 186),+ ("»", chr 187),+ ("¼", chr 188),+ ("½", chr 189),+ ("¾", chr 190),+ ("¿", chr 191),+ ("À", chr 192),+ ("Á", chr 193),+ ("Â", chr 194),+ ("Ã", chr 195),+ ("Ä", chr 196),+ ("Å", chr 197),+ ("Æ", chr 198),+ ("Ç", chr 199),+ ("È", chr 200),+ ("É", chr 201),+ ("Ê", chr 202),+ ("Ë", chr 203),+ ("Ì", chr 204),+ ("Í", chr 205),+ ("Î", chr 206),+ ("Ï", chr 207),+ ("Ð", chr 208),+ ("Ñ", chr 209),+ ("Ò", chr 210),+ ("Ó", chr 211),+ ("Ô", chr 212),+ ("Õ", chr 213),+ ("Ö", chr 214),+ ("×", chr 215),+ ("Ø", chr 216),+ ("Ù", chr 217),+ ("Ú", chr 218),+ ("Û", chr 219),+ ("Ü", chr 220),+ ("Ý", chr 221),+ ("Þ", chr 222),+ ("ß", chr 223),+ ("à", chr 224),+ ("á", chr 225),+ ("â", chr 226),+ ("ã", chr 227),+ ("ä", chr 228),+ ("å", chr 229),+ ("æ", chr 230),+ ("ç", chr 231),+ ("è", chr 232),+ ("é", chr 233),+ ("ê", chr 234),+ ("ë", chr 235),+ ("ì", chr 236),+ ("í", chr 237),+ ("î", chr 238),+ ("ï", chr 239),+ ("ð", chr 240),+ ("ñ", chr 241),+ ("ò", chr 242),+ ("ó", chr 243),+ ("ô", chr 244),+ ("õ", chr 245),+ ("ö", chr 246),+ ("÷", chr 247),+ ("ø", chr 248),+ ("ù", chr 249),+ ("ú", chr 250),+ ("û", chr 251),+ ("ü", chr 252),+ ("ý", chr 253),+ ("þ", chr 254),+ ("ÿ", chr 255),+ ("Œ", chr 338),+ ("œ", chr 339),+ ("Š", chr 352),+ ("š", chr 353),+ ("Ÿ", chr 376),+ ("ƒ", chr 402),+ ("ˆ", chr 710),+ ("˜", chr 732),+ ("Α", chr 913),+ ("Β", chr 914),+ ("Γ", chr 915),+ ("Δ", chr 916),+ ("Ε", chr 917),+ ("Ζ", chr 918),+ ("Η", chr 919),+ ("Θ", chr 920),+ ("Ι", chr 921),+ ("Κ", chr 922),+ ("Λ", chr 923),+ ("Μ", chr 924),+ ("Ν", chr 925),+ ("Ξ", chr 926),+ ("Ο", chr 927),+ ("Π", chr 928),+ ("Ρ", chr 929),+ ("Σ", chr 931),+ ("Τ", chr 932),+ ("Υ", chr 933),+ ("Φ", chr 934),+ ("Χ", chr 935),+ ("Ψ", chr 936),+ ("Ω", chr 937),+ ("α", chr 945),+ ("β", chr 946),+ ("γ", chr 947),+ ("δ", chr 948),+ ("ε", chr 949),+ ("ζ", chr 950),+ ("η", chr 951),+ ("θ", chr 952),+ ("ι", chr 953),+ ("κ", chr 954),+ ("λ", chr 955),+ ("μ", chr 956),+ ("ν", chr 957),+ ("ξ", chr 958),+ ("ο", chr 959),+ ("π", chr 960),+ ("ρ", chr 961),+ ("ς", chr 962),+ ("σ", chr 963),+ ("τ", chr 964),+ ("υ", chr 965),+ ("φ", chr 966),+ ("χ", chr 967),+ ("ψ", chr 968),+ ("ω", chr 969),+ ("ϑ", chr 977),+ ("ϒ", chr 978),+ ("ϖ", chr 982),+ (" ", chr 8194),+ (" ", chr 8195),+ (" ", chr 8201),+ ("‌", chr 8204),+ ("‍", chr 8205),+ ("‎", chr 8206),+ ("‏", chr 8207),+ ("–", chr 8211),+ ("—", chr 8212),+ ("‘", chr 8216),+ ("’", chr 8217),+ ("‚", chr 8218),+ ("“", chr 8220),+ ("”", chr 8221),+ ("„", chr 8222),+ ("†", chr 8224),+ ("‡", chr 8225),+ ("•", chr 8226),+ ("…", chr 8230),+ ("‰", chr 8240),+ ("′", chr 8242),+ ("″", chr 8243),+ ("‹", chr 8249),+ ("›", chr 8250),+ ("‾", chr 8254),+ ("⁄", chr 8260),+ ("€", chr 8364),+ ("ℑ", chr 8465),+ ("℘", chr 8472),+ ("ℜ", chr 8476),+ ("™", chr 8482),+ ("ℵ", chr 8501),+ ("←", chr 8592),+ ("↑", chr 8593),+ ("→", chr 8594),+ ("↓", chr 8595),+ ("↔", chr 8596),+ ("↵", chr 8629),+ ("⇐", chr 8656),+ ("⇑", chr 8657),+ ("⇒", chr 8658),+ ("⇓", chr 8659),+ ("⇔", chr 8660),+ ("∀", chr 8704),+ ("∂", chr 8706),+ ("∃", chr 8707),+ ("∅", chr 8709),+ ("∇", chr 8711),+ ("∈", chr 8712),+ ("∉", chr 8713),+ ("∋", chr 8715),+ ("∏", chr 8719),+ ("∑", chr 8721),+ ("−", chr 8722),+ ("∗", chr 8727),+ ("√", chr 8730),+ ("∝", chr 8733),+ ("∞", chr 8734),+ ("∠", chr 8736),+ ("∧", chr 8743),+ ("∨", chr 8744),+ ("∩", chr 8745),+ ("∪", chr 8746),+ ("∫", chr 8747),+ ("∴", chr 8756),+ ("∼", chr 8764),+ ("≅", chr 8773),+ ("≈", chr 8776),+ ("≠", chr 8800),+ ("≡", chr 8801),+ ("≤", chr 8804),+ ("≥", chr 8805),+ ("⊂", chr 8834),+ ("⊃", chr 8835),+ ("⊄", chr 8836),+ ("⊆", chr 8838),+ ("⊇", chr 8839),+ ("⊕", chr 8853),+ ("⊗", chr 8855),+ ("⊥", chr 8869),+ ("⋅", chr 8901),+ ("⌈", chr 8968),+ ("⌉", chr 8969),+ ("⌊", chr 8970),+ ("⌋", chr 8971),+ ("⟨", chr 9001),+ ("⟩", chr 9002),+ ("◊", chr 9674),+ ("♠", chr 9824),+ ("♣", chr 9827),+ ("♥", chr 9829),+ ("♦", chr 9830)+ ]
+ src/Text/Pandoc/Definition.hs view
@@ -0,0 +1,116 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Definition+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Definition of 'Pandoc' data structure for format-neutral representation+of documents.+-}+module Text.Pandoc.Definition where++data Pandoc = Pandoc Meta [Block] deriving (Eq, Read, Show)++-- | Bibliographic information for the document: title (list of 'Inline'),+-- authors (list of strings), date (string).+data Meta = Meta [Inline] -- title+ [String] -- authors+ String -- date+ deriving (Eq, Show, Read)++-- | Alignment of a table column.+data Alignment = AlignLeft + | AlignRight + | AlignCenter + | AlignDefault deriving (Eq, Show, Read)++-- | List attributes.+type ListAttributes = (Int, ListNumberStyle, ListNumberDelim)++-- | Style of list numbers.+data ListNumberStyle = DefaultStyle+ | Decimal + | LowerRoman + | UpperRoman+ | LowerAlpha + | UpperAlpha deriving (Eq, Show, Read)++-- | Delimiter of list numbers.+data ListNumberDelim = DefaultDelim+ | Period+ | OneParen + | TwoParens deriving (Eq, Show, Read)+ +-- | Block element.+data Block + = Plain [Inline] -- ^ Plain text, not a paragraph+ | Para [Inline] -- ^ Paragraph+ | CodeBlock String -- ^ Code block (literal)+ | RawHtml String -- ^ Raw HTML block (literal)+ | BlockQuote [Block] -- ^ Block quote (list of blocks)+ | OrderedList ListAttributes [[Block]] -- ^ Ordered list (attributes+ -- and a list of items, each a list of blocks)+ | BulletList [[Block]] -- ^ Bullet list (list of items, each+ -- a list of blocks)+ | DefinitionList [([Inline],[Block])] -- ^ Definition list + -- (list of items, each a pair of an inline list,+ -- the term, and a block list)+ | Header Int [Inline] -- ^ Header - level (integer) and text (inlines) + | HorizontalRule -- ^ Horizontal rule+ | Table [Inline] [Alignment] [Float] [[Block]] [[[Block]]] -- ^ Table,+ -- with caption, column alignments,+ -- relative column widths, column headers+ -- (each a list of blocks), and rows+ -- (each a list of lists of blocks)+ | Null -- ^ Nothing+ deriving (Eq, Read, Show)++-- | Type of quotation marks to use in Quoted inline.+data QuoteType = SingleQuote | DoubleQuote deriving (Show, Eq, Read)++type Target = (String, String) -- ^ Link target (URL, title)++-- | Inline elements.+data Inline + = Str String -- ^ Text (string)+ | Emph [Inline] -- ^ Emphasized text (list of inlines)+ | Strong [Inline] -- ^ Strongly emphasized text (list of inlines)+ | Strikeout [Inline] -- ^ Strikeout text (list of inlines)+ | Superscript [Inline] -- ^ Superscripted text (list of inlines)+ | Subscript [Inline] -- ^ Subscripted text (list of inlines)+ | Quoted QuoteType [Inline] -- ^ Quoted text (list of inlines)+ | Code String -- ^ Inline code (literal)+ | Space -- ^ Inter-word space+ | EmDash -- ^ Em dash+ | EnDash -- ^ En dash+ | Apostrophe -- ^ Apostrophe+ | Ellipses -- ^ Ellipses+ | LineBreak -- ^ Hard line break+ | TeX String -- ^ LaTeX code (literal)+ | HtmlInline String -- ^ HTML code (literal)+ | Link [Inline] Target -- ^ Hyperlink: text (list of inlines), target+ | Image [Inline] Target -- ^ Image: alt text (list of inlines), target+ -- and target+ | Note [Block] -- ^ Footnote or endnote + deriving (Show, Eq, Read)
+ src/Text/Pandoc/Readers/HTML.hs view
@@ -0,0 +1,486 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Readers.HTML+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha + Portability : portable++Conversion of HTML to 'Pandoc' document.+-}+module Text.Pandoc.Readers.HTML ( + readHtml, + rawHtmlInline, + rawHtmlBlock, + anyHtmlBlockTag, + anyHtmlInlineTag, + anyHtmlTag,+ anyHtmlEndTag,+ htmlEndTag,+ extractTagType,+ htmlBlockElement + ) where++import Text.ParserCombinators.Parsec+import Text.Pandoc.Definition+import Text.Pandoc.Shared +import Text.Pandoc.CharacterReferences ( characterReference, + decodeCharacterReferences )+import Data.Maybe ( fromMaybe )+import Data.List ( takeWhile, dropWhile )+import Data.Char ( toUpper, toLower, isAlphaNum )++-- | Convert HTML-formatted string to 'Pandoc' document.+readHtml :: ParserState -- ^ Parser state+ -> String -- ^ String to parse+ -> Pandoc+readHtml = readWith parseHtml++--+-- Constants+--++inlineHtmlTags = ["a", "abbr", "acronym", "b", "basefont", "bdo", "big",+ "br", "cite", "code", "dfn", "em", "font", "i", "img",+ "input", "kbd", "label", "q", "s", "samp", "select",+ "small", "span", "strike", "strong", "sub", "sup",+ "textarea", "tt", "u", "var"]++--+-- HTML utility functions+--++-- | Read blocks until end tag.+blocksTilEnd tag = do+ blocks <- manyTill (block >>~ spaces) (htmlEndTag tag)+ return $ filter (/= Null) blocks++-- | Read inlines until end tag.+inlinesTilEnd tag = manyTill inline (htmlEndTag tag)++-- | Parse blocks between open and close tag.+blocksIn tag = try $ htmlTag tag >> spaces >> blocksTilEnd tag++-- | Parse inlines between open and close tag.+inlinesIn tag = try $ htmlTag tag >> spaces >> inlinesTilEnd tag++-- | Extract type from a tag: e.g. @br@ from @\<br\>@+extractTagType :: String -> String+extractTagType ('<':rest) = + let isSpaceOrSlash c = c `elem` "/ \n\t" in+ map toLower $ takeWhile isAlphaNum $ dropWhile isSpaceOrSlash rest+extractTagType _ = ""++-- | Parse any HTML tag (closing or opening) and return text of tag+anyHtmlTag = try $ do+ char '<'+ spaces+ tag <- many1 alphaNum+ attribs <- htmlAttributes+ spaces+ ender <- option "" (string "/")+ let ender' = if null ender then "" else " /"+ spaces+ char '>'+ return $ "<" ++ tag ++ attribs ++ ender' ++ ">"++anyHtmlEndTag = try $ do+ char '<' + spaces+ char '/'+ spaces+ tagType <- many1 alphaNum+ spaces+ char '>'+ return $ "</" ++ tagType ++ ">"++htmlTag :: String -> GenParser Char st (String, [(String, String)])+htmlTag tag = try $ do+ char '<'+ spaces+ stringAnyCase tag+ attribs <- many htmlAttribute+ spaces+ optional (string "/")+ spaces+ char '>'+ return (tag, (map (\(name, content, raw) -> (name, content)) attribs))++-- parses a quoted html attribute value+quoted quoteChar = do+ result <- between (char quoteChar) (char quoteChar) + (many (noneOf [quoteChar]))+ return (result, [quoteChar])++htmlAttributes = do+ attrList <- many htmlAttribute+ return $ concatMap (\(name, content, raw) -> raw) attrList++htmlAttribute = htmlRegularAttribute <|> htmlMinimizedAttribute++-- minimized boolean attribute+htmlMinimizedAttribute = try $ do+ many1 space+ name <- many1 (choice [letter, oneOf ".-_:"])+ spaces+ notFollowedBy (char '=')+ let content = name+ return (name, content, (" " ++ name))++htmlRegularAttribute = try $ do+ many1 space+ name <- many1 (choice [letter, oneOf ".-_:"])+ spaces+ char '='+ spaces+ (content, quoteStr) <- choice [ (quoted '\''), + (quoted '"'), + (do+ a <- many (alphaNum <|> (oneOf "-._:"))+ return (a,"")) ]+ return (name, content,+ (" " ++ name ++ "=" ++ quoteStr ++ content ++ quoteStr))++-- | Parse an end tag of type 'tag'+htmlEndTag tag = try $ do+ char '<' + spaces+ char '/'+ spaces+ stringAnyCase tag+ spaces+ char '>'+ return $ "</" ++ tag ++ ">"++-- | Returns @True@ if the tag is an inline tag.+isInline tag = (extractTagType tag) `elem` inlineHtmlTags++anyHtmlBlockTag = try $ do+ tag <- anyHtmlTag <|> anyHtmlEndTag+ if isInline tag then fail "inline tag" else return tag++anyHtmlInlineTag = try $ do+ tag <- anyHtmlTag <|> anyHtmlEndTag+ if isInline tag then return tag else fail "not an inline tag"++-- | Parses material between script tags.+-- Scripts must be treated differently, because they can contain '<>' etc.+htmlScript = try $ do+ open <- string "<script"+ rest <- manyTill anyChar (htmlEndTag "script")+ return $ open ++ rest ++ "</script>"++htmlBlockElement = choice [ htmlScript, htmlComment, xmlDec, definition ]++rawHtmlBlock = try $ do+ notFollowedBy' (htmlTag "/body" <|> htmlTag "/html")+ body <- htmlBlockElement <|> anyHtmlBlockTag+ sp <- many space+ state <- getState+ if stateParseRaw state then return (RawHtml (body ++ sp)) else return Null++-- | Parses an HTML comment.+htmlComment = try $ do+ string "<!--"+ comment <- manyTill anyChar (try (string "-->"))+ return $ "<!--" ++ comment ++ "-->"++--+-- parsing documents+--++xmlDec = try $ do+ string "<?"+ rest <- manyTill anyChar (char '>')+ return $ "<?" ++ rest ++ ">"++definition = try $ do+ string "<!"+ rest <- manyTill anyChar (char '>')+ return $ "<!" ++ rest ++ ">"++nonTitleNonHead = try $ notFollowedBy' (htmlTag "title" <|> htmlTag "/head") >>+ ((rawHtmlBlock >> return ' ') <|> anyChar)++parseTitle = try $ do+ (tag, _) <- htmlTag "title"+ contents <- inlinesTilEnd tag+ spaces+ return contents++-- parse header and return meta-information (for now, just title)+parseHead = try $ do+ htmlTag "head"+ spaces+ skipMany nonTitleNonHead+ contents <- option [] parseTitle+ skipMany nonTitleNonHead+ htmlTag "/head"+ return (contents, [], "")++skipHtmlTag tag = optional (htmlTag tag)++-- h1 class="title" representation of title in body+bodyTitle = try $ do+ (tag, attribs) <- htmlTag "h1" + cl <- case (extractAttribute "class" attribs) of+ Just "title" -> return ""+ otherwise -> fail "not title"+ inlinesTilEnd "h1"++parseHtml = do+ sepEndBy (choice [xmlDec, definition, htmlComment]) spaces+ skipHtmlTag "html"+ spaces+ (title, authors, date) <- option ([], [], "") parseHead + spaces+ skipHtmlTag "body"+ spaces+ optional bodyTitle -- skip title in body, because it's represented in meta+ blocks <- parseBlocks+ spaces+ optional (htmlEndTag "body")+ spaces+ optional (htmlEndTag "html")+ many anyChar -- ignore anything after </html>+ eof+ return $ Pandoc (Meta title authors date) blocks++--+-- parsing blocks+--++parseBlocks = spaces >> sepEndBy block spaces >>= (return . filter (/= Null))++block = choice [ codeBlock+ , header+ , hrule+ , list+ , blockQuote+ , para+ , plain+ , rawHtmlBlock ] <?> "block"++--+-- header blocks+--++header = choice (map headerLevel (enumFromTo 1 5)) <?> "header"++headerLevel n = try $ do+ let level = "h" ++ show n+ (tag, attribs) <- htmlTag level+ contents <- inlinesTilEnd level+ return $ Header n (normalizeSpaces contents)++--+-- hrule block+--++hrule = try $ do+ (tag, attribs) <- htmlTag "hr"+ state <- getState+ if not (null attribs) && stateParseRaw state+ then unexpected "attributes in hr" -- parse as raw in this case+ else return HorizontalRule++--+-- code blocks+--++codeBlock = preCodeBlock <|> bareCodeBlock <?> "code block"++preCodeBlock = try $ do+ htmlTag "pre" + spaces+ result <- bareCodeBlock+ spaces+ htmlEndTag "pre"+ return result++bareCodeBlock = try $ do+ htmlTag "code"+ result <- manyTill anyChar (htmlEndTag "code")+ return $ CodeBlock $ stripTrailingNewlines $ + decodeCharacterReferences result++--+-- block quotes+--++blockQuote = try $ htmlTag "blockquote" >> spaces >> + blocksTilEnd "blockquote" >>= (return . BlockQuote)++--+-- list blocks+--++list = choice [ bulletList, orderedList, definitionList ] <?> "list"++orderedList = try $ do+ (_, attribs) <- htmlTag "ol"+ (start, style) <- option (1, DefaultStyle) $+ do failIfStrict+ let sta = fromMaybe "1" $ + lookup "start" attribs+ let sty = fromMaybe (fromMaybe "" $+ lookup "style" attribs) $+ lookup "class" attribs+ let sty' = case sty of+ "lower-roman" -> LowerRoman+ "upper-roman" -> UpperRoman+ "lower-alpha" -> LowerAlpha+ "upper-alpha" -> UpperAlpha+ "decimal" -> Decimal+ _ -> DefaultStyle+ return (read sta, sty')+ spaces+ items <- sepEndBy1 (blocksIn "li") spaces+ htmlEndTag "ol"+ return $ OrderedList (start, style, DefaultDelim) items++bulletList = try $ do+ htmlTag "ul"+ spaces+ items <- sepEndBy1 (blocksIn "li") spaces+ htmlEndTag "ul"+ return $ BulletList items++definitionList = try $ do+ failIfStrict -- def lists not part of standard markdown+ tag <- htmlTag "dl"+ spaces+ items <- sepEndBy1 definitionListItem spaces+ htmlEndTag "dl"+ return $ DefinitionList items++definitionListItem = try $ do+ terms <- sepEndBy1 (inlinesIn "dt") spaces+ defs <- sepEndBy1 (blocksIn "dd") spaces+ let term = joinWithSep [LineBreak] terms+ return (term, concat defs)++--+-- paragraph block+--++para = htmlTag "p" >> inlinesTilEnd "p" >>= return . Para . normalizeSpaces++-- +-- plain block+--++plain = many1 inline >>= return . Plain . normalizeSpaces++-- +-- inline+--++inline = choice [ charRef+ , strong+ , emph+ , superscript+ , subscript+ , strikeout+ , spanStrikeout+ , code+ , str+ , linebreak+ , whitespace+ , link+ , image+ , rawHtmlInline+ ] <?> "inline"++code = try $ do + htmlTag "code"+ result <- manyTill anyChar (htmlEndTag "code")+ -- remove internal line breaks, leading and trailing space,+ -- and decode character references+ return $ Code $ decodeCharacterReferences $ removeLeadingTrailingSpace $ + joinWithSep " " $ lines result ++rawHtmlInline = do+ result <- htmlScript <|> htmlComment <|> anyHtmlInlineTag+ state <- getState+ if stateParseRaw state then return (HtmlInline result) else return (Str "")++betweenTags tag = try $ htmlTag tag >> inlinesTilEnd tag >>= + return . normalizeSpaces++emph = (betweenTags "em" <|> betweenTags "it") >>= return . Emph++strong = (betweenTags "b" <|> betweenTags "strong") >>= return . Strong++superscript = failIfStrict >> betweenTags "sup" >>= return . Superscript++subscript = failIfStrict >> betweenTags "sub" >>= return . Subscript++strikeout = failIfStrict >> (betweenTags "s" <|> betweenTags "strike") >>=+ return . Strikeout++spanStrikeout = try $ do+ failIfStrict -- strict markdown has no strikeout, so treat as raw HTML+ (tag, attributes) <- htmlTag "span" + result <- case (extractAttribute "class" attributes) of+ Just "strikeout" -> inlinesTilEnd "span"+ _ -> fail "not a strikeout"+ return $ Strikeout result++whitespace = many1 space >> return Space++-- hard line break+linebreak = htmlTag "br" >> optional newline >> return LineBreak++str = many1 (noneOf "<& \t\n") >>= return . Str++--+-- links and images+--++-- extract contents of attribute (attribute names are case-insensitive)+extractAttribute name [] = Nothing+extractAttribute name ((attrName, contents):rest) = + let name' = map toLower name + attrName' = map toLower attrName+ in if attrName' == name'+ then Just (decodeCharacterReferences contents)+ else extractAttribute name rest++link = try $ do+ (tag, attributes) <- htmlTag "a" + url <- case (extractAttribute "href" attributes) of+ Just url -> return url+ Nothing -> fail "no href"+ let title = fromMaybe "" $ extractAttribute "title" attributes+ label <- inlinesTilEnd "a"+ return $ Link (normalizeSpaces label) (url, title)++image = try $ do+ (tag, attributes) <- htmlTag "img" + url <- case (extractAttribute "src" attributes) of+ Just url -> return url+ Nothing -> fail "no src"+ let title = fromMaybe "" $ extractAttribute "title" attributes+ let alt = fromMaybe "" (extractAttribute "alt" attributes)+ return $ Image [Str alt] (url, title)+
+ src/Text/Pandoc/Readers/LaTeX.hs view
@@ -0,0 +1,648 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Readers.LaTeX+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of LaTeX to 'Pandoc' document.+-}+module Text.Pandoc.Readers.LaTeX ( + readLaTeX,+ rawLaTeXInline,+ rawLaTeXEnvironment+ ) where++import Text.ParserCombinators.Parsec+import Text.Pandoc.Definition+import Text.Pandoc.Shared +import Data.Maybe ( fromMaybe )+import Data.Char ( chr )+import Data.List ( isPrefixOf, isSuffixOf )++-- | Parse LaTeX from string and return 'Pandoc' document.+readLaTeX :: ParserState -- ^ Parser state, including options for parser+ -> String -- ^ String to parse+ -> Pandoc+readLaTeX = readWith parseLaTeX++-- characters with special meaning+specialChars = "\\$%^&_~#{}\n \t|<>'\"-"++--+-- utility functions+--++-- | Returns text between brackets and its matching pair.+bracketedText openB closeB = do+ result <- charsInBalanced' openB closeB+ return $ [openB] ++ result ++ [closeB]++-- | Returns an option or argument of a LaTeX command.+optOrArg = bracketedText '{' '}' <|> bracketedText '[' ']'++-- | True if the string begins with '{'.+isArg ('{':rest) = True+isArg other = False++-- | Returns list of options and arguments of a LaTeX command.+commandArgs = many optOrArg++-- | Parses LaTeX command, returns (name, star, list of options or arguments).+command = try $ do+ char '\\'+ name <- many1 alphaNum+ star <- option "" (string "*") -- some commands have starred versions+ args <- commandArgs+ return (name, star, args)++begin name = try $ do+ string $ "\\begin{" ++ name ++ "}"+ optional commandArgs+ spaces+ return name++end name = try $ do+ string $ "\\end{" ++ name ++ "}"+ spaces+ return name++-- | Returns a list of block elements containing the contents of an+-- environment.+environment name = try $ begin name >> spaces >> manyTill block (end name)++anyEnvironment = try $ do+ string "\\begin{"+ name <- many alphaNum + star <- option "" (string "*") -- some environments have starred variants+ char '}'+ optional commandArgs+ spaces+ contents <- manyTill block (end (name ++ star))+ return $ BlockQuote contents++--+-- parsing documents+--++-- | Process LaTeX preamble, extracting metadata.+processLaTeXPreamble = try $ manyTill + (choice [bibliographic, comment, unknownCommand, nullBlock]) + (try (string "\\begin{document}")) >> + spaces++-- | Parse LaTeX and return 'Pandoc'.+parseLaTeX = do+ optional processLaTeXPreamble -- preamble might not be present (fragment)+ spaces+ blocks <- parseBlocks+ spaces+ optional $ try (string "\\end{document}") -- might not be present (fragment)+ spaces+ eof+ state <- getState+ let blocks' = filter (/= Null) blocks+ let title' = stateTitle state+ let authors' = stateAuthors state+ let date' = stateDate state+ return $ Pandoc (Meta title' authors' date') blocks'++--+-- parsing blocks+--++parseBlocks = spaces >> many block++block = choice [ hrule+ , codeBlock+ , header+ , list+ , blockQuote+ , mathBlock+ , comment+ , bibliographic+ , para+ , specialEnvironment+ , itemBlock+ , unknownEnvironment+ , unknownCommand ] <?> "block"++--+-- header blocks+--++header = choice (map headerLevel (enumFromTo 1 5)) <?> "header"++headerLevel n = try $ do+ let subs = concat $ replicate (n - 1) "sub"+ string ("\\" ++ subs ++ "section")+ optional (char '*')+ char '{'+ title <- manyTill inline (char '}')+ spaces+ return $ Header n (normalizeSpaces title)++--+-- hrule block+--++hrule = oneOfStrings [ "\\begin{center}\\rule{3in}{0.4pt}\\end{center}\n\n", + "\\newpage" ] >> spaces >> return HorizontalRule++--+-- code blocks+--++codeBlock = codeBlock1 <|> codeBlock2++codeBlock1 = try $ do+ string "\\begin{verbatim}" -- don't use begin function because it + -- gobbles whitespace+ optional blanklines -- we want to gobble blank lines, but not + -- leading space+ contents <- manyTill anyChar (try (string "\\end{verbatim}"))+ spaces+ return $ CodeBlock (stripTrailingNewlines contents)++codeBlock2 = try $ do+ string "\\begin{Verbatim}" -- used by fancyvrb package+ option "" blanklines+ contents <- manyTill anyChar (try (string "\\end{Verbatim}"))+ spaces+ return $ CodeBlock (stripTrailingNewlines contents)++--+-- block quotes+--++blockQuote = (environment "quote" <|> environment "quotation") >>~ spaces >>= + return . BlockQuote++--+-- math block+--++mathBlock = mathBlockWith (begin "equation") (end "equation") <|> + mathBlockWith (begin "displaymath") (end "displaymath") <|>+ mathBlockWith (string "\\[") (string "\\]") <?> "math block"++mathBlockWith start end = try $ do+ start+ spaces+ result <- manyTill anyChar end+ spaces+ return $ BlockQuote [Para [TeX ("$" ++ result ++ "$")]]++--+-- list blocks+--++list = bulletList <|> orderedList <|> definitionList <?> "list"++listItem = try $ do+ ("item", _, args) <- command+ spaces+ state <- getState+ let oldParserContext = stateParserContext state+ updateState (\state -> state {stateParserContext = ListItemState})+ blocks <- many block+ updateState (\state -> state {stateParserContext = oldParserContext})+ opt <- case args of+ ([x]) | "[" `isPrefixOf` x && "]" `isSuffixOf` x -> + parseFromString (many inline) $ tail $ init x+ _ -> return []+ return (opt, blocks)++orderedList = try $ do+ string "\\begin{enumerate}"+ (_, style, delim) <- option (1, DefaultStyle, DefaultDelim) $+ try $ do failIfStrict+ char '['+ res <- anyOrderedListMarker+ char ']'+ return res+ spaces+ option "" $ try $ do string "\\setlength{\\itemindent}"+ char '{'+ manyTill anyChar (char '}')+ spaces+ start <- option 1 $ try $ do failIfStrict+ string "\\setcounter{enum"+ many1 (char 'i')+ string "}{"+ num <- many1 digit+ char '}' + spaces+ return $ (read num) + 1+ items <- many listItem+ end "enumerate"+ spaces+ return $ OrderedList (start, style, delim) $ map snd items++bulletList = try $ do+ begin "itemize"+ spaces+ items <- many listItem+ end "itemize"+ spaces+ return (BulletList $ map snd items)++definitionList = try $ do+ begin "description"+ spaces+ items <- many listItem+ end "description"+ spaces+ return (DefinitionList items)++--+-- paragraph block+--++para = many1 inline >>~ spaces >>= return . Para . normalizeSpaces++--+-- title authors date+--++bibliographic = choice [ maketitle, title, authors, date ]++maketitle = try (string "\\maketitle") >> spaces >> return Null++title = try $ do+ string "\\title{"+ tit <- manyTill inline (char '}')+ spaces+ updateState (\state -> state { stateTitle = tit })+ return Null++authors = try $ do+ string "\\author{"+ authors <- manyTill anyChar (char '}')+ spaces+ let authors' = map removeLeadingTrailingSpace $ lines $+ substitute "\\\\" "\n" authors+ updateState (\state -> state { stateAuthors = authors' })+ return Null++date = try $ do+ string "\\date{"+ date' <- manyTill anyChar (char '}')+ spaces+ updateState (\state -> state { stateDate = date' })+ return Null++--+-- item block+-- for use in unknown environments that aren't being parsed as raw latex+--++-- this forces items to be parsed in different blocks+itemBlock = try $ do+ ("item", _, args) <- command+ state <- getState+ if (stateParserContext state == ListItemState)+ then fail "item should be handled by list block"+ else if null args + then return Null+ else return $ Plain [Str (stripFirstAndLast (head args))]++--+-- raw LaTeX +--++specialEnvironment = do -- these are always parsed as raw+ lookAhead (choice (map (\name -> begin name) ["tabular", "figure",+ "tabbing", "eqnarry", "picture", "table", "verse", "theorem"]))+ rawLaTeXEnvironment++-- | Parse any LaTeX environment and return a Para block containing+-- the whole literal environment as raw TeX.+rawLaTeXEnvironment :: GenParser Char st Block+rawLaTeXEnvironment = try $ do+ string "\\begin{"+ name <- many1 alphaNum+ star <- option "" (string "*") -- for starred variants+ let name' = name ++ star+ char '}'+ args <- option [] commandArgs+ let argStr = concat args+ contents <- manyTill (choice [ (many1 (noneOf "\\")), + (do + (Para [TeX str]) <- rawLaTeXEnvironment+ return str),+ string "\\" ]) + (end name')+ spaces+ return $ Para [TeX $ "\\begin{" ++ name' ++ "}" ++ argStr ++ + concat contents ++ "\\end{" ++ name' ++ "}"]++unknownEnvironment = try $ do+ state <- getState+ result <- if stateParseRaw state -- check whether we should include raw TeX + then rawLaTeXEnvironment -- if so, get whole raw environment+ else anyEnvironment -- otherwise just the contents+ return result++unknownCommand = try $ do+ notFollowedBy' $ choice $ map end ["itemize", "enumerate", "description", + "document"]+ (name, star, args) <- command+ spaces+ let argStr = concat args+ state <- getState+ if name == "item" && (stateParserContext state) == ListItemState+ then fail "should not be parsed as raw"+ else string ""+ if stateParseRaw state+ then return $ Plain [TeX ("\\" ++ name ++ star ++ argStr)]+ else return $ Plain [Str (joinWithSep " " args)]++-- latex comment+comment = try $ char '%' >> manyTill anyChar newline >> spaces >> return Null++-- +-- inline+--++inline = choice [ strong+ , emph+ , strikeout+ , superscript+ , subscript+ , ref+ , lab+ , code+ , linebreak+ , spacer+ , math+ , ellipses+ , emDash+ , enDash+ , hyphen+ , quoted+ , apostrophe+ , accentedChar+ , specialChar+ , url+ , link+ , image+ , footnote+ , rawLaTeXInline+ , escapedChar+ , unescapedChar+ , str+ , endline+ , whitespace ] <?> "inline"++accentedChar = normalAccentedChar <|> specialAccentedChar++normalAccentedChar = try $ do+ char '\\'+ accent <- oneOf "'`^\"~"+ character <- (try $ char '{' >> alphaNum >>~ char '}') <|> alphaNum+ let table = fromMaybe [] $ lookup character accentTable + let result = case lookup accent table of+ Just num -> chr num+ Nothing -> '?'+ return $ Str [result]++-- an association list of letters and association list of accents+-- and decimal character numbers.+accentTable = + [ ('A', [('`', 192), ('\'', 193), ('^', 194), ('~', 195), ('"', 196)]),+ ('E', [('`', 200), ('\'', 201), ('^', 202), ('"', 203)]),+ ('I', [('`', 204), ('\'', 205), ('^', 206), ('"', 207)]),+ ('N', [('~', 209)]),+ ('O', [('`', 210), ('\'', 211), ('^', 212), ('~', 213), ('"', 214)]),+ ('U', [('`', 217), ('\'', 218), ('^', 219), ('"', 220)]),+ ('a', [('`', 224), ('\'', 225), ('^', 227), ('"', 228)]),+ ('e', [('`', 232), ('\'', 233), ('^', 234), ('"', 235)]),+ ('i', [('`', 236), ('\'', 237), ('^', 238), ('"', 239)]),+ ('n', [('~', 241)]),+ ('o', [('`', 242), ('\'', 243), ('^', 244), ('~', 245), ('"', 246)]),+ ('u', [('`', 249), ('\'', 250), ('^', 251), ('"', 252)]) ]++specialAccentedChar = choice [ ccedil, aring, iuml, szlig, aelig,+ oslash, pound, euro, copyright, sect ]++ccedil = try $ do+ char '\\'+ letter <- oneOfStrings ["cc", "cC"]+ let num = if letter == "cc" then 231 else 199+ return $ Str [chr num]++aring = try $ do+ char '\\'+ letter <- oneOfStrings ["aa", "AA"]+ let num = if letter == "aa" then 229 else 197+ return $ Str [chr num]++iuml = try (string "\\\"") >> oneOfStrings ["\\i", "{\\i}"] >> + return (Str [chr 239])++icirc = try (string "\\^") >> oneOfStrings ["\\i", "{\\i}"] >>+ return (Str [chr 238])++szlig = try (string "\\ss") >> return (Str [chr 223])++oslash = try $ do+ char '\\'+ letter <- choice [char 'o', char 'O']+ let num = if letter == 'o' then 248 else 216+ return $ Str [chr num]++aelig = try $ do+ char '\\'+ letter <- oneOfStrings ["ae", "AE"]+ let num = if letter == "ae" then 230 else 198+ return $ Str [chr num]++pound = try (string "\\pounds") >> return (Str [chr 163])++euro = try (string "\\euro") >> return (Str [chr 8364])++copyright = try (string "\\copyright") >> return (Str [chr 169])++sect = try (string "\\S") >> return (Str [chr 167])++escapedChar = do+ result <- escaped (oneOf " $%&_#{}\n")+ return $ if result == Str "\n" then Str " " else result++-- ignore standalone, nonescaped special characters+unescapedChar = oneOf "$^&_#{}|<>" >> return (Str "")++specialChar = choice [ backslash, tilde, caret, bar, lt, gt ]++backslash = try (string "\\textbackslash") >> return (Str "\\")++tilde = try (string "\\ensuremath{\\sim}") >> return (Str "~")++caret = try (string "\\^{}") >> return (Str "^")++bar = try (string "\\textbar") >> return (Str "\\")++lt = try (string "\\textless") >> return (Str "<")++gt = try (string "\\textgreater") >> return (Str ">")++code = code1 <|> code2++code1 = try $ do + string "\\verb"+ marker <- anyChar+ result <- manyTill anyChar (char marker)+ return $ Code $ removeLeadingTrailingSpace result++code2 = try $ do+ string "\\texttt{"+ result <- manyTill (noneOf "\\\n~$%^&{}") (char '}')+ return $ Code result++emph = try $ oneOfStrings [ "\\emph{", "\\textit{" ] >>+ manyTill inline (char '}') >>= return . Emph++strikeout = try $ string "\\sout{" >> manyTill inline (char '}') >>=+ return . Strikeout++superscript = try $ string "\\textsuperscript{" >> + manyTill inline (char '}') >>= return . Superscript++-- note: \textsubscript isn't a standard latex command, but we use+-- a defined version in pandoc.+subscript = try $ string "\\textsubscript{" >> manyTill inline (char '}') >>=+ return . Subscript++apostrophe = char '\'' >> return Apostrophe++quoted = doubleQuoted <|> singleQuoted++singleQuoted = enclosed singleQuoteStart singleQuoteEnd inline >>=+ return . Quoted SingleQuote . normalizeSpaces++doubleQuoted = enclosed doubleQuoteStart doubleQuoteEnd inline >>=+ return . Quoted DoubleQuote . normalizeSpaces++singleQuoteStart = char '`'++singleQuoteEnd = try $ char '\'' >> notFollowedBy alphaNum++doubleQuoteStart = string "``"++doubleQuoteEnd = string "''"++ellipses = try $ string "\\ldots" >> optional (try (string "{}")) >>+ return Ellipses++enDash = try (string "--") >> return EnDash++emDash = try (string "---") >> return EmDash++hyphen = char '-' >> return (Str "-")++lab = try $ do+ string "\\label{"+ result <- manyTill anyChar (char '}')+ return $ Str $ "(" ++ result ++ ")"++ref = try (string "\\ref{") >> manyTill anyChar (char '}') >>= return . Str++strong = try (string "\\textbf{") >> manyTill inline (char '}') >>=+ return . Strong++whitespace = many1 (oneOf "~ \t") >> return Space++-- hard line break+linebreak = try (string "\\\\") >> return LineBreak++spacer = try (string "\\,") >> return (Str "")++str = many1 (noneOf specialChars) >>= return . Str++-- endline internal to paragraph+endline = try $ newline >> notFollowedBy blankline >> return Space++-- math+math = math1 <|> math2 <?> "math"++math1 = try $ do+ char '$'+ result <- many (noneOf "$")+ char '$'+ return $ TeX ("$" ++ result ++ "$")++math2 = try $ do+ string "\\("+ result <- many (noneOf "$")+ string "\\)"+ return $ TeX ("$" ++ result ++ "$")++--+-- links and images+--++url = try $ do+ string "\\url"+ url <- charsInBalanced '{' '}'+ return $ Link [Code url] (url, "")++link = try $ do+ string "\\href{"+ url <- manyTill anyChar (char '}')+ char '{'+ label <- manyTill inline (char '}') + return $ Link (normalizeSpaces label) (url, "")++image = try $ do+ ("includegraphics", _, args) <- command+ let args' = filter isArg args -- filter out options+ let src = if null args' then+ ("", "")+ else+ (stripFirstAndLast (head args'), "")+ return $ Image [Str "image"] src++footnote = try $ do+ (name, _, (contents:[])) <- command+ if ((name == "footnote") || (name == "thanks"))+ then string ""+ else fail "not a footnote or thanks command"+ let contents' = stripFirstAndLast contents+ -- parse the extracted block, which may contain various block elements:+ rest <- getInput+ setInput $ contents'+ blocks <- parseBlocks+ setInput rest+ return $ Note blocks++-- | Parse any LaTeX command and return it in a raw TeX inline element.+rawLaTeXInline :: GenParser Char ParserState Inline+rawLaTeXInline = try $ do+ (name, star, args) <- command+ state <- getState+ if ((name == "begin") || (name == "end") || (name == "item"))+ then fail "not an inline command" + else string ""+ return $ TeX ("\\" ++ name ++ star ++ concat args)+
+ src/Text/Pandoc/Readers/Markdown.hs view
@@ -0,0 +1,908 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Readers.Markdown+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of markdown-formatted plain text to 'Pandoc' document.+-}+module Text.Pandoc.Readers.Markdown ( + readMarkdown + ) where++import Data.List ( transpose, isSuffixOf, lookup, sortBy )+import Data.Ord ( comparing )+import Data.Char ( isAlphaNum )+import Text.Pandoc.Definition+import Text.Pandoc.Shared +import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXEnvironment )+import Text.Pandoc.Readers.HTML ( rawHtmlBlock, anyHtmlBlockTag, + anyHtmlInlineTag, anyHtmlTag,+ anyHtmlEndTag, htmlEndTag, extractTagType,+ htmlBlockElement )+import Text.Pandoc.CharacterReferences ( decodeCharacterReferences )+import Text.ParserCombinators.Parsec++-- | Read markdown from an input string and return a Pandoc document.+readMarkdown :: ParserState -> String -> Pandoc+readMarkdown state str = (readWith parseMarkdown) state (str ++ "\n\n")++--+-- Constants and data structure definitions+--++spaceChars = " \t"+bulletListMarkers = "*+-"+hruleChars = "*-_"+titleOpeners = "\"'("+setextHChars = "=-"++-- treat these as potentially non-text when parsing inline:+specialChars = "\\[]*_~`<>$!^-.&'\""++--+-- auxiliary functions+--++indentSpaces = try $ do+ state <- getState+ let tabStop = stateTabStop state+ try (count tabStop (char ' ')) <|> + (many (char ' ') >> string "\t") <?> "indentation"++nonindentSpaces = do+ state <- getState+ let tabStop = stateTabStop state+ choice $ map (\n -> (try (count n (char ' ')))) $ reverse [0..(tabStop - 1)]++-- | Fail unless we're at beginning of a line.+failUnlessBeginningOfLine = do+ pos <- getPosition+ if sourceColumn pos == 1 then return () else fail "not beginning of line"++-- | Fail unless we're in "smart typography" mode.+failUnlessSmart = do+ state <- getState+ if stateSmart state then return () else fail "Smart typography feature"++-- | Parse an inline Str element with a given content.+inlineString str = try $ do + (Str res) <- inline + if res == str then return res else fail $ "unexpected Str content"++-- | Parse a sequence of inline elements between a string+-- @opener@ and a string @closer@, including inlines+-- between balanced pairs of @opener@ and a @closer@.+inlinesInBalanced :: String -> String -> GenParser Char ParserState [Inline]+inlinesInBalanced opener closer = try $ do+ string opener+ result <- manyTill ( (do lookAhead (inlineString opener)+ -- because it might be a link...+ bal <- inlinesInBalanced opener closer + return $ [Str opener] ++ bal ++ [Str closer])+ <|> (count 1 inline)) + (try (string closer))+ return $ concat result++--+-- document structure+--++titleLine = try $ char '%' >> skipSpaces >> manyTill inline newline++authorsLine = try $ do + char '%'+ skipSpaces+ authors <- sepEndBy (many1 (noneOf ",;\n")) (oneOf ",;")+ newline+ return $ map (decodeCharacterReferences . removeLeadingTrailingSpace) authors++dateLine = try $ do+ char '%'+ skipSpaces+ date <- many (noneOf "\n")+ newline+ return $ decodeCharacterReferences $ removeTrailingSpace date++titleBlock = try $ do+ failIfStrict+ title <- option [] titleLine+ author <- option [] authorsLine+ date <- option "" dateLine+ optional blanklines+ return (title, author, date)++parseMarkdown = do+ -- markdown allows raw HTML+ updateState (\state -> state { stateParseRaw = True })+ (title, author, date) <- option ([],[],"") titleBlock+ -- go through once just to get list of reference keys+ refs <- manyTill (referenceKey <|> (lineClump >>= return . LineClump)) eof+ let keys = map (\(KeyBlock label target) -> (label, target)) $ + filter isKeyBlock refs+ let rawlines = map (\(LineClump ln) -> ln) $ filter isLineClump refs+ setInput $ concat rawlines -- with keys stripped out + updateState (\state -> state { stateKeys = keys })+ -- now go through for notes (which may contain references - hence 2nd pass)+ refs <- manyTill (noteBlock <|> (lineClump >>= return . LineClump)) eof + let notes = map (\(NoteBlock label blocks) -> (label, blocks)) $ + filter isNoteBlock refs+ let rawlines = map (\(LineClump ln) -> ln) $ filter isLineClump refs+ -- go through a 3rd time, with note blocks and keys stripped out+ setInput $ concat rawlines + updateState (\state -> state { stateNotes = notes })+ blocks <- parseBlocks + let blocks' = filter (/= Null) blocks+ return $ Pandoc (Meta title author date) blocks'++-- +-- initial pass for references and notes+--++referenceKey = try $ do+ nonindentSpaces+ label <- reference+ char ':'+ skipSpaces+ optional (char '<')+ src <- many (noneOf "> \n\t")+ optional (char '>')+ tit <- option "" title + blanklines + return $ KeyBlock label (removeTrailingSpace src, tit)++noteMarker = try $ do+ char '['+ char '^'+ manyTill (noneOf " \t\n") (char ']')++rawLine = try $ do+ notFollowedBy blankline+ notFollowedBy' noteMarker+ contents <- many1 nonEndline+ end <- option "" (newline >> optional indentSpaces >> return "\n") + return $ contents ++ end++rawLines = many1 rawLine >>= return . concat++noteBlock = try $ do+ failIfStrict+ ref <- noteMarker+ char ':'+ optional blankline+ optional indentSpaces+ raw <- sepBy rawLines (try (blankline >> indentSpaces))+ optional blanklines+ -- parse the extracted text, which may contain various block elements:+ rest <- getInput+ setInput $ (joinWithSep "\n" raw) ++ "\n\n"+ contents <- parseBlocks+ setInput rest+ return $ NoteBlock ref contents++--+-- parsing blocks+--++parseBlocks = manyTill block eof++block = choice [ header + , table+ , codeBlock+ , hrule+ , list+ , blockQuote+ , htmlBlock+ , rawLaTeXEnvironment'+ , para+ , plain+ , nullBlock ] <?> "block"++--+-- header blocks+--++header = setextHeader <|> atxHeader <?> "header"++atxHeader = try $ do+ lead <- many1 (char '#')+ notFollowedBy (char '.' <|> char ')') -- this would be a list+ skipSpaces+ txt <- manyTill inline atxClosing+ return $ Header (length lead) (normalizeSpaces txt)++atxClosing = try $ skipMany (char '#') >> skipSpaces >> newline >> + option "" blanklines++setextHeader = choice $ + map (\x -> setextH x) $ enumFromTo 1 (length setextHChars)++setextH n = try $ do+ txt <- many1Till inline newline+ many1 (char (setextHChars !! (n-1)))+ skipSpaces+ newline+ optional blanklines+ return $ Header n (normalizeSpaces txt)++--+-- hrule block+--++hruleWith chr = try $ do+ count 3 (skipSpaces >> char chr)+ skipMany (skipSpaces >> char chr)+ newline+ optional blanklines+ return HorizontalRule++hrule = choice (map hruleWith hruleChars) <?> "hrule"++--+-- code blocks+--++indentedLine = try $ do+ indentSpaces+ result <- manyTill anyChar newline+ return $ result ++ "\n"++-- two or more indented lines, possibly separated by blank lines+indentedBlock = try $ do + res1 <- indentedLine+ blanks <- many blankline + res2 <- indentedBlock <|> indentedLine+ return $ res1 ++ blanks ++ res2++codeBlock = (indentedBlock <|> indentedLine) >>~ optional blanklines >>=+ return . CodeBlock . stripTrailingNewlines++--+-- block quotes+--++emacsBoxQuote = try $ do+ failIfStrict+ string ",----"+ manyTill anyChar newline+ raw <- manyTill + (try (char '|' >> optional (char ' ') >> manyTill anyChar newline))+ (try (string "`----"))+ blanklines+ return raw++emailBlockQuoteStart = try $ nonindentSpaces >> char '>' >>~ optional (char ' ')++emailBlockQuote = try $ do+ emailBlockQuoteStart+ raw <- sepBy (many (nonEndline <|> + (try (endline >> notFollowedBy emailBlockQuoteStart >>+ return '\n'))))+ (try (newline >> emailBlockQuoteStart))+ newline <|> (eof >> return '\n')+ optional blanklines+ return raw++blockQuote = do + raw <- emailBlockQuote <|> emacsBoxQuote+ -- parse the extracted block, which may contain various block elements:+ rest <- getInput+ setInput $ (joinWithSep "\n" raw) ++ "\n\n"+ contents <- parseBlocks+ setInput rest+ return $ BlockQuote contents+ +--+-- list blocks+--++list = choice [ bulletList, orderedList, definitionList ] <?> "list"++bulletListStart = try $ do+ optional newline -- if preceded by a Plain block in a list context+ nonindentSpaces+ notFollowedBy' hrule -- because hrules start out just like lists+ oneOf bulletListMarkers+ spaceChar+ skipSpaces++anyOrderedListStart = try $ do+ optional newline -- if preceded by a Plain block in a list context+ nonindentSpaces+ state <- getState+ if stateStrict state+ then do many1 digit+ char '.'+ return (1, DefaultStyle, DefaultDelim)+ else anyOrderedListMarker++orderedListStart style delim = try $ do+ optional newline -- if preceded by a Plain block in a list context+ nonindentSpaces+ state <- getState+ if stateStrict state+ then do many1 digit+ char '.'+ return 1+ else orderedListMarker style delim + oneOf spaceChars+ skipSpaces++-- parse a line of a list item (start = parser for beginning of list item)+listLine start = try $ do+ notFollowedBy' start+ notFollowedBy blankline+ notFollowedBy' (do indentSpaces+ many (spaceChar)+ bulletListStart <|> (anyOrderedListStart >> return ()))+ line <- manyTill anyChar newline+ return $ line ++ "\n"++-- parse raw text for one list item, excluding start marker and continuations+rawListItem start = try $ do+ start+ result <- many1 (listLine start)+ blanks <- many blankline+ return $ concat result ++ blanks++-- continuation of a list item - indented and separated by blankline +-- or (in compact lists) endline.+-- note: nested lists are parsed as continuations+listContinuation start = try $ do+ lookAhead indentSpaces+ result <- many1 (listContinuationLine start)+ blanks <- many blankline+ return $ concat result ++ blanks++listContinuationLine start = try $ do+ notFollowedBy blankline+ notFollowedBy' start+ optional indentSpaces+ result <- manyTill anyChar newline+ return $ result ++ "\n"++listItem start = try $ do + first <- rawListItem start+ continuations <- many (listContinuation start)+ -- parsing with ListItemState forces markers at beginning of lines to+ -- count as list item markers, even if not separated by blank space.+ -- see definition of "endline"+ state <- getState+ let oldContext = stateParserContext state+ setState $ state {stateParserContext = ListItemState}+ -- parse the extracted block, which may contain various block elements:+ rest <- getInput+ let raw = concat (first:continuations)+ setInput raw+ contents <- parseBlocks+ setInput rest+ updateState (\st -> st {stateParserContext = oldContext})+ return contents++orderedList = do+ (start, style, delim) <- lookAhead anyOrderedListStart+ items <- many1 (listItem (orderedListStart style delim))+ return $ OrderedList (start, style, delim) $ compactify items++bulletList = many1 (listItem bulletListStart) >>= + return . BulletList . compactify++-- definition lists++definitionListItem = try $ do+ notFollowedBy blankline+ notFollowedBy' indentSpaces+ term <- manyTill inline newline+ raw <- many1 defRawBlock+ state <- getState+ let oldContext = stateParserContext state+ -- parse the extracted block, which may contain various block elements:+ rest <- getInput+ setInput (concat raw)+ contents <- parseBlocks+ setInput rest+ updateState (\st -> st {stateParserContext = oldContext})+ return ((normalizeSpaces term), contents)++defRawBlock = try $ do+ char ':'+ state <- getState+ let tabStop = stateTabStop state+ try (count (tabStop - 1) (char ' ')) <|> (many (char ' ') >> string "\t")+ firstline <- anyLine+ rawlines <- many (notFollowedBy blankline >> indentSpaces >> anyLine)+ trailing <- option "" blanklines+ return $ firstline ++ "\n" ++ unlines rawlines ++ trailing++definitionList = do+ failIfStrict+ items <- many1 definitionListItem+ let (terms, defs) = unzip items+ let defs' = compactify defs+ let items' = zip terms defs'+ return $ DefinitionList items'++--+-- paragraph block+--++para = try $ do + result <- many1 inline+ newline+ st <- getState+ if stateStrict st+ then choice [ lookAhead blockQuote, lookAhead header, + (blanklines >> return Null) ]+ else choice [ lookAhead emacsBoxQuote >> return Null, + (blanklines >> return Null) ]+ return $ Para $ normalizeSpaces result++plain = many1 inline >>= return . Plain . normalizeSpaces ++-- +-- raw html+--++htmlElement = strictHtmlBlock <|> htmlBlockElement <?> "html element"++htmlBlock = do+ st <- getState+ if stateStrict st+ then try $ do failUnlessBeginningOfLine+ first <- htmlElement+ finalSpace <- many (oneOf spaceChars)+ finalNewlines <- many newline+ return $ RawHtml $ first ++ finalSpace ++ finalNewlines+ else rawHtmlBlocks++-- True if tag is self-closing+isSelfClosing tag = + isSuffixOf "/>" $ filter (\c -> (not (c `elem` " \n\t"))) tag++strictHtmlBlock = try $ do+ tag <- anyHtmlBlockTag + let tag' = extractTagType tag+ if isSelfClosing tag || tag' == "hr" + then return tag+ else do contents <- many (notFollowedBy' (htmlEndTag tag') >> + (htmlElement <|> (count 1 anyChar)))+ end <- htmlEndTag tag'+ return $ tag ++ concat contents ++ end++rawHtmlBlocks = try $ do+ htmlBlocks <- many1 rawHtmlBlock + let combined = concatMap (\(RawHtml str) -> str) htmlBlocks+ let combined' = if not (null combined) && last combined == '\n'+ then init combined -- strip extra newline + else combined + return $ RawHtml combined'++--+-- LaTeX+--++rawLaTeXEnvironment' = failIfStrict >> rawLaTeXEnvironment++--+-- Tables+-- ++-- Parse a dashed line with optional trailing spaces; return its length+-- and the length including trailing space.+dashedLine ch = try $ do+ dashes <- many1 (char ch)+ sp <- many spaceChar+ return $ (length dashes, length $ dashes ++ sp)++-- Parse a table header with dashed lines of '-' preceded by +-- one line of text.+simpleTableHeader = try $ do+ rawContent <- anyLine+ initSp <- nonindentSpaces+ dashes <- many1 (dashedLine '-')+ newline+ let (lengths, lines) = unzip dashes+ let indices = scanl (+) (length initSp) lines+ let rawHeads = tail $ splitByIndices (init indices) rawContent+ let aligns = zipWith alignType (map (\a -> [a]) rawHeads) lengths+ return (rawHeads, aligns, indices)++-- Parse a table footer - dashed lines followed by blank line.+tableFooter = try $ nonindentSpaces >> many1 (dashedLine '-') >> blanklines++-- Parse a table separator - dashed line.+tableSep = try $ nonindentSpaces >> many1 (dashedLine '-') >> string "\n"++-- Parse a raw line and split it into chunks by indices.+rawTableLine indices = do+ notFollowedBy' (blanklines <|> tableFooter)+ line <- many1Till anyChar newline+ return $ map removeLeadingTrailingSpace $ tail $ + splitByIndices (init indices) line++-- Parse a table line and return a list of lists of blocks (columns).+tableLine indices = rawTableLine indices >>= mapM (parseFromString (many plain))++-- Parse a multiline table row and return a list of blocks (columns).+multilineRow indices = try $ do+ colLines <- many1 (rawTableLine indices)+ optional blanklines+ let cols = map unlines $ transpose colLines+ mapM (parseFromString (many plain)) cols++-- Calculate relative widths of table columns, based on indices+widthsFromIndices :: Int -- Number of columns on terminal+ -> [Int] -- Indices+ -> [Float] -- Fractional relative sizes of columns+widthsFromIndices _ [] = [] +widthsFromIndices numColumns indices = + let lengths = zipWith (-) indices (0:indices)+ totLength = sum lengths+ quotient = if totLength > numColumns+ then fromIntegral totLength+ else fromIntegral numColumns+ fracs = map (\l -> (fromIntegral l) / quotient) lengths in+ tail fracs++-- Parses a table caption: inlines beginning with 'Table:'+-- and followed by blank lines.+tableCaption = try $ do+ nonindentSpaces+ string "Table:"+ result <- many1 inline+ blanklines+ return $ normalizeSpaces result++-- Parse a table using 'headerParser', 'lineParser', and 'footerParser'.+tableWith headerParser lineParser footerParser = try $ do+ (rawHeads, aligns, indices) <- headerParser+ lines <- many1Till (lineParser indices) footerParser+ caption <- option [] tableCaption+ heads <- mapM (parseFromString (many plain)) rawHeads+ state <- getState+ let numColumns = stateColumns state+ let widths = widthsFromIndices numColumns indices+ return $ Table caption aligns widths heads lines++-- Parse a simple table with '---' header and one line per row.+simpleTable = tableWith simpleTableHeader tableLine blanklines++-- Parse a multiline table: starts with row of '-' on top, then header+-- (which may be multiline), then the rows,+-- which may be multiline, separated by blank lines, and+-- ending with a footer (dashed line followed by blank line).+multilineTable = tableWith multilineTableHeader multilineRow tableFooter++multilineTableHeader = try $ do+ tableSep + rawContent <- many1 (notFollowedBy' tableSep >> many1Till anyChar newline)+ initSp <- nonindentSpaces+ dashes <- many1 (dashedLine '-')+ newline+ let (lengths, lines) = unzip dashes+ let indices = scanl (+) (length initSp) lines+ let rawHeadsList = transpose $ map + (\ln -> tail $ splitByIndices (init indices) ln)+ rawContent+ let rawHeads = map (joinWithSep " ") rawHeadsList+ let aligns = zipWith alignType rawHeadsList lengths+ return ((map removeLeadingTrailingSpace rawHeads), aligns, indices)++-- Returns an alignment type for a table, based on a list of strings+-- (the rows of the column header) and a number (the length of the+-- dashed line under the rows.+alignType :: [String] -> Int -> Alignment+alignType [] len = AlignDefault+alignType strLst len =+ let str = head $ sortBy (comparing length) $ + map removeTrailingSpace strLst+ leftSpace = if null str then False else (str !! 0) `elem` " \t"+ rightSpace = length str < len || (str !! (len - 1)) `elem` " \t"+ in case (leftSpace, rightSpace) of+ (True, False) -> AlignRight+ (False, True) -> AlignLeft+ (True, True) -> AlignCenter+ (False, False) -> AlignDefault++table = failIfStrict >> (simpleTable <|> multilineTable) <?> "table"++-- +-- inline+--++inline = choice [ rawLaTeXInline'+ , escapedChar+ , charRef+ , note+ , inlineNote+ , link+ , referenceLink+ , rawHtmlInline'+ , autoLink+ , image+ , math+ , strong+ , emph+ , strikeout+ , superscript+ , subscript+ , smartPunctuation+ , code+ , ltSign+ , symbol+ , str+ , linebreak+ , tabchar+ , whitespace+ , endline ] <?> "inline"++escapedChar = try $ do+ char '\\'+ state <- getState+ result <- if stateStrict state + then oneOf "\\`*_{}[]()>#+-.!~"+ else satisfy (not . isAlphaNum)+ return $ Str [result]++ltSign = try $ do+ notFollowedBy (noneOf "<") -- continue only if it's a <+ notFollowedBy' rawHtmlBlocks -- don't return < if it starts html+ char '<'+ return $ Str ['<']++specialCharsMinusLt = filter (/= '<') specialChars++symbol = do + result <- oneOf specialCharsMinusLt+ return $ Str [result]++-- parses inline code, between n `s and n `s+code = try $ do + starts <- many1 (char '`')+ let num = length starts+ result <- many1Till anyChar (try (count num (char '`')))+ -- get rid of any internal newlines+ return $ Code $ removeLeadingTrailingSpace $ joinWithSep " " $ lines result++mathWord = many1 ((noneOf " \t\n\\$") <|>+ (try (char '\\') >>~ notFollowedBy (char '$')))++math = try $ do+ failIfStrict+ char '$'+ notFollowedBy space+ words <- sepBy1 mathWord (many1 space)+ char '$'+ return $ TeX ("$" ++ (joinWithSep " " words) ++ "$")++emph = ((enclosed (char '*') (char '*') inline) <|>+ (enclosed (char '_') (char '_') inline)) >>= + return . Emph . normalizeSpaces++strong = ((enclosed (string "**") (string "**") inline) <|> + (enclosed (string "__") (string "__") inline)) >>=+ return . Strong . normalizeSpaces++strikeout = failIfStrict >> enclosed (string "~~") (string "~~") inline >>=+ return . Strikeout . normalizeSpaces++superscript = failIfStrict >> enclosed (char '^') (char '^') + (notFollowedBy' whitespace >> inline) >>= -- may not contain Space+ return . Superscript++subscript = failIfStrict >> enclosed (char '~') (char '~')+ (notFollowedBy' whitespace >> inline) >>= -- may not contain Space+ return . Subscript ++smartPunctuation = failUnlessSmart >> + choice [ quoted, apostrophe, dash, ellipses ]++apostrophe = (char '\'' <|> char '\8217') >> return Apostrophe++quoted = doubleQuoted <|> singleQuoted ++withQuoteContext context parser = do+ oldState <- getState+ let oldQuoteContext = stateQuoteContext oldState+ setState oldState { stateQuoteContext = context }+ result <- parser+ newState <- getState+ setState newState { stateQuoteContext = oldQuoteContext }+ return result++singleQuoted = try $ do+ singleQuoteStart+ withQuoteContext InSingleQuote $ many1Till inline singleQuoteEnd >>=+ return . Quoted SingleQuote . normalizeSpaces++doubleQuoted = try $ do + doubleQuoteStart+ withQuoteContext InDoubleQuote $ many1Till inline doubleQuoteEnd >>=+ return . Quoted DoubleQuote . normalizeSpaces++failIfInQuoteContext context = do+ st <- getState+ if (stateQuoteContext st == context)+ then fail "already inside quotes"+ else return ()++singleQuoteStart = do + failIfInQuoteContext InSingleQuote+ char '\8216' <|> + do char '\'' + notFollowedBy (oneOf ")!],.;:-? \t\n")+ notFollowedBy (try (oneOfStrings ["s","t","m","ve","ll","re"] >>+ satisfy (not . isAlphaNum))) -- possess/contraction+ return '\''++singleQuoteEnd = (char '\'' <|> char '\8217') >> notFollowedBy alphaNum++doubleQuoteStart = failIfInQuoteContext InDoubleQuote >>+ (char '"' <|> char '\8220') >>+ notFollowedBy (oneOf " \t\n")++doubleQuoteEnd = char '"' <|> char '\8221'++ellipses = try $ oneOfStrings ["...", " . . . ", ". . .", " . . ."] >>+ return Ellipses++dash = enDash <|> emDash++enDash = try $ char '-' >> notFollowedBy (noneOf "0123456789") >> return EnDash++emDash = try $ skipSpaces >> oneOfStrings ["---", "--"] >>+ skipSpaces >> return EmDash++whitespace = (many1 (oneOf spaceChars) >> return Space) <?> "whitespace"++tabchar = tab >> return (Str "\t")++-- hard line break+linebreak = try $ oneOf spaceChars >> many1 (oneOf spaceChars) >>+ endline >> return LineBreak++nonEndline = satisfy (/='\n')++strChar = noneOf (specialChars ++ spaceChars ++ "\n")++str = many1 strChar >>= return . Str++-- an endline character that can be treated as a space, not a structural break+endline = try $ do+ newline+ notFollowedBy blankline+ st <- getState+ if stateStrict st + then do+ notFollowedBy emailBlockQuoteStart+ notFollowedBy (char '#') -- atx header+ notFollowedBy (manyTill anyChar newline >> oneOf setextHChars) + -- setext header+ else return () + -- parse potential list-starts differently if in a list:+ if stateParserContext st == ListItemState+ then notFollowedBy' (bulletListStart <|> + (anyOrderedListStart >> return ()))+ else return ()+ return Space++--+-- links+--++-- a reference label for a link+reference = notFollowedBy' (string "[^") >> -- footnote reference+ inlinesInBalanced "[" "]" >>= (return . normalizeSpaces)++-- source for a link, with optional title+source = try $ do + char '('+ optional (char '<')+ src <- many (noneOf ")> \t\n")+ optional (char '>')+ tit <- option "" title+ skipSpaces+ char ')'+ return (removeTrailingSpace src, tit)++titleWith startChar endChar = try $ do+ leadingSpace <- many1 (oneOf " \t\n")+ if length (filter (=='\n') leadingSpace) > 1+ then fail "title must be separated by space and on same or next line"+ else return ()+ char startChar+ tit <- manyTill anyChar (try (char endChar >> skipSpaces >>+ notFollowedBy (noneOf ")\n")))+ return $ decodeCharacterReferences tit++title = choice [ titleWith '(' ')', + titleWith '"' '"', + titleWith '\'' '\''] <?> "title"++link = choice [explicitLink, referenceLink] <?> "link"++explicitLink = try $ do+ label <- reference+ src <- source + return $ Link label src++-- a link like [this][ref] or [this][] or [this]+referenceLink = try $ do+ label <- reference+ ref <- option [] (try (skipSpaces >> optional newline >>+ skipSpaces >> reference))+ let ref' = if null ref then label else ref+ state <- getState+ case lookupKeySrc (stateKeys state) ref' of+ Nothing -> fail "no corresponding key" + Just target -> return (Link label target)++autoLink = autoLinkEmail <|> autoLinkRegular++-- a link <like@this.com>+autoLinkEmail = try $ do+ char '<'+ name <- many1Till (noneOf "/:<> \t\n") (char '@')+ domain <- sepBy1 (many1 (noneOf "/:.@<> \t\n")) (char '.')+ let src = name ++ "@" ++ (joinWithSep "." domain)+ char '>'+ return $ Link [Code src] (("mailto:" ++ src), "")++-- a link <http://like.this.com>+autoLinkRegular = try $ do+ char '<'+ prot <- oneOfStrings ["http:", "ftp:", "mailto:"]+ rest <- many1Till (noneOf " \t\n<>") (char '>')+ let src = prot ++ rest+ return $ Link [Code src] (src, "")++image = try $ do+ char '!'+ (Link label src) <- link+ return $ Image label src++note = try $ do+ failIfStrict+ ref <- noteMarker+ state <- getState+ let notes = stateNotes state+ case lookup ref notes of+ Nothing -> fail "note not found"+ Just contents -> return $ Note contents++inlineNote = try $ do+ failIfStrict+ char '^'+ contents <- inlinesInBalanced "[" "]"+ return $ Note [Para contents]++rawLaTeXInline' = failIfStrict >> rawLaTeXInline++rawHtmlInline' = do+ st <- getState+ result <- choice $ if stateStrict st+ then [htmlBlockElement, anyHtmlTag, anyHtmlEndTag] + else [htmlBlockElement, anyHtmlInlineTag]+ return $ HtmlInline result+
+ src/Text/Pandoc/Readers/RST.hs view
@@ -0,0 +1,646 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Readers.RST + Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion from reStructuredText to 'Pandoc' document.+-}+module Text.Pandoc.Readers.RST ( + readRST+ ) where+import Text.Pandoc.Definition+import Text.Pandoc.Shared +import Text.ParserCombinators.Parsec+import Data.List ( findIndex, delete )++-- | Parse reStructuredText string and return Pandoc document.+readRST :: ParserState -> String -> Pandoc+readRST state str = (readWith parseRST) state (str ++ "\n\n")++--+-- Constants and data structure definitions+---++bulletListMarkers = "*+-"+underlineChars = "!\"#$&'()*+,-./:;<=>?@[\\]^_`{|}~"++-- treat these as potentially non-text when parsing inline:+specialChars = "\\`|*_<>$:[-"++--+-- parsing documents+--++isAnonKey (ref, src) = ref == [Str "_"]++isHeader :: Int -> Block -> Bool+isHeader n (Header x _) = x == n+isHeader _ _ = False++-- | Promote all headers in a list of blocks. (Part of+-- title transformation for RST.)+promoteHeaders :: Int -> [Block] -> [Block]+promoteHeaders num ((Header level text):rest) = + (Header (level - num) text):(promoteHeaders num rest)+promoteHeaders num (other:rest) = other:(promoteHeaders num rest)+promoteHeaders num [] = []++-- | If list of blocks starts with a header (or a header and subheader)+-- of level that are not found elsewhere, return it as a title and+-- promote all the other headers. +titleTransform :: [Block] -- ^ list of blocks+ -> ([Block], [Inline]) -- ^ modified list of blocks, title+titleTransform ((Header 1 head1):(Header 2 head2):rest) = -- title subtitle+ if (any (isHeader 1) rest) || (any (isHeader 2) rest)+ then ((Header 1 head1):(Header 2 head2):rest, [])+ else ((promoteHeaders 2 rest), head1 ++ [Str ":", Space] ++ head2)+titleTransform ((Header 1 head1):rest) = -- title, no subtitle+ if (any (isHeader 1) rest)+ then ((Header 1 head1):rest, [])+ else ((promoteHeaders 1 rest), head1)+titleTransform blocks = (blocks, [])++parseRST = do+ -- first pass: get keys+ refs <- manyTill (referenceKey <|> (lineClump >>= return . LineClump)) eof+ let keys = map (\(KeyBlock label target) -> (label, target)) $+ filter isKeyBlock refs+ -- second pass, with keys stripped out+ let rawlines = map (\(LineClump ln) -> ln) $ filter isLineClump refs+ setInput $ concat rawlines + updateState (\state -> state { stateKeys = keys })+ blocks <- parseBlocks+ let blocks' = filter (/= Null) blocks+ state <- getState+ let (blocks'', title) = if stateStandalone state+ then titleTransform blocks'+ else (blocks', [])+ let authors = stateAuthors state+ let date = stateDate state+ let title' = if (null title) then (stateTitle state) else title+ return $ Pandoc (Meta title' authors date) blocks''++--+-- parsing blocks+--++parseBlocks = manyTill block eof++block = choice [ codeBlock+ , rawHtmlBlock+ , rawLaTeXBlock+ , blockQuote+ , imageBlock+ , unknownDirective+ , header+ , hrule+ , list+ , fieldList+ , lineBlock+ , para+ , plain+ , nullBlock ] <?> "block"++--+-- field list+--++fieldListItem = try $ do+ char ':'+ name <- many1 alphaNum+ string ": "+ skipSpaces+ first <- manyTill anyChar newline+ rest <- many (notFollowedBy ((char ':') <|> blankline) >>+ skipSpaces >> manyTill anyChar newline)+ return $ (name, (joinWithSep " " (first:rest)))++fieldList = try $ do+ items <- many1 fieldListItem+ blanklines+ let authors = case lookup "Authors" items of+ Just auth -> [auth]+ Nothing -> map snd (filter (\(x,y) -> x == "Author") items)+ let date = case (lookup "Date" items) of+ Just dat -> dat+ Nothing -> ""+ let title = case (lookup "Title" items) of+ Just tit -> [Str tit]+ Nothing -> []+ let remaining = filter (\(x,y) -> (x /= "Authors") && (x /= "Author") && + (x /= "Date") && (x /= "Title")) items+ let result = map (\(x,y) -> + Para [Strong [Str x], Str ":", Space, Str y]) remaining+ updateState (\st -> st { stateAuthors = authors, + stateDate = date, + stateTitle = title })+ return $ BlockQuote result++--+-- line block+--++lineBlockLine = try $ do+ string "| "+ white <- many (oneOf " \t")+ line <- manyTill inline newline+ return $ (if null white then [] else [Str white]) ++ line ++ [LineBreak]++lineBlock = try $ do+ lines <- many1 lineBlockLine+ blanklines+ return $ Para (concat lines)++--+-- paragraph block+--++para = paraBeforeCodeBlock <|> paraNormal <?> "paragraph"++codeBlockStart = try $ string "::" >> blankline >> blankline++-- paragraph that ends in a :: starting a code block+paraBeforeCodeBlock = try $ do+ result <- many1 (notFollowedBy' codeBlockStart >> inline)+ lookAhead (string "::")+ return $ Para $ if last result == Space+ then normalizeSpaces result+ else (normalizeSpaces result) ++ [Str ":"]++-- regular paragraph+paraNormal = try $ do + result <- many1 inline+ newline+ blanklines+ return $ Para $ normalizeSpaces result++plain = many1 inline >>= return . Plain . normalizeSpaces ++--+-- image block+--++imageBlock = try $ do+ string ".. image:: "+ src <- manyTill anyChar newline+ return $ Plain [Image [Str "image"] (src, "")]++--+-- header blocks+--++header = doubleHeader <|> singleHeader <?> "header"++-- a header with lines on top and bottom+doubleHeader = try $ do+ c <- oneOf underlineChars+ rest <- many (char c) -- the top line+ let lenTop = length (c:rest)+ skipSpaces+ newline+ txt <- many1 (notFollowedBy blankline >> inline)+ pos <- getPosition+ let len = (sourceColumn pos) - 1+ if (len > lenTop) then fail "title longer than border" else return ()+ blankline -- spaces and newline+ count lenTop (char c) -- the bottom line+ blanklines+ -- check to see if we've had this kind of header before. + -- if so, get appropriate level. if not, add to list.+ state <- getState+ let headerTable = stateHeaderTable state+ let (headerTable',level) = case findIndex (== DoubleHeader c) headerTable of+ Just ind -> (headerTable, ind + 1)+ Nothing -> (headerTable ++ [DoubleHeader c], (length headerTable) + 1)+ setState (state { stateHeaderTable = headerTable' })+ return $ Header level (normalizeSpaces txt)++-- a header with line on the bottom only+singleHeader = try $ do + notFollowedBy' whitespace+ txt <- many1 (do {notFollowedBy blankline; inline})+ pos <- getPosition+ let len = (sourceColumn pos) - 1+ blankline+ c <- oneOf underlineChars+ rest <- count (len - 1) (char c)+ many (char c)+ blanklines+ state <- getState+ let headerTable = stateHeaderTable state+ let (headerTable',level) = case findIndex (== SingleHeader c) headerTable of+ Just ind -> (headerTable, ind + 1)+ Nothing -> (headerTable ++ [SingleHeader c], (length headerTable) + 1)+ setState (state { stateHeaderTable = headerTable' })+ return $ Header level (normalizeSpaces txt)++--+-- hrule block+--++hruleWith chr = try $ do+ count 4 (char chr)+ skipMany (char chr)+ skipSpaces+ newline+ blanklines+ return HorizontalRule++hrule = choice (map hruleWith underlineChars) <?> "hrule"++--+-- code blocks+--++-- read a line indented by a given string+indentedLine indents = try $ do+ string indents+ result <- manyTill anyChar newline+ return $ result ++ "\n"++-- two or more indented lines, possibly separated by blank lines.+-- if variable = True, then any indent will work, but it must be+-- consistent through the block.+-- if variable = False, indent should be one tab or equivalent in spaces.+indentedBlock variable = try $ do + state <- getState+ let tabStop = stateTabStop state+ indents <- if variable+ then many1 (oneOf " \t")+ else oneOfStrings ["\t", (replicate tabStop ' ')]+ firstline <- manyTill anyChar newline+ rest <- many (choice [ indentedLine indents, + try (do b <- blanklines+ l <- indentedLine indents+ return (b ++ l))])+ optional blanklines+ return $ firstline ++ "\n" ++ concat rest++codeBlock = try $ do+ codeBlockStart+ result <- indentedBlock False+ -- the False means we want one tab stop indent on each line+ return $ CodeBlock $ stripTrailingNewlines result++--+-- raw html+--++rawHtmlBlock = try $ string ".. raw:: html" >> blanklines >>+ indentedBlock True >>= return . RawHtml++--+-- raw latex+--++rawLaTeXBlock = try $ do+ string ".. raw:: latex"+ blanklines+ result <- indentedBlock True+ return $ Para [(TeX result)]++--+-- block quotes+--++blockQuote = try $ do+ raw <- indentedBlock True+ -- parse the extracted block, which may contain various block elements:+ rest <- getInput+ setInput $ raw ++ "\n\n"+ contents <- parseBlocks+ setInput rest+ return $ BlockQuote contents++--+-- list blocks+--++list = choice [ bulletList, orderedList, definitionList ] <?> "list"++definitionListItem = try $ do+ term <- many1Till inline endline+ raw <- indentedBlock True+ -- parse the extracted block, which may contain various block elements:+ rest <- getInput+ setInput $ raw ++ "\n\n"+ contents <- parseBlocks+ setInput rest+ return (normalizeSpaces term, contents)++definitionList = try $ do+ items <- many1 definitionListItem + return $ DefinitionList items++-- parses bullet list start and returns its length (inc. following whitespace)+bulletListStart = try $ do+ notFollowedBy' hrule -- because hrules start out just like lists+ marker <- oneOf bulletListMarkers+ white <- many1 spaceChar+ return $ length (marker:white)++-- parses ordered list start and returns its length (inc following whitespace)+orderedListStart style delim = try $ do+ (_, markerLen) <- withHorizDisplacement (orderedListMarker style delim)+ white <- many1 spaceChar+ return $ markerLen + length white++-- parse a line of a list item+listLine markerLength = try $ do+ notFollowedBy blankline+ indentWith markerLength+ line <- manyTill anyChar newline+ return $ line ++ "\n"++-- indent by specified number of spaces (or equiv. tabs)+indentWith num = do+ state <- getState+ let tabStop = stateTabStop state+ if (num < tabStop)+ then count num (char ' ')+ else choice [ try (count num (char ' ')), + (try (char '\t' >> count (num - tabStop) (char ' '))) ] ++-- parse raw text for one list item, excluding start marker and continuations+rawListItem start = try $ do+ markerLength <- start+ firstLine <- manyTill anyChar newline+ restLines <- many (listLine markerLength)+ return (markerLength, (firstLine ++ "\n" ++ (concat restLines)))++-- continuation of a list item - indented and separated by blankline or +-- (in compact lists) endline. +-- Note: nested lists are parsed as continuations.+listContinuation markerLength = try $ do+ blanks <- many1 blankline+ result <- many1 (listLine markerLength)+ return $ blanks ++ concat result++listItem start = try $ do + (markerLength, first) <- rawListItem start+ rest <- many (listContinuation markerLength)+ blanks <- choice [ try (many blankline >>~ lookAhead start),+ many1 blankline ] -- whole list must end with blank.+ -- parsing with ListItemState forces markers at beginning of lines to+ -- count as list item markers, even if not separated by blank space.+ -- see definition of "endline"+ state <- getState+ let oldContext = stateParserContext state+ remaining <- getInput+ setState $ state {stateParserContext = ListItemState}+ -- parse the extracted block, which may itself contain block elements+ setInput $ concat (first:rest) ++ blanks+ parsed <- parseBlocks+ setInput remaining + updateState (\st -> st {stateParserContext = oldContext})+ return parsed++orderedList = try $ do+ (start, style, delim) <- lookAhead anyOrderedListMarker + items <- many1 (listItem (orderedListStart style delim))+ let items' = compactify items+ return $ OrderedList (start, style, delim) items'++bulletList = try $ do+ items <- many1 (listItem bulletListStart)+ let items' = compactify items+ return $ BulletList items'++--+-- unknown directive (e.g. comment)+--++unknownDirective = try $ do+ string ".. "+ manyTill anyChar newline+ many (string " :" >> many1 (noneOf "\n:") >> char ':' >>+ many1 (noneOf "\n") >> newline)+ optional blanklines+ return Null++-- +-- reference key+--++referenceKey = + choice [imageKey, anonymousKey, regularKeyQuoted, regularKey] >>~ + optional blanklines++targetURI = try $ do+ skipSpaces+ optional newline+ contents <- many1 (try (many spaceChar >> newline >> + many1 spaceChar >> noneOf " \t\n") <|> noneOf "\n")+ blanklines+ return contents++imageKey = try $ do+ string ".. |"+ ref <- manyTill inline (char '|')+ skipSpaces+ string "image::"+ src <- targetURI+ return $ KeyBlock (normalizeSpaces ref) (removeLeadingTrailingSpace src, "")++anonymousKey = try $ do+ oneOfStrings [".. __:", "__"]+ src <- targetURI+ state <- getState+ return $ KeyBlock [Str "_"] (removeLeadingTrailingSpace src, "")++regularKeyQuoted = try $ do+ string ".. _`"+ ref <- manyTill inline (char '`')+ char ':'+ src <- targetURI+ return $ KeyBlock (normalizeSpaces ref) (removeLeadingTrailingSpace src, "")++regularKey = try $ do+ string ".. _"+ ref <- manyTill inline (char ':')+ src <- targetURI+ return $ KeyBlock (normalizeSpaces ref) (removeLeadingTrailingSpace src, "")++ -- + -- inline+ --++inline = choice [ superscript+ , subscript+ , escapedChar+ , link+ , image+ , hyphens+ , strong+ , emph+ , code+ , str+ , tabchar+ , whitespace+ , endline+ , symbol ] <?> "inline"++hyphens = try $ do+ result <- many1 (char '-')+ option Space endline + -- don't want to treat endline after hyphen or dash as a space+ return $ Str result++escapedChar = escaped anyChar++symbol = do + result <- oneOf specialChars+ return $ Str [result]++-- parses inline code, between codeStart and codeEnd+code = try $ do + string "``"+ result <- manyTill anyChar (try (string "``"))+ return $ Code $ removeLeadingTrailingSpace $ joinWithSep " " $ lines result++emph = enclosed (char '*') (char '*') inline >>= + return . Emph . normalizeSpaces++strong = enclosed (string "**") (string "**") inline >>= + return . Strong . normalizeSpaces++interpreted role = try $ do+ optional $ try $ string "\\ "+ result <- enclosed (string $ ":" ++ role ++ ":`") (char '`') anyChar+ nextChar <- lookAhead anyChar+ try (string "\\ ") <|> lookAhead (count 1 $ oneOf " \t\n") <|> (eof >> return "")+ return [Str result]++superscript = interpreted "sup" >>= (return . Superscript)++subscript = interpreted "sub" >>= (return . Subscript)++whitespace = many1 spaceChar >> return Space <?> "whitespace"++tabchar = tab >> return (Str "\t")++str = notFollowedBy' oneWordReference >> + many1 (noneOf (specialChars ++ "\t\n ")) >>= return . Str++-- an endline character that can be treated as a space, not a structural break+endline = try $ do+ newline+ notFollowedBy blankline+ -- parse potential list-starts at beginning of line differently in a list:+ st <- getState+ if ((stateParserContext st) == ListItemState)+ then notFollowedBy' anyOrderedListMarker >> notFollowedBy' bulletListStart+ else return ()+ return Space++--+-- links+--++link = choice [explicitLink, referenceLink, autoLink] <?> "link"++explicitLink = try $ do+ char '`'+ notFollowedBy (char '`') -- `` is marks start of inline code+ label <- manyTill inline (try (do {spaces; char '<'}))+ src <- manyTill (noneOf ">\n ") (char '>')+ skipSpaces+ string "`_"+ return $ Link (normalizeSpaces label) (removeLeadingTrailingSpace src, "")++reference = try $ do+ char '`'+ notFollowedBy (char '`')+ label <- many1Till inline (char '`') + char '_'+ return label++oneWordReference = do+ raw <- many1 alphaNum+ char '_'+ notFollowedBy alphaNum -- because this_is_not a link+ return [Str raw]++referenceLink = try $ do+ label <- reference <|> oneWordReference+ key <- option label (do{char '_'; return [Str "_"]}) -- anonymous link+ state <- getState+ let keyTable = stateKeys state+ src <- case lookupKeySrc keyTable key of+ Nothing -> fail "no corresponding key"+ Just target -> return target+ -- if anonymous link, remove first anon key so it won't be used again+ let keyTable' = if (key == [Str "_"]) -- anonymous link? + then delete ([Str "_"], src) keyTable -- remove first anon key + else keyTable + setState $ state { stateKeys = keyTable' }+ return $ Link (normalizeSpaces label) src ++uriScheme = oneOfStrings [ "http://", "https://", "ftp://", "file://", + "mailto:", "news:", "telnet:" ]++uri = try $ do+ scheme <- uriScheme+ identifier <- many1 (noneOf " \t\n")+ return $ scheme ++ identifier++autoURI = try $ do+ src <- uri+ return $ Link [Str src] (src, "")++emailChar = alphaNum <|> oneOf "-+_."++emailAddress = try $ do+ firstLetter <- alphaNum+ restAddr <- many emailChar+ let addr = firstLetter:restAddr+ char '@'+ dom <- domain+ return $ addr ++ '@':dom++domainChar = alphaNum <|> char '-'++domain = try $ do+ first <- many1 domainChar+ dom <- many1 (try (do{ char '.'; many1 domainChar }))+ return $ joinWithSep "." (first:dom)++autoEmail = try $ do+ src <- emailAddress+ return $ Link [Str src] ("mailto:" ++ src, "")++autoLink = autoURI <|> autoEmail++-- For now, we assume that all substitution references are for images.+image = try $ do+ char '|'+ ref <- manyTill inline (char '|')+ state <- getState+ let keyTable = stateKeys state+ src <- case lookupKeySrc keyTable ref of+ Nothing -> fail "no corresponding key"+ Just target -> return target+ return $ Image (normalizeSpaces ref) src+
@@ -0,0 +1,818 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Shared+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Utility functions and definitions used by the various Pandoc modules.+-}+module Text.Pandoc.Shared ( + -- * List processing+ splitBy,+ splitByIndices,+ substitute,+ joinWithSep,+ -- * Text processing+ tabsToSpaces,+ backslashEscapes,+ escapeStringUsing,+ stripTrailingNewlines,+ removeLeadingTrailingSpace,+ removeLeadingSpace,+ removeTrailingSpace,+ stripFirstAndLast,+ camelCaseToHyphenated,+ toRomanNumeral,+ -- * Parsing+ (>>~),+ anyLine,+ many1Till,+ notFollowedBy',+ oneOfStrings,+ spaceChar,+ skipSpaces,+ blankline,+ blanklines,+ enclosed,+ stringAnyCase,+ parseFromString,+ lineClump,+ charsInBalanced,+ charsInBalanced',+ romanNumeral,+ withHorizDisplacement,+ nullBlock,+ failIfStrict,+ escaped,+ anyOrderedListMarker,+ orderedListMarker,+ charRef,+ readWith,+ testStringWith,+ ParserState (..),+ defaultParserState,+ Reference (..),+ isNoteBlock,+ isKeyBlock,+ isLineClump,+ HeaderType (..),+ ParserContext (..),+ QuoteContext (..),+ NoteTable,+ KeyTable,+ lookupKeySrc,+ refsMatch,+ -- * Native format prettyprinting+ prettyPandoc,+ -- * Pandoc block and inline list processing+ orderedListMarkers,+ normalizeSpaces,+ compactify,+ Element (..),+ hierarchicalize,+ isHeaderBlock,+ -- * Writer options+ WriterOptions (..),+ defaultWriterOptions+ ) where++import Text.Pandoc.Definition+import Text.ParserCombinators.Parsec+import Text.Pandoc.CharacterReferences ( characterReference )+import Data.Char ( toLower, toUpper, ord, chr, isLower, isUpper )+import Data.List ( find, groupBy, isPrefixOf, isSuffixOf )++--+-- List processing+--++-- | Split list by groups of one or more sep.+splitBy :: (Eq a) => a -> [a] -> [[a]]+splitBy _ [] = []+splitBy sep lst = + let (first, rest) = break (== sep) lst+ rest' = dropWhile (== sep) rest+ in first:(splitBy sep rest')++-- | Split list into chunks divided at specified indices.+splitByIndices :: [Int] -> [a] -> [[a]]+splitByIndices [] lst = [lst]+splitByIndices (x:xs) lst =+ let (first, rest) = splitAt x lst in+ first:(splitByIndices (map (\y -> y - x) xs) rest)++-- | Replace each occurrence of one sublist in a list with another.+substitute :: (Eq a) => [a] -> [a] -> [a] -> [a]+substitute _ _ [] = []+substitute [] _ lst = lst+substitute target replacement lst = + if target `isPrefixOf` lst+ then replacement ++ (substitute target replacement $ drop (length target) lst)+ else (head lst):(substitute target replacement $ tail lst)++-- | Joins a list of lists, separated by another list.+joinWithSep :: [a] -- ^ List to use as separator+ -> [[a]] -- ^ Lists to join+ -> [a]+joinWithSep sep [] = []+joinWithSep sep lst = foldr1 (\a b -> a ++ sep ++ b) lst++--+-- Text processing+--++-- | Convert tabs to spaces (with adjustable tab stop).+tabsToSpaces :: Int -- ^ Tabstop+ -> String -- ^ String to convert+ -> String+tabsToSpaces tabstop str =+ unlines $ map (tabsInLine tabstop tabstop) (lines str)++-- | Convert tabs to spaces in one line.+tabsInLine :: Int -- ^ Number of spaces to next tab stop+ -> Int -- ^ Tabstop+ -> String -- ^ Line to convert+ -> String+tabsInLine num tabstop [] = ""+tabsInLine num tabstop (c:cs) = + let (replacement, nextnum) = if c == '\t'+ then (replicate num ' ', tabstop)+ else if num > 1+ then ([c], num - 1)+ else ([c], tabstop)+ in replacement ++ tabsInLine nextnum tabstop cs++-- | Returns an association list of backslash escapes for the+-- designated characters.+backslashEscapes :: [Char] -- ^ list of special characters to escape+ -> [(Char, String)]+backslashEscapes = map (\ch -> (ch, ['\\',ch]))++-- | Escape a string of characters, using an association list of+-- characters and strings.+escapeStringUsing :: [(Char, String)] -> String -> String+escapeStringUsing escapeTable [] = ""+escapeStringUsing escapeTable (x:xs) = + case (lookup x escapeTable) of+ Just str -> str ++ rest+ Nothing -> x:rest+ where rest = escapeStringUsing escapeTable xs++-- | Strip trailing newlines from string.+stripTrailingNewlines :: String -> String+stripTrailingNewlines = reverse . dropWhile (== '\n') . reverse++-- | Remove leading and trailing space (including newlines) from string.+removeLeadingTrailingSpace :: String -> String+removeLeadingTrailingSpace = removeLeadingSpace . removeTrailingSpace++-- | Remove leading space (including newlines) from string.+removeLeadingSpace :: String -> String+removeLeadingSpace = dropWhile (`elem` " \n\t")++-- | Remove trailing space (including newlines) from string.+removeTrailingSpace :: String -> String+removeTrailingSpace = reverse . removeLeadingSpace . reverse++-- | Strip leading and trailing characters from string+stripFirstAndLast :: String -> String+stripFirstAndLast str =+ drop 1 $ take ((length str) - 1) str++-- | Change CamelCase word to hyphenated lowercase (e.g., camel-case). +camelCaseToHyphenated :: String -> String+camelCaseToHyphenated [] = ""+camelCaseToHyphenated (a:b:rest) | isLower a && isUpper b =+ a:'-':(toLower b):(camelCaseToHyphenated rest)+camelCaseToHyphenated (a:rest) = (toLower a):(camelCaseToHyphenated rest)++-- | Convert number < 4000 to uppercase roman numeral.+toRomanNumeral :: Int -> String+toRomanNumeral x =+ if x >= 4000 || x < 0+ then "?"+ else case x of+ x | x >= 1000 -> "M" ++ toRomanNumeral (x - 1000)+ x | x >= 900 -> "CM" ++ toRomanNumeral (x - 900)+ x | x >= 500 -> "D" ++ toRomanNumeral (x - 500)+ x | x >= 400 -> "CD" ++ toRomanNumeral (x - 400)+ x | x >= 100 -> "C" ++ toRomanNumeral (x - 100)+ x | x >= 90 -> "XC" ++ toRomanNumeral (x - 90)+ x | x >= 50 -> "L" ++ toRomanNumeral (x - 50)+ x | x >= 40 -> "XL" ++ toRomanNumeral (x - 40)+ x | x >= 10 -> "X" ++ toRomanNumeral (x - 10)+ x | x >= 9 -> "IX" ++ toRomanNumeral (x - 5)+ x | x >= 5 -> "V" ++ toRomanNumeral (x - 5)+ x | x >= 4 -> "IV" ++ toRomanNumeral (x - 4)+ x | x >= 1 -> "I" ++ toRomanNumeral (x - 1)+ 0 -> ""++--+-- Parsing+--++-- | Like >>, but returns the operation on the left.+-- (Suggested by Tillmann Rendel on Haskell-cafe list.)+(>>~) :: (Monad m) => m a -> m b -> m a+a >>~ b = a >>= \x -> b >> return x++-- | Parse any line of text+anyLine :: GenParser Char st [Char]+anyLine = try (manyTill anyChar newline) <|> many1 anyChar+ -- second alternative is for a line ending with eof++-- | Like @manyTill@, but reads at least one item.+many1Till :: GenParser tok st a+ -> GenParser tok st end+ -> GenParser tok st [a]+many1Till p end = do+ first <- p+ rest <- manyTill p end+ return (first:rest)++-- | A more general form of @notFollowedBy@. This one allows any +-- type of parser to be specified, and succeeds only if that parser fails.+-- It does not consume any input.+notFollowedBy' :: Show b => GenParser a st b -> GenParser a st ()+notFollowedBy' parser = try $ (do result <- try parser+ unexpected (show result))+ <|> return ()++-- | Parses one of a list of strings (tried in order). +oneOfStrings :: [String] -> GenParser Char st String+oneOfStrings listOfStrings = choice $ map (try . string) listOfStrings++-- | Parses a space or tab.+spaceChar :: CharParser st Char+spaceChar = oneOf " \t"++-- | Skips zero or more spaces or tabs.+skipSpaces :: GenParser Char st ()+skipSpaces = skipMany spaceChar++-- | Skips zero or more spaces or tabs, then reads a newline.+blankline :: GenParser Char st Char+blankline = try $ skipSpaces >> newline++-- | Parses one or more blank lines and returns a string of newlines.+blanklines :: GenParser Char st [Char]+blanklines = many1 blankline++-- | Parses material enclosed between start and end parsers.+enclosed :: GenParser Char st t -- ^ start parser+ -> GenParser Char st end -- ^ end parser+ -> GenParser Char st a -- ^ content parser (to be used repeatedly)+ -> GenParser Char st [a]+enclosed start end parser = try $ + start >> notFollowedBy space >> many1Till parser (try end)+ +-- | Parse string, case insensitive.+stringAnyCase :: [Char] -> CharParser st String+stringAnyCase [] = string ""+stringAnyCase (x:xs) = try $ do+ firstChar <- choice [ char (toUpper x), char (toLower x) ]+ rest <- stringAnyCase xs+ return (firstChar:rest)++-- | Parse contents of 'str' using 'parser' and return result.+parseFromString :: GenParser tok st a -> [tok] -> GenParser tok st a+parseFromString parser str = try $ do+ oldInput <- getInput+ setInput str+ result <- parser+ setInput oldInput+ return result++-- | Parse raw line block up to and including blank lines.+lineClump :: GenParser Char st String+lineClump = do+ lines <- many1 (notFollowedBy blankline >> anyLine)+ blanks <- blanklines <|> (eof >> return "\n")+ return $ (unlines lines) ++ blanks++-- | Parse a string of characters between an open character+-- and a close character, including text between balanced+-- pairs of open and close. For example,+-- @charsInBalanced '(' ')'@ will parse "(hello (there))"+-- and return "hello (there)". Stop if a blank line is+-- encountered.+charsInBalanced :: Char -> Char -> GenParser Char st String+charsInBalanced open close = try $ do+ char open+ raw <- manyTill ( (do res <- charsInBalanced open close+ return $ [open] ++ res ++ [close])+ <|> (do notFollowedBy' (blankline >> blanklines)+ count 1 anyChar))+ (char close)+ return $ concat raw++-- | Like @charsInBalanced@, but allow blank lines in the content.+charsInBalanced' :: Char -> Char -> GenParser Char st String+charsInBalanced' open close = try $ do+ char open+ raw <- manyTill ( (do res <- charsInBalanced open close+ return $ [open] ++ res ++ [close])+ <|> count 1 anyChar)+ (char close)+ return $ concat raw++-- | Parses a roman numeral (uppercase or lowercase), returns number.+romanNumeral :: Bool -- ^ Uppercase if true+ -> GenParser Char st Int+romanNumeral upper = try $ do+ let charAnyCase c = char (if upper then toUpper c else c)+ let one = charAnyCase 'i'+ let five = charAnyCase 'v'+ let ten = charAnyCase 'x'+ let fifty = charAnyCase 'l'+ let hundred = charAnyCase 'c'+ let fivehundred = charAnyCase 'd'+ let thousand = charAnyCase 'm'+ thousands <- many thousand >>= (return . (1000 *) . length)+ ninehundreds <- option 0 $ try $ hundred >> thousand >> return 900+ fivehundreds <- many fivehundred >>= (return . (500 *) . length)+ fourhundreds <- option 0 $ try $ hundred >> fivehundred >> return 400+ hundreds <- many hundred >>= (return . (100 *) . length)+ nineties <- option 0 $ try $ ten >> hundred >> return 90+ fifties <- many fifty >>= (return . (50 *) . length)+ forties <- option 0 $ try $ ten >> fifty >> return 40+ tens <- many ten >>= (return . (10 *) . length)+ nines <- option 0 $ try $ one >> ten >> return 9+ fives <- many five >>= (return . (5 *) . length)+ fours <- option 0 $ try $ one >> five >> return 4+ ones <- many one >>= (return . length)+ let total = thousands + ninehundreds + fivehundreds + fourhundreds ++ hundreds + nineties + fifties + forties + tens + nines ++ fives + fours + ones+ if total == 0+ then fail "not a roman numeral"+ else return total++-- | Applies a parser, returns tuple of its results and its horizontal+-- displacement (the difference between the source column at the end+-- and the source column at the beginning). Vertical displacement+-- (source row) is ignored.+withHorizDisplacement :: GenParser Char st a -- ^ Parser to apply+ -> GenParser Char st (a, Int) -- ^ (result, displacement)+withHorizDisplacement parser = do+ pos1 <- getPosition+ result <- parser+ pos2 <- getPosition+ return (result, sourceColumn pos2 - sourceColumn pos1)++-- | Parses a character and returns 'Null' (so that the parser can move on+-- if it gets stuck).+nullBlock :: GenParser Char st Block+nullBlock = anyChar >> return Null++-- | Fail if reader is in strict markdown syntax mode.+failIfStrict :: GenParser Char ParserState ()+failIfStrict = do+ state <- getState+ if stateStrict state then fail "strict mode" else return ()++-- | Parses backslash, then applies character parser.+escaped :: GenParser Char st Char -- ^ Parser for character to escape+ -> GenParser Char st Inline+escaped parser = try $ do+ char '\\'+ result <- parser+ return (Str [result])++-- | Parses an uppercase roman numeral and returns (UpperRoman, number).+upperRoman :: GenParser Char st (ListNumberStyle, Int)+upperRoman = do+ num <- romanNumeral True+ return (UpperRoman, num)++-- | Parses a lowercase roman numeral and returns (LowerRoman, number).+lowerRoman :: GenParser Char st (ListNumberStyle, Int)+lowerRoman = do+ num <- romanNumeral False+ return (LowerRoman, num)++-- | Parses a decimal numeral and returns (Decimal, number).+decimal :: GenParser Char st (ListNumberStyle, Int)+decimal = do+ num <- many1 digit+ return (Decimal, read num)++-- | Parses a '#' returns (DefaultStyle, 1).+defaultNum :: GenParser Char st (ListNumberStyle, Int)+defaultNum = do+ char '#'+ return (DefaultStyle, 1)++-- | Parses a lowercase letter and returns (LowerAlpha, number).+lowerAlpha :: GenParser Char st (ListNumberStyle, Int)+lowerAlpha = do+ ch <- oneOf ['a'..'z']+ return (LowerAlpha, ord ch - ord 'a' + 1)++-- | Parses an uppercase letter and returns (UpperAlpha, number).+upperAlpha :: GenParser Char st (ListNumberStyle, Int)+upperAlpha = do+ ch <- oneOf ['A'..'Z']+ return (UpperAlpha, ord ch - ord 'A' + 1)++-- | Parses a roman numeral i or I+romanOne :: GenParser Char st (ListNumberStyle, Int)+romanOne = (char 'i' >> return (LowerRoman, 1)) <|>+ (char 'I' >> return (UpperRoman, 1))++-- | Parses an ordered list marker and returns list attributes.+anyOrderedListMarker :: GenParser Char st ListAttributes +anyOrderedListMarker = choice $ + [delimParser numParser | delimParser <- [inPeriod, inOneParen, inTwoParens],+ numParser <- [decimal, defaultNum, romanOne,+ lowerAlpha, lowerRoman, upperAlpha, upperRoman]]++-- | Parses a list number (num) followed by a period, returns list attributes.+inPeriod :: GenParser Char st (ListNumberStyle, Int)+ -> GenParser Char st ListAttributes +inPeriod num = try $ do+ (style, start) <- num+ char '.'+ let delim = if style == DefaultStyle+ then DefaultDelim+ else Period+ return (start, style, delim)+ +-- | Parses a list number (num) followed by a paren, returns list attributes.+inOneParen :: GenParser Char st (ListNumberStyle, Int)+ -> GenParser Char st ListAttributes +inOneParen num = try $ do+ (style, start) <- num+ char ')'+ return (start, style, OneParen)++-- | Parses a list number (num) enclosed in parens, returns list attributes.+inTwoParens :: GenParser Char st (ListNumberStyle, Int)+ -> GenParser Char st ListAttributes +inTwoParens num = try $ do+ char '('+ (style, start) <- num+ char ')'+ return (start, style, TwoParens)++-- | Parses an ordered list marker with a given style and delimiter,+-- returns number.+orderedListMarker :: ListNumberStyle + -> ListNumberDelim + -> GenParser Char st Int+orderedListMarker style delim = do+ let num = case style of+ DefaultStyle -> decimal <|> defaultNum+ Decimal -> decimal+ UpperRoman -> upperRoman+ LowerRoman -> lowerRoman+ UpperAlpha -> upperAlpha+ LowerAlpha -> lowerAlpha+ let context = case delim of+ DefaultDelim -> inPeriod+ Period -> inPeriod+ OneParen -> inOneParen+ TwoParens -> inTwoParens+ (start, style, delim) <- context num+ return start++-- | Parses a character reference and returns a Str element.+charRef :: GenParser Char st Inline+charRef = do+ c <- characterReference+ return $ Str [c]++-- | Parse a string with a given parser and state.+readWith :: GenParser Char ParserState a -- ^ parser+ -> ParserState -- ^ initial state+ -> String -- ^ input string+ -> a+readWith parser state input = + case runParser parser state "source" input of+ Left err -> error $ "\nError:\n" ++ show err+ Right result -> result++-- | Parse a string with @parser@ (for testing).+testStringWith :: (Show a) => GenParser Char ParserState a+ -> String+ -> IO ()+testStringWith parser str = putStrLn $ show $ + readWith parser defaultParserState str++-- | Parsing options.+data ParserState = ParserState+ { stateParseRaw :: Bool, -- ^ Parse raw HTML and LaTeX?+ stateParserContext :: ParserContext, -- ^ Inside list?+ stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?+ stateKeys :: KeyTable, -- ^ List of reference keys+ stateNotes :: NoteTable, -- ^ List of notes+ stateTabStop :: Int, -- ^ Tab stop+ stateStandalone :: Bool, -- ^ Parse bibliographic info?+ stateTitle :: [Inline], -- ^ Title of document+ stateAuthors :: [String], -- ^ Authors of document+ stateDate :: String, -- ^ Date of document+ stateStrict :: Bool, -- ^ Use strict markdown syntax?+ stateSmart :: Bool, -- ^ Use smart typography?+ stateColumns :: Int, -- ^ Number of columns in terminal+ stateHeaderTable :: [HeaderType] -- ^ Ordered list of header types used+ }+ deriving Show++defaultParserState :: ParserState+defaultParserState = + ParserState { stateParseRaw = False,+ stateParserContext = NullState,+ stateQuoteContext = NoQuote,+ stateKeys = [],+ stateNotes = [],+ stateTabStop = 4,+ stateStandalone = False,+ stateTitle = [],+ stateAuthors = [],+ stateDate = [],+ stateStrict = False,+ stateSmart = False,+ stateColumns = 80,+ stateHeaderTable = [] }++-- | References from preliminary parsing.+data Reference+ = KeyBlock [Inline] Target -- ^ Key for reference-style link (label URL title)+ | NoteBlock String [Block] -- ^ Footnote reference and contents+ | LineClump String -- ^ Raw clump of lines with blanks at end+ deriving (Eq, Read, Show)++-- | Auxiliary functions used in preliminary parsing.+isNoteBlock :: Reference -> Bool+isNoteBlock (NoteBlock _ _) = True+isNoteBlock _ = False++isKeyBlock :: Reference -> Bool+isKeyBlock (KeyBlock _ _) = True+isKeyBlock _ = False++isLineClump :: Reference -> Bool+isLineClump (LineClump _) = True+isLineClump _ = False++data HeaderType + = SingleHeader Char -- ^ Single line of characters underneath+ | DoubleHeader Char -- ^ Lines of characters above and below+ deriving (Eq, Show)++data ParserContext + = ListItemState -- ^ Used when running parser on list item contents+ | NullState -- ^ Default state+ deriving (Eq, Show)++data QuoteContext+ = InSingleQuote -- ^ Used when parsing inside single quotes+ | InDoubleQuote -- ^ Used when parsing inside double quotes+ | NoQuote -- ^ Used when not parsing inside quotes+ deriving (Eq, Show)++type NoteTable = [(String, [Block])]++type KeyTable = [([Inline], Target)]++-- | Look up key in key table and return target object.+lookupKeySrc :: KeyTable -- ^ Key table+ -> [Inline] -- ^ Key+ -> Maybe Target+lookupKeySrc table key = case find (refsMatch key . fst) table of+ Nothing -> Nothing+ Just (_, src) -> Just src++-- | Returns @True@ if keys match (case insensitive).+refsMatch :: [Inline] -> [Inline] -> Bool+refsMatch ((Str x):restx) ((Str y):resty) = + ((map toLower x) == (map toLower y)) && refsMatch restx resty+refsMatch ((Emph x):restx) ((Emph y):resty) = + refsMatch x y && refsMatch restx resty+refsMatch ((Strong x):restx) ((Strong y):resty) = + refsMatch x y && refsMatch restx resty+refsMatch ((Strikeout x):restx) ((Strikeout y):resty) = + refsMatch x y && refsMatch restx resty+refsMatch ((Superscript x):restx) ((Superscript y):resty) = + refsMatch x y && refsMatch restx resty+refsMatch ((Subscript x):restx) ((Subscript y):resty) = + refsMatch x y && refsMatch restx resty+refsMatch ((Quoted t x):restx) ((Quoted u y):resty) = + t == u && refsMatch x y && refsMatch restx resty+refsMatch ((Code x):restx) ((Code y):resty) = + ((map toLower x) == (map toLower y)) && refsMatch restx resty+refsMatch ((TeX x):restx) ((TeX y):resty) = + ((map toLower x) == (map toLower y)) && refsMatch restx resty+refsMatch ((HtmlInline x):restx) ((HtmlInline y):resty) = + ((map toLower x) == (map toLower y)) && refsMatch restx resty+refsMatch (x:restx) (y:resty) = (x == y) && refsMatch restx resty+refsMatch [] x = null x+refsMatch x [] = null x++--+-- Native format prettyprinting+--+ +-- | Indent string as a block.+indentBy :: Int -- ^ Number of spaces to indent the block + -> Int -- ^ Number of spaces (rel to block) to indent first line+ -> String -- ^ Contents of block to indent+ -> String+indentBy num first [] = ""+indentBy num first str = + let (firstLine:restLines) = lines str + firstLineIndent = num + first+ in (replicate firstLineIndent ' ') ++ firstLine ++ "\n" ++ + (joinWithSep "\n" $ map ((replicate num ' ') ++ ) restLines)++-- | Prettyprint list of Pandoc blocks elements.+prettyBlockList :: Int -- ^ Number of spaces to indent list of blocks+ -> [Block] -- ^ List of blocks+ -> String+prettyBlockList indent [] = indentBy indent 0 "[]"+prettyBlockList indent blocks = indentBy indent (-2) $ "[ " ++ + (joinWithSep "\n, " (map prettyBlock blocks)) ++ " ]"++-- | Prettyprint Pandoc block element.+prettyBlock :: Block -> String+prettyBlock (BlockQuote blocks) = "BlockQuote\n " ++ + (prettyBlockList 2 blocks) +prettyBlock (OrderedList attribs blockLists) = + "OrderedList " ++ show attribs ++ "\n" ++ indentBy 2 0 ("[ " ++ + (joinWithSep ", " $ map (\blocks -> prettyBlockList 2 blocks) + blockLists)) ++ " ]"+prettyBlock (BulletList blockLists) = "BulletList\n" ++ + indentBy 2 0 ("[ " ++ (joinWithSep ", " + (map (\blocks -> prettyBlockList 2 blocks) blockLists))) ++ " ]" +prettyBlock (DefinitionList blockLists) = "DefinitionList\n" ++ + indentBy 2 0 ("[" ++ (joinWithSep ",\n" + (map (\(term, blocks) -> " (" ++ show term ++ ",\n" ++ + indentBy 1 2 (prettyBlockList 2 blocks) ++ " )") blockLists))) ++ " ]" +prettyBlock (Table caption aligns widths header rows) = + "Table " ++ show caption ++ " " ++ show aligns ++ " " ++ + show widths ++ "\n" ++ prettyRow header ++ " [\n" ++ + (joinWithSep ",\n" (map prettyRow rows)) ++ " ]"+ where prettyRow cols = indentBy 2 0 ("[ " ++ (joinWithSep ", "+ (map (\blocks -> prettyBlockList 2 blocks) + cols))) ++ " ]"+prettyBlock block = show block++-- | Prettyprint Pandoc document.+prettyPandoc :: Pandoc -> String+prettyPandoc (Pandoc meta blocks) = "Pandoc " ++ "(" ++ show meta ++ + ")\n" ++ (prettyBlockList 0 blocks) ++ "\n"++--+-- Pandoc block and inline list processing+--++-- | Generate infinite lazy list of markers for an ordered list,+-- depending on list attributes.+orderedListMarkers :: (Int, ListNumberStyle, ListNumberDelim) -> [String]+orderedListMarkers (start, numstyle, numdelim) = + let singleton c = [c]+ seq = case numstyle of+ DefaultStyle -> map show [start..]+ Decimal -> map show [start..]+ UpperAlpha -> drop (start - 1) $ cycle $ + map singleton ['A'..'Z']+ LowerAlpha -> drop (start - 1) $ cycle $+ map singleton ['a'..'z']+ UpperRoman -> map toRomanNumeral [start..]+ LowerRoman -> map (map toLower . toRomanNumeral) [start..]+ inDelim str = case numdelim of+ DefaultDelim -> str ++ "."+ Period -> str ++ "."+ OneParen -> str ++ ")"+ TwoParens -> "(" ++ str ++ ")"+ in map inDelim seq++-- | Normalize a list of inline elements: remove leading and trailing+-- @Space@ elements, collapse double @Space@s into singles, and+-- remove empty Str elements.+normalizeSpaces :: [Inline] -> [Inline]+normalizeSpaces [] = []+normalizeSpaces list = + let removeDoubles [] = []+ removeDoubles (Space:Space:rest) = removeDoubles (Space:rest)+ removeDoubles (Space:(Str ""):Space:rest) = removeDoubles (Space:rest)+ removeDoubles ((Str ""):rest) = removeDoubles rest + removeDoubles (x:rest) = x:(removeDoubles rest)+ removeLeading (Space:xs) = removeLeading xs+ removeLeading x = x+ removeTrailing [] = []+ removeTrailing lst = if (last lst == Space)+ then init lst+ else lst+ in removeLeading $ removeTrailing $ removeDoubles list++-- | Change final list item from @Para@ to @Plain@ if the list should +-- be compact.+compactify :: [[Block]] -- ^ List of list items (each a list of blocks)+ -> [[Block]]+compactify [] = []+compactify items =+ let final = last items+ others = init items+ in case final of+ [Para a] -> if any containsPara others+ then items+ else others ++ [[Plain a]]+ otherwise -> items++containsPara :: [Block] -> Bool+containsPara [] = False+containsPara ((Para a):rest) = True+containsPara ((BulletList items):rest) = any containsPara items ||+ containsPara rest+containsPara ((OrderedList _ items):rest) = any containsPara items ||+ containsPara rest+containsPara ((DefinitionList items):rest) = any containsPara (map snd items) ||+ containsPara rest+containsPara (x:rest) = containsPara rest++-- | Data structure for defining hierarchical Pandoc documents+data Element = Blk Block + | Sec [Inline] [Element] deriving (Eq, Read, Show)++-- | Returns @True@ on Header block with at least the specified level+headerAtLeast :: Int -> Block -> Bool+headerAtLeast level (Header x _) = x <= level+headerAtLeast level _ = False++-- | Convert list of Pandoc blocks into (hierarchical) list of Elements+hierarchicalize :: [Block] -> [Element]+hierarchicalize [] = []+hierarchicalize (block:rest) = + case block of+ (Header level title) -> + let (thisSection, rest') = break (headerAtLeast level) rest+ in (Sec title (hierarchicalize thisSection)):(hierarchicalize rest') + x -> (Blk x):(hierarchicalize rest)++-- | True if block is a Header block.+isHeaderBlock :: Block -> Bool+isHeaderBlock (Header _ _) = True+isHeaderBlock _ = False++--+-- Writer options+--++-- | Options for writers+data WriterOptions = WriterOptions+ { writerStandalone :: Bool -- ^ Include header and footer+ , writerHeader :: String -- ^ Header for the document+ , writerTitlePrefix :: String -- ^ Prefix for HTML titles+ , writerTabStop :: Int -- ^ Tabstop for conversion btw spaces and tabs+ , writerTableOfContents :: Bool -- ^ Include table of contents+ , writerS5 :: Bool -- ^ We're writing S5 + , writerUseASCIIMathML :: Bool -- ^ Use ASCIIMathML+ , writerASCIIMathMLURL :: Maybe String -- ^ URL to asciiMathML.js + , writerIgnoreNotes :: Bool -- ^ Ignore footnotes (used in making toc)+ , writerIncremental :: Bool -- ^ Incremental S5 lists+ , writerNumberSections :: Bool -- ^ Number sections in LaTeX+ , writerIncludeBefore :: String -- ^ String to include before the body+ , writerIncludeAfter :: String -- ^ String to include after the body+ , writerStrictMarkdown :: Bool -- ^ Use strict markdown syntax+ , writerReferenceLinks :: Bool -- ^ Use reference links in writing markdown, rst+ } deriving Show++-- | Default writer options.+defaultWriterOptions = + WriterOptions { writerStandalone = False,+ writerHeader = "",+ writerTitlePrefix = "",+ writerTabStop = 4,+ writerTableOfContents = False,+ writerS5 = False,+ writerUseASCIIMathML = False,+ writerASCIIMathMLURL = Nothing,+ writerIgnoreNotes = False,+ writerIncremental = False,+ writerNumberSections = False,+ writerIncludeBefore = "",+ writerIncludeAfter = "",+ writerStrictMarkdown = False,+ writerReferenceLinks = False }
+ src/Text/Pandoc/UTF8.hs view
@@ -0,0 +1,44 @@+-- | Functions for converting Unicode strings to UTF-8 and vice versa.+-- +-- Taken from <http://www.cse.ogi.edu/~hallgren/Talks/LHiH/base/lib/UTF8.hs>.+-- (c) 2003, OGI School of Science & Engineering, Oregon Health and+-- Science University. +--+-- Modified by Martin Norbaeck+-- to pass illegal UTF-8 sequences through unchanged.+module Text.Pandoc.UTF8 ( + fromUTF8, + toUTF8 + ) where++-- From the Char module supplied with HBC.++-- | Take a UTF-8 string and decode it into a Unicode string.+fromUTF8 :: String -> String+fromUTF8 "" = ""+fromUTF8 (c:c':cs) | '\xc0' <= c && c <= '\xdf' && + '\x80' <= c' && c' <= '\xbf' =+ toEnum ((fromEnum c `mod` 0x20) * 0x40 + fromEnum c' `mod` 0x40) : fromUTF8 cs+fromUTF8 (c:c':c'':cs) | '\xe0' <= c && c <= '\xef' && + '\x80' <= c' && c' <= '\xbf' &&+ '\x80' <= c'' && c'' <= '\xbf' =+ toEnum ((fromEnum c `mod` 0x10 * 0x1000) + (fromEnum c' `mod` 0x40) * 0x40 + fromEnum c'' `mod` 0x40) : fromUTF8 cs+fromUTF8 (c:cs) = c : fromUTF8 cs++-- | Take a Unicode string and encode it as a UTF-8 string.+toUTF8 :: String -> String+toUTF8 "" = ""+toUTF8 (c:cs) =+ if c > '\x0000' && c < '\x0080' then+ c : toUTF8 cs+ else if c < toEnum 0x0800 then+ let i = fromEnum c+ in toEnum (0xc0 + i `div` 0x40) : + toEnum (0x80 + i `mod` 0x40) : + toUTF8 cs+ else+ let i = fromEnum c+ in toEnum (0xe0 + i `div` 0x1000) : + toEnum (0x80 + (i `mod` 0x1000) `div` 0x40) : + toEnum (0x80 + i `mod` 0x40) : + toUTF8 cs
+ src/Text/Pandoc/Writers/ConTeXt.hs view
@@ -0,0 +1,248 @@+{-+Copyright (C) 2007 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.ConTeXt+ Copyright : Copyright (C) 2007 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha + Portability : portable++Conversion of 'Pandoc' format into ConTeXt.+-}+module Text.Pandoc.Writers.ConTeXt ( writeConTeXt ) where+import Text.Pandoc.Definition+import Text.Pandoc.Shared+import Text.Printf ( printf )+import Data.List ( (\\), intersperse )+import Control.Monad.State++type WriterState = Int -- number of next URL reference ++-- | Convert Pandoc to ConTeXt.+writeConTeXt :: WriterOptions -> Pandoc -> String+writeConTeXt options document = evalState (pandocToConTeXt options document) 1 ++pandocToConTeXt :: WriterOptions -> Pandoc -> State WriterState String+pandocToConTeXt options (Pandoc meta blocks) = do+ main <- blockListToConTeXt blocks + let body = writerIncludeBefore options ++ main ++ writerIncludeAfter options+ head <- if writerStandalone options+ then contextHeader options meta+ else return ""+ let toc = if writerTableOfContents options+ then "\\placecontent\n\n"+ else "" + let foot = if writerStandalone options+ then "\n\\stoptext\n"+ else ""+ return $ head ++ toc ++ body ++ foot++-- | Insert bibliographic information into ConTeXt header.+contextHeader :: WriterOptions -- ^ Options, including ConTeXt header+ -> Meta -- ^ Meta with bibliographic information+ -> State WriterState String+contextHeader options (Meta title authors date) = do+ titletext <- if null title+ then return "" + else inlineListToConTeXt title+ let authorstext = if null authors+ then ""+ else if length authors == 1+ then stringToConTeXt $ head authors+ else stringToConTeXt $ (joinWithSep ", " $+ init authors) ++ " & " ++ last authors+ let datetext = if date == ""+ then "" + else stringToConTeXt date+ let titleblock = "\\doctitle{" ++ titletext ++ "}\n\+ \ \\author{" ++ authorstext ++ "}\n\+ \ \\date{" ++ datetext ++ "}\n\n"+ let setupheads = if (writerNumberSections options)+ then "\\setupheads[sectionnumber=yes, style=\\bf]\n" + else "\\setupheads[sectionnumber=no, style=\\bf]\n"+ let header = writerHeader options+ return $ header ++ setupheads ++ titleblock ++ "\\starttext\n\\maketitle\n\n"++-- escape things as needed for ConTeXt++escapeCharForConTeXt :: Char -> String+escapeCharForConTeXt ch =+ case ch of+ '{' -> "\\letteropenbrace{}"+ '}' -> "\\letterclosebrace{}"+ '\\' -> "\\letterbackslash{}"+ '$' -> "\\$"+ '|' -> "\\letterbar{}"+ '^' -> "\\letterhat{}"+ '%' -> "\\%"+ '~' -> "\\lettertilde{}"+ '&' -> "\\&"+ '#' -> "\\#"+ '<' -> "\\letterless{}"+ '>' -> "\\lettermore{}"+ '_' -> "\\letterunderscore{}"+ x -> [x]++-- | Escape string for ConTeXt+stringToConTeXt :: String -> String+stringToConTeXt = concatMap escapeCharForConTeXt++-- | Convert Pandoc block element to ConTeXt.+blockToConTeXt :: Block -> State WriterState String +blockToConTeXt Null = return ""+blockToConTeXt (Plain lst) = inlineListToConTeXt lst >>= return . (++ "\n")+blockToConTeXt (Para lst) = inlineListToConTeXt lst >>= return . (++ "\n\n")+blockToConTeXt (BlockQuote lst) = do+ contents <- blockListToConTeXt lst+ return $ "\\startblockquote\n" ++ contents ++ "\\stopblockquote\n\n"+blockToConTeXt (CodeBlock str) = + return $ "\\starttyping\n" ++ str ++ "\n\\stoptyping\n"+blockToConTeXt (RawHtml str) = return ""+blockToConTeXt (BulletList lst) = do + contents <- mapM listItemToConTeXt lst+ return $ "\\startltxitem\n" ++ concat contents ++ "\\stopltxitem\n"+blockToConTeXt (OrderedList attribs lst) = case attribs of+ (1, DefaultStyle, DefaultDelim) -> do+ contents <- mapM listItemToConTeXt lst+ return $ "\\startltxenum\n" ++ concat contents ++ "\\stopltxenum\n"+ _ -> do+ let markers = take (length lst) $ orderedListMarkers attribs+ contents <- zipWithM orderedListItemToConTeXt markers lst+ let markerWidth = maximum $ map length markers + let markerWidth' = if markerWidth < 3+ then ""+ else "[width=" ++ + show ((markerWidth + 2) `div` 2) ++ "em]"+ return $ "\\startitemize" ++ markerWidth' ++ "\n" ++ concat contents ++ + "\\stopitemize\n"+blockToConTeXt (DefinitionList lst) =+ mapM defListItemToConTeXt lst >>= return . (++ "\n") . concat+blockToConTeXt HorizontalRule = return "\\thinrule\n\n"+blockToConTeXt (Header level lst) = do+ contents <- inlineListToConTeXt lst+ return $ if level > 0 && level <= 3+ then "\\" ++ concat (replicate (level - 1) "sub") ++ + "section{" ++ contents ++ "}\n\n"+ else contents ++ "\n\n"+blockToConTeXt (Table caption aligns widths heads rows) = do+ let colWidths = map printDecimal widths+ let colDescriptor colWidth alignment = (case alignment of+ AlignLeft -> 'l' + AlignRight -> 'r'+ AlignCenter -> 'c'+ AlignDefault -> 'l'):+ "p(" ++ colWidth ++ "\\textwidth)|"+ let colDescriptors = "|" ++ (concat $ + zipWith colDescriptor colWidths aligns)+ headers <- tableRowToConTeXt heads + captionText <- inlineListToConTeXt caption + let captionText' = if null caption then "none" else captionText+ rows' <- mapM tableRowToConTeXt rows + return $ "\\placetable[here]{" ++ captionText' ++ "}\n\\starttable[" ++ + colDescriptors ++ "]\n" ++ "\\HL\n" ++ headers ++ "\\HL\n" ++ + concat rows' ++ "\\HL\n\\stoptable\n\n" ++printDecimal :: Float -> String+printDecimal = printf "%.2f" ++tableRowToConTeXt cols = do+ cols' <- mapM blockListToConTeXt cols+ return $ "\\NC " ++ (concat $ intersperse "\\NC " cols') ++ "\\NC\\AR\n"++listItemToConTeXt list = do+ contents <- blockListToConTeXt list+ return $ "\\item " ++ contents++orderedListItemToConTeXt marker list = do+ contents <- blockListToConTeXt list+ return $ "\\sym{" ++ marker ++ "} " ++ contents++defListItemToConTeXt (term, def) = do+ term' <- inlineListToConTeXt term+ def' <- blockListToConTeXt def+ return $ "\\startdescr{" ++ term' ++ "}\n" +++ def' ++ "\n\\stopdescr\n"++-- | Convert list of block elements to ConTeXt.+blockListToConTeXt :: [Block] -> State WriterState String+blockListToConTeXt lst = mapM blockToConTeXt lst >>= return . concat++-- | Convert list of inline elements to ConTeXt.+inlineListToConTeXt :: [Inline] -- ^ Inlines to convert+ -> State WriterState String+inlineListToConTeXt lst = mapM inlineToConTeXt lst >>= return . concat++isQuoted :: Inline -> Bool+isQuoted (Quoted _ _) = True+isQuoted Apostrophe = True+isQuoted _ = False++-- | Convert inline element to ConTeXt+inlineToConTeXt :: Inline -- ^ Inline to convert+ -> State WriterState String+inlineToConTeXt (Emph lst) = do+ contents <- inlineListToConTeXt lst+ return $ "{\\em " ++ contents ++ "}" +inlineToConTeXt (Strong lst) = do+ contents <- inlineListToConTeXt lst+ return $ "{\\bf " ++ contents ++ "}" +inlineToConTeXt (Strikeout lst) = do+ contents <- inlineListToConTeXt lst+ return $ "\\overstrikes{" ++ contents ++ "}" +inlineToConTeXt (Superscript lst) = do+ contents <- inlineListToConTeXt lst+ return $ "\\high{" ++ contents ++ "}" +inlineToConTeXt (Subscript lst) = do+ contents <- inlineListToConTeXt lst+ return $ "\\low{" ++ contents ++ "}" +inlineToConTeXt (Code str) = return $ "\\type{" ++ str ++ "}"+inlineToConTeXt (Quoted SingleQuote lst) = do+ contents <- inlineListToConTeXt lst+ return $ "\\quote{" ++ contents ++ "}"+inlineToConTeXt (Quoted DoubleQuote lst) = do+ contents <- inlineListToConTeXt lst+ return $ "\\quotation{" ++ contents ++ "}"+inlineToConTeXt Apostrophe = return "'"+inlineToConTeXt EmDash = return "---"+inlineToConTeXt EnDash = return "--"+inlineToConTeXt Ellipses = return "\\ldots{}"+inlineToConTeXt (Str str) = return $ stringToConTeXt str+inlineToConTeXt (TeX str) = return str+inlineToConTeXt (HtmlInline str) = return ""+inlineToConTeXt (LineBreak) = return "\\crlf\n"+inlineToConTeXt Space = return " "+inlineToConTeXt (Link [Code str] (src, tit)) = -- since ConTeXt has its own + inlineToConTeXt (Link [Str str] (src, tit)) -- way of printing links... +inlineToConTeXt (Link text (src, _)) = do+ next <- get+ put (next + 1)+ let ref = show next+ label <- inlineListToConTeXt text+ return $ "\\useurl[" ++ ref ++ "][" ++ src ++ "][][" ++ label ++ + "]\\from[" ++ ref ++ "]" +inlineToConTeXt (Image alternate (src, tit)) = do+ alt <- inlineListToConTeXt alternate+ return $ "\\placefigure\n[]\n[fig:" ++ alt ++ "]\n{" +++ tit ++ "}\n{\\externalfigure[" ++ src ++ "]}" +inlineToConTeXt (Note contents) = do+ contents' <- blockListToConTeXt contents+ return $ "\\footnote{" ++ contents' ++ "}"+
+ src/Text/Pandoc/Writers/DefaultHeaders.hs view
@@ -0,0 +1,59 @@+----------------------------------------------------+-- Do not edit this file by hand. Edit +-- 'templates/DefaultHeaders.hs'+-- and run ./fillTemplates.pl Text/Pandoc/Writers/DefaultHeaders.hs+----------------------------------------------------++{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.DefaultHeaders+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Default headers for Pandoc writers.+-}+module Text.Pandoc.Writers.DefaultHeaders (+ defaultLaTeXHeader,+ defaultConTeXtHeader,+ defaultDocbookHeader,+ defaultS5Header,+ defaultRTFHeader+ ) where+import Text.Pandoc.Writers.S5++defaultLaTeXHeader :: String+defaultLaTeXHeader = "\\documentclass{article}\n\\usepackage[mathletters]{ucs}\n\\usepackage[utf8x]{inputenc}\n\\setlength{\\parindent}{0pt}\n\\setlength{\\parskip}{6pt plus 2pt minus 1pt}\n"++defaultConTeXtHeader :: String+defaultConTeXtHeader = "\\enableregime[utf] % use UTF-8\n\n\\setupcolors[state=start]\n\\setupinteraction[state=start, color=middlered] % needed for hyperlinks\n\n\\setuppapersize[letter][letter] % use letter paper\n\\setuplayout[width=middle, backspace=1.5in, cutspace=1.5in,\n height=middle, header=0.75in, footer=0.75in] % page layout\n\\setuppagenumbering[location={footer,center}] % number pages\n\\setupbodyfont[11pt] % 11pt font\n\\setupwhitespace[medium] % inter-paragraph spacing\n\n\\setuphead[section][style=\\tfc]\n\\setuphead[subsection][style=\\tfb]\n\\setuphead[subsubsection][style=\\bf]\n\n% define title block commands\n\\unprotect\n\\def\\doctitle#1{\\gdef\\@title{#1}}\n\\def\\author#1{\\gdef\\@author{#1}}\n\\def\\date#1{\\gdef\\@date{#1}}\n\\date{\\currentdate} % Default to today unless specified otherwise.\n\\def\\maketitle{%\n \\startalignment[center]\n \\blank[2*big]\n {\\tfd \\@title}\n \\blank[3*medium]\n {\\tfa \\@author}\n \\blank[2*medium]\n {\\tfa \\@date}\n \\blank[3*medium]\n \\stopalignment}\n\\protect\n\n% define descr (for definition lists)\n\\definedescription[descr][\n headstyle=bold,style=normal,align=left,location=hanging,\n width=broad,margin=1cm]\n\n% define ltxitem (for bulleted lists) \n\\defineitemgroup[ltxitem][levels=4]\n\\setupitemgroup[ltxitem][1][1]\n\\setupitemgroup[ltxitem][2][2]\n\\setupitemgroup[ltxitem][3][3]\n\\setupitemgroup[ltxitem][4][4,packed]\n\n% define ltxenum (for enumerated lists)\n\\defineitemgroup[ltxenum][levels=4]\n\\setupitemgroup[ltxenum][1][n]\n\\setupitemgroup[ltxenum][2][a]\n\\setupitemgroup[ltxenum][3][r]\n\\setupitemgroup[ltxenum][4][A,packed]\n\n\\setupthinrules[width=15em] % width of horizontal rules\n\n% for block quotations\n\\definestartstop [blockquote]\n [before={\\startnarrower\\switchtobodyfont[11pt]\n \\whitespace\\setupindenting[no]},\n after={\\stopnarrower\\whitespace}]\n\n"++defaultDocbookHeader :: String+defaultDocbookHeader = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE article PUBLIC \"-//OASIS//DTD DocBook XML V4.4//EN\"\n \"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd\">\n"++defaultS5Header :: String+defaultS5Header = s5Meta ++ s5CSS ++ s5Javascript++defaultRTFHeader :: String+defaultRTFHeader = "{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0 \\fswiss Helvetica;}{\\f1 Courier;}}\n{\\colortbl;\\red255\\green0\\blue0;\\red0\\green0\\blue255;}\n\\widowctrl\\hyphauto\n\n"+
+ src/Text/Pandoc/Writers/Docbook.hs view
@@ -0,0 +1,297 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.Docbook+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to Docbook XML.+-}+module Text.Pandoc.Writers.Docbook ( writeDocbook) where+import Text.Pandoc.Definition+import Text.Pandoc.Shared+import Data.List ( isPrefixOf, drop )+import Text.PrettyPrint.HughesPJ hiding ( Str )++--+-- code to format XML+--++-- | Escape one character as needed for XML.+escapeCharForXML :: Char -> String+escapeCharForXML x = case x of+ '&' -> "&"+ '<' -> "<"+ '>' -> ">"+ '"' -> """+ '\160' -> " "+ c -> [c] ++-- | True if the character needs to be escaped.+needsEscaping :: Char -> Bool+needsEscaping c = c `elem` "&<>\"\160"++-- | Escape string as needed for XML. Entity references are not preserved.+escapeStringForXML :: String -> String+escapeStringForXML "" = ""+escapeStringForXML str = + case break needsEscaping str of+ (okay, "") -> okay+ (okay, (c:cs)) -> okay ++ escapeCharForXML c ++ escapeStringForXML cs ++-- | Return a text object with a string of formatted XML attributes. +attributeList :: [(String, String)] -> Doc+attributeList = text . concatMap + (\(a, b) -> " " ++ escapeStringForXML a ++ "=\"" ++ + escapeStringForXML b ++ "\"") ++-- | Put the supplied contents between start and end tags of tagType,+-- with specified attributes and (if specified) indentation.+inTags:: Bool -> String -> [(String, String)] -> Doc -> Doc+inTags isIndented tagType attribs contents = + let openTag = char '<' <> text tagType <> attributeList attribs <> + char '>'+ closeTag = text "</" <> text tagType <> char '>'+ in if isIndented+ then openTag $$ nest 2 contents $$ closeTag+ else openTag <> contents <> closeTag++-- | Return a self-closing tag of tagType with specified attributes+selfClosingTag :: String -> [(String, String)] -> Doc+selfClosingTag tagType attribs = + char '<' <> text tagType <> attributeList attribs <> text " />" + +-- | Put the supplied contents between start and end tags of tagType.+inTagsSimple :: String -> Doc -> Doc+inTagsSimple tagType = inTags False tagType []++-- | Put the supplied contents in indented block btw start and end tags.+inTagsIndented :: String -> Doc -> Doc+inTagsIndented tagType = inTags True tagType []++--+-- Docbook writer+--++-- | Convert list of authors to a docbook <author> section+authorToDocbook :: [Char] -> Doc+authorToDocbook name = inTagsIndented "author" $ + if ',' `elem` name+ then -- last name first+ let (lastname, rest) = break (==',') name + firstname = removeLeadingSpace rest in+ inTagsSimple "firstname" (text $ escapeStringForXML firstname) <> + inTagsSimple "surname" (text $ escapeStringForXML lastname) + else -- last name last+ let namewords = words name+ lengthname = length namewords + (firstname, lastname) = case lengthname of+ 0 -> ("","") + 1 -> ("", name)+ n -> (joinWithSep " " (take (n-1) namewords), last namewords)+ in inTagsSimple "firstname" (text $ escapeStringForXML firstname) $$ + inTagsSimple "surname" (text $ escapeStringForXML lastname) ++-- | Convert Pandoc document to string in Docbook format.+writeDocbook :: WriterOptions -> Pandoc -> String+writeDocbook opts (Pandoc (Meta title authors date) blocks) = + let head = if writerStandalone opts+ then text (writerHeader opts)+ else empty+ meta = if writerStandalone opts+ then inTagsIndented "articleinfo" $+ (inTagsSimple "title" (wrap opts title)) $$ + (vcat (map authorToDocbook authors)) $$ + (inTagsSimple "date" (text $ escapeStringForXML date)) + else empty+ elements = hierarchicalize blocks+ before = writerIncludeBefore opts+ after = writerIncludeAfter opts+ body = (if null before then empty else text before) $$+ vcat (map (elementToDocbook opts) elements) $$+ (if null after then empty else text after)+ body' = if writerStandalone opts+ then inTagsIndented "article" (meta $$ body)+ else body + in render $ head $$ body' $$ text ""++-- | Convert an Element to Docbook.+elementToDocbook :: WriterOptions -> Element -> Doc+elementToDocbook opts (Blk block) = blockToDocbook opts block +elementToDocbook opts (Sec title elements) =+ -- Docbook doesn't allow sections with no content, so insert some if needed+ let elements' = if null elements+ then [Blk (Para [])]+ else elements+ in inTagsIndented "section" $+ inTagsSimple "title" (wrap opts title) $$+ vcat (map (elementToDocbook opts) elements') ++-- | Convert a list of Pandoc blocks to Docbook.+blocksToDocbook :: WriterOptions -> [Block] -> Doc+blocksToDocbook opts = vcat . map (blockToDocbook opts)++-- | Auxiliary function to convert Plain block to Para.+plainToPara (Plain x) = Para x+plainToPara x = x++-- | Convert a list of pairs of terms and definitions into a list of +-- Docbook varlistentrys.+deflistItemsToDocbook :: WriterOptions -> [([Inline],[Block])] -> Doc+deflistItemsToDocbook opts items = + vcat $ map (\(term, def) -> deflistItemToDocbook opts term def) items++-- | Convert a term and a list of blocks into a Docbook varlistentry.+deflistItemToDocbook :: WriterOptions -> [Inline] -> [Block] -> Doc+deflistItemToDocbook opts term def =+ let def' = map plainToPara def+ in inTagsIndented "varlistentry" $+ inTagsIndented "term" (inlinesToDocbook opts term) $$+ inTagsIndented "listitem" (blocksToDocbook opts def')++-- | Convert a list of lists of blocks to a list of Docbook list items.+listItemsToDocbook :: WriterOptions -> [[Block]] -> Doc+listItemsToDocbook opts items = vcat $ map (listItemToDocbook opts) items++-- | Convert a list of blocks into a Docbook list item.+listItemToDocbook :: WriterOptions -> [Block] -> Doc+listItemToDocbook opts item =+ inTagsIndented "listitem" $ blocksToDocbook opts $ map plainToPara item++-- | Convert a Pandoc block element to Docbook.+blockToDocbook :: WriterOptions -> Block -> Doc+blockToDocbook opts Null = empty+blockToDocbook opts (Plain lst) = wrap opts lst+blockToDocbook opts (Para lst) = inTagsIndented "para" $ wrap opts lst+blockToDocbook opts (BlockQuote blocks) =+ inTagsIndented "blockquote" $ blocksToDocbook opts blocks+blockToDocbook opts (CodeBlock str) = + text "<screen>\n" <> text (escapeStringForXML str) <> text "\n</screen>"+blockToDocbook opts (BulletList lst) = + inTagsIndented "itemizedlist" $ listItemsToDocbook opts lst +blockToDocbook opts (OrderedList _ []) = empty +blockToDocbook opts (OrderedList (start, numstyle, numdelim) (first:rest)) =+ let attribs = case numstyle of+ DefaultStyle -> []+ Decimal -> [("numeration", "arabic")]+ UpperAlpha -> [("numeration", "upperalpha")]+ LowerAlpha -> [("numeration", "loweralpha")]+ UpperRoman -> [("numeration", "upperroman")]+ LowerRoman -> [("numeration", "lowerroman")]+ items = if start == 1+ then listItemsToDocbook opts (first:rest)+ else (inTags True "listitem" [("override",show start)]+ (blocksToDocbook opts $ map plainToPara first)) $$ + listItemsToDocbook opts rest + in inTags True "orderedlist" attribs items+blockToDocbook opts (DefinitionList lst) = + inTagsIndented "variablelist" $ deflistItemsToDocbook opts lst +blockToDocbook opts (RawHtml str) = text str -- raw XML block +blockToDocbook opts HorizontalRule = empty -- not semantic+blockToDocbook opts (Table caption aligns widths headers rows) =+ let alignStrings = map alignmentToString aligns+ captionDoc = if null caption+ then empty+ else inTagsIndented "caption" + (inlinesToDocbook opts caption)+ tableType = if isEmpty captionDoc then "informaltable" else "table"+ in inTagsIndented tableType $ captionDoc $$+ (colHeadsToDocbook opts alignStrings widths headers) $$ + (vcat $ map (tableRowToDocbook opts alignStrings) rows)++colHeadsToDocbook opts alignStrings widths headers =+ let heads = zipWith3 (\align width item -> + tableItemToDocbook opts "th" align width item) + alignStrings widths headers+ in inTagsIndented "tr" $ vcat heads++alignmentToString alignment = case alignment of+ AlignLeft -> "left"+ AlignRight -> "right"+ AlignCenter -> "center"+ AlignDefault -> "left"++tableRowToDocbook opts aligns cols = inTagsIndented "tr" $ + vcat $ zipWith3 (tableItemToDocbook opts "td") aligns (repeat 0) cols++tableItemToDocbook opts tag align width item =+ let attrib = [("align", align)] ++ + if width /= 0+ then [("style", "{width: " ++ + show (truncate (100*width)) ++ "%;}")]+ else [] + in inTags True tag attrib $ vcat $ map (blockToDocbook opts) item++-- | Take list of inline elements and return wrapped doc.+wrap :: WriterOptions -> [Inline] -> Doc+wrap opts lst = fsep $ map (inlinesToDocbook opts) (splitBy Space lst)++-- | Convert a list of inline elements to Docbook.+inlinesToDocbook :: WriterOptions -> [Inline] -> Doc+inlinesToDocbook opts lst = hcat $ map (inlineToDocbook opts) lst++-- | Convert an inline element to Docbook.+inlineToDocbook :: WriterOptions -> Inline -> Doc+inlineToDocbook opts (Str str) = text $ escapeStringForXML str +inlineToDocbook opts (Emph lst) = + inTagsSimple "emphasis" $ inlinesToDocbook opts lst+inlineToDocbook opts (Strong lst) = + inTags False "emphasis" [("role", "strong")] $ inlinesToDocbook opts lst+inlineToDocbook opts (Strikeout lst) = + inTags False "emphasis" [("role", "strikethrough")] $+ inlinesToDocbook opts lst+inlineToDocbook opts (Superscript lst) = + inTagsSimple "superscript" $ inlinesToDocbook opts lst+inlineToDocbook opts (Subscript lst) = + inTagsSimple "subscript" $ inlinesToDocbook opts lst+inlineToDocbook opts (Quoted _ lst) = + inTagsSimple "quote" $ inlinesToDocbook opts lst+inlineToDocbook opts Apostrophe = char '\''+inlineToDocbook opts Ellipses = text "…"+inlineToDocbook opts EmDash = text "—" +inlineToDocbook opts EnDash = text "–" +inlineToDocbook opts (Code str) = + inTagsSimple "literal" $ text (escapeStringForXML str)+inlineToDocbook opts (TeX str) = inlineToDocbook opts (Code str)+inlineToDocbook opts (HtmlInline str) = empty+inlineToDocbook opts LineBreak = text $ "<literallayout></literallayout>" +inlineToDocbook opts Space = char ' '+inlineToDocbook opts (Link txt (src, tit)) =+ if isPrefixOf "mailto:" src+ then let src' = drop 7 src+ emailLink = inTagsSimple "email" $ text $ + escapeStringForXML $ src'+ in if txt == [Code src']+ then emailLink+ else inlinesToDocbook opts txt <+> char '(' <> emailLink <> + char ')'+ else inTags False "ulink" [("url", src)] $ inlinesToDocbook opts txt+inlineToDocbook opts (Image alt (src, tit)) = + let titleDoc = if null tit+ then empty+ else inTagsIndented "objectinfo" $+ inTagsIndented "title" (text $ escapeStringForXML tit)+ in inTagsIndented "inlinemediaobject" $ inTagsIndented "imageobject" $+ titleDoc $$ selfClosingTag "imagedata" [("fileref", src)] +inlineToDocbook opts (Note contents) = + inTagsIndented "footnote" $ blocksToDocbook opts contents
+ src/Text/Pandoc/Writers/HTML.hs view
@@ -0,0 +1,446 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.HTML + Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to HTML.+-}+module Text.Pandoc.Writers.HTML ( writeHtml , writeHtmlString ) where+import Text.Pandoc.Definition+import Text.Pandoc.ASCIIMathML+import Text.Pandoc.CharacterReferences ( decodeCharacterReferences )+import Text.Pandoc.Shared+import Text.Regex ( mkRegex, matchRegex )+import Numeric ( showHex )+import Data.Char ( ord, toLower )+import Data.List ( isPrefixOf, intersperse )+import qualified Data.Set as S+import Control.Monad.State+import Text.XHtml.Transitional++data WriterState = WriterState+ { stNotes :: [Html] -- ^ List of notes+ , stIds :: [String] -- ^ List of header identifiers+ , stMath :: Bool -- ^ Math is used in document+ , stCSS :: S.Set String -- ^ CSS to include in header+ } deriving Show++defaultWriterState :: WriterState+defaultWriterState = WriterState {stNotes= [], stIds = [], + stMath = False, stCSS = S.empty}++-- | Convert Pandoc document to Html string.+writeHtmlString :: WriterOptions -> Pandoc -> String+writeHtmlString opts = + if writerStandalone opts+ then renderHtml . writeHtml opts+ else renderHtmlFragment . writeHtml opts++-- | Convert Pandoc document to Html structure.+writeHtml :: WriterOptions -> Pandoc -> Html+writeHtml opts (Pandoc (Meta tit authors date) blocks) = + let titlePrefix = writerTitlePrefix opts+ topTitle = evalState (inlineListToHtml opts tit) defaultWriterState+ topTitle' = if null titlePrefix+ then topTitle+ else titlePrefix +++ " - " +++ topTitle+ metadata = thetitle topTitle' +++ + meta ! [httpequiv "Content-Type", + content "text/html; charset=UTF-8"] ++++ meta ! [name "generator", content "pandoc"] ++++ (toHtmlFromList $ + map (\a -> meta ! [name "author", content a]) authors) ++++ (if null date+ then noHtml+ else meta ! [name "date", content date])+ titleHeader = if writerStandalone opts && not (null tit) && + not (writerS5 opts)+ then h1 ! [theclass "title"] $ topTitle+ else noHtml+ headerBlocks = filter isHeaderBlock blocks+ ids = uniqueIdentifiers $ + map (\(Header _ lst) -> lst) headerBlocks+ toc = if writerTableOfContents opts + then tableOfContents opts headerBlocks ids+ else noHtml+ (blocks', newstate) = + runState (blockListToHtml opts blocks)+ (defaultWriterState {stIds = ids})+ cssLines = stCSS newstate+ css = if S.null cssLines+ then noHtml+ else style ! [thetype "text/css"] $ primHtml $+ '\n':(unlines $ S.toList cssLines)+ math = if stMath newstate+ then case writerASCIIMathMLURL opts of+ Just path -> script ! [src path, + thetype "text/javascript"] $+ noHtml+ Nothing -> primHtml asciiMathMLScript+ else noHtml+ head = header $ metadata +++ math +++ css +++ + primHtml (writerHeader opts)+ notes = reverse (stNotes newstate)+ before = primHtml $ writerIncludeBefore opts+ after = primHtml $ writerIncludeAfter opts+ thebody = before +++ titleHeader +++ toc +++ blocks' ++++ footnoteSection opts notes +++ after+ in if writerStandalone opts+ then head +++ body thebody+ else thebody++-- | Construct table of contents from list of header blocks and identifiers.+-- Assumes there are as many identifiers as header blocks.+tableOfContents :: WriterOptions -> [Block] -> [String] -> Html+tableOfContents opts headers ids =+ let opts' = opts { writerIgnoreNotes = True }+ contentsTree = hierarchicalize headers+ contents = evalState (mapM (elementToListItem opts') contentsTree) + (defaultWriterState {stIds = ids})+ in thediv ! [identifier "toc"] $ unordList contents++-- | Converts an Element to a list item for a table of contents,+-- retrieving the appropriate identifier from state.+elementToListItem :: WriterOptions -> Element -> State WriterState Html+elementToListItem opts (Blk _) = return noHtml+elementToListItem opts (Sec headerText subsecs) = do+ st <- get+ let ids = stIds st+ let (id, rest) = if null ids+ then ("", [])+ else (head ids, tail ids)+ put $ st {stIds = rest}+ txt <- inlineListToHtml opts headerText+ subHeads <- mapM (elementToListItem opts) subsecs+ let subList = if null subHeads+ then noHtml+ else unordList subHeads + return $ (anchor ! [href ("#" ++ id), identifier ("TOC-" ++ id)] $ txt) +++ + subList++-- | Convert list of Note blocks to a footnote <div>.+-- Assumes notes are sorted.+footnoteSection :: WriterOptions -> [Html] -> Html+footnoteSection opts notes =+ if null notes + then noHtml+ else thediv ! [theclass "footnotes"] $ hr +++ (olist << notes)++-- | Obfuscate a "mailto:" link using Javascript.+obfuscateLink :: WriterOptions -> String -> String -> Html+obfuscateLink opts text src =+ let emailRegex = mkRegex "^mailto:([^@]*)@(.*)$"+ src' = map toLower src+ in case (matchRegex emailRegex src') of+ (Just [name, domain]) ->+ let domain' = substitute "." " dot " domain+ at' = obfuscateChar '@'+ (linkText, altText) = + if text == drop 7 src' -- autolink+ then ("'<code>'+e+'</code>'", name ++ " at " ++ domain')+ else ("'" ++ text ++ "'", text ++ " (" ++ name ++ " at " ++ + domain' ++ ")")+ in if writerStrictMarkdown opts+ then -- need to use primHtml or &'s are escaped to & in URL+ primHtml $ "<a href=\"" ++ (obfuscateString src')+ ++ "\">" ++ (obfuscateString text) ++ "</a>"+ else (script ! [thetype "text/javascript"] $+ primHtml ("\n<!--\nh='" ++ + obfuscateString domain ++ "';a='" ++ at' ++ "';n='" ++ + obfuscateString name ++ "';e=n+a+h;\n" +++ "document.write('<a h'+'ref'+'=\"ma'+'ilto'+':'+e+'\">'+" ++ + linkText ++ "+'<\\/'+'a'+'>');\n// -->\n")) +++ + noscript (primHtml $ obfuscateString altText)+ _ -> anchor ! [href src] $ primHtml text -- malformed email++-- | Obfuscate character as entity.+obfuscateChar :: Char -> String+obfuscateChar char = + let num = ord char+ numstr = if even num then show num else "x" ++ showHex num ""+ in "&#" ++ numstr ++ ";"++-- | Obfuscate string using entities.+obfuscateString :: String -> String+obfuscateString = concatMap obfuscateChar . decodeCharacterReferences++-- | True if character is a punctuation character (unicode).+isPunctuation :: Char -> Bool+isPunctuation c =+ let c' = ord c+ in if c `elem` "!\"'()*,-./:;<>?[\\]`{|}~" || c' >= 0x2000 && c' <= 0x206F ||+ c' >= 0xE000 && c' <= 0xE0FF+ then True+ else False++-- | Add CSS for document header.+addToCSS :: String -> State WriterState ()+addToCSS item = do+ st <- get+ let current = stCSS st+ put $ st {stCSS = S.insert item current}++-- | Convert Pandoc inline list to plain text identifier.+inlineListToIdentifier :: [Inline] -> String+inlineListToIdentifier [] = ""+inlineListToIdentifier (x:xs) = + xAsText ++ inlineListToIdentifier xs+ where xAsText = case x of+ Str s -> filter (\c -> c == '-' || not (isPunctuation c)) $+ concat $ intersperse "-" $ words $ map toLower s+ Emph lst -> inlineListToIdentifier lst+ Strikeout lst -> inlineListToIdentifier lst+ Superscript lst -> inlineListToIdentifier lst+ Subscript lst -> inlineListToIdentifier lst+ Strong lst -> inlineListToIdentifier lst+ Quoted _ lst -> inlineListToIdentifier lst+ Code s -> s+ Space -> "-"+ EmDash -> "-"+ EnDash -> "-"+ Apostrophe -> ""+ Ellipses -> ""+ LineBreak -> "-"+ TeX _ -> ""+ HtmlInline _ -> ""+ Link lst _ -> inlineListToIdentifier lst+ Image lst _ -> inlineListToIdentifier lst+ Note _ -> ""++-- | Return unique identifiers for list of inline lists.+uniqueIdentifiers :: [[Inline]] -> [String]+uniqueIdentifiers ls =+ let addIdentifier (nonuniqueIds, uniqueIds) l =+ let new = inlineListToIdentifier l+ matches = length $ filter (== new) nonuniqueIds+ new' = new ++ if matches > 0 then ("-" ++ show matches) else ""+ in (new:nonuniqueIds, new':uniqueIds)+ in reverse $ snd $ foldl addIdentifier ([],[]) ls++-- | Convert Pandoc block element to HTML.+blockToHtml :: WriterOptions -> Block -> State WriterState Html+blockToHtml opts Null = return $ noHtml +blockToHtml opts (Plain lst) = inlineListToHtml opts lst+blockToHtml opts (Para lst) = inlineListToHtml opts lst >>= (return . paragraph)+blockToHtml opts (RawHtml str) = return $ primHtml str+blockToHtml opts (HorizontalRule) = return $ hr+blockToHtml opts (CodeBlock str) = return $ pre $ thecode << (str ++ "\n") + -- the final \n for consistency with Markdown.pl+blockToHtml opts (BlockQuote blocks) =+ -- in S5, treat list in blockquote specially+ -- if default is incremental, make it nonincremental; + -- otherwise incremental+ if writerS5 opts+ then let inc = not (writerIncremental opts) in+ case blocks of + [BulletList lst] -> blockToHtml (opts {writerIncremental = inc})+ (BulletList lst)+ [OrderedList attribs lst] -> + blockToHtml (opts {writerIncremental = inc})+ (OrderedList attribs lst)+ otherwise -> blockListToHtml opts blocks >>= + (return . blockquote)+ else blockListToHtml opts blocks >>= (return . blockquote)+blockToHtml opts (Header level lst) = do + contents <- inlineListToHtml opts lst+ st <- get+ let ids = stIds st+ let (id, rest) = if null ids+ then ("", [])+ else (head ids, tail ids)+ put $ st {stIds = rest}+ let attribs = [identifier id]+ let headerHtml = case level of+ 1 -> h1 contents ! attribs+ 2 -> h2 contents ! attribs+ 3 -> h3 contents ! attribs+ 4 -> h4 contents ! attribs+ 5 -> h5 contents ! attribs+ 6 -> h6 contents ! attribs+ _ -> paragraph contents ! attribs+ return $ if writerTableOfContents opts+ then anchor ! [href ("#TOC-" ++ id)] $ headerHtml+ else headerHtml+blockToHtml opts (BulletList lst) = do+ contents <- mapM (blockListToHtml opts) lst+ let attribs = if writerIncremental opts+ then [theclass "incremental"]+ else []+ return $ unordList ! attribs $ contents+blockToHtml opts (OrderedList (startnum, numstyle, _) lst) = do+ contents <- mapM (blockListToHtml opts) lst+ let numstyle' = camelCaseToHyphenated $ show numstyle+ let attribs = (if writerIncremental opts+ then [theclass "incremental"]+ else []) +++ (if startnum /= 1+ then [start startnum]+ else []) +++ (if numstyle /= DefaultStyle+ then [theclass numstyle']+ else [])+ if numstyle /= DefaultStyle+ then addToCSS $ "ol." ++ numstyle' ++ + " { list-style-type: " ++ + numstyle' ++ "; }"+ else return ()+ return $ ordList ! attribs $ contents+blockToHtml opts (DefinitionList lst) = do+ contents <- mapM (\(term, def) -> do term' <- inlineListToHtml opts term+ def' <- blockListToHtml opts def+ return $ (term', def')) lst+ let attribs = if writerIncremental opts+ then [theclass "incremental"]+ else []+ return $ defList ! attribs $ contents+blockToHtml opts (Table capt aligns widths headers rows) = do+ let alignStrings = map alignmentToString aligns+ captionDoc <- if null capt+ then return noHtml+ else inlineListToHtml opts capt >>= return . caption+ colHeads <- colHeadsToHtml opts alignStrings + widths headers+ rows' <- mapM (tableRowToHtml opts alignStrings) rows+ return $ table $ captionDoc +++ colHeads +++ rows'++colHeadsToHtml opts alignStrings widths headers = do+ heads <- sequence $ zipWith3 + (\align width item -> tableItemToHtml opts th align width item) + alignStrings widths headers+ return $ tr $ toHtmlFromList heads++alignmentToString alignment = case alignment of+ AlignLeft -> "left"+ AlignRight -> "right"+ AlignCenter -> "center"+ AlignDefault -> "left"++tableRowToHtml opts aligns cols = + (sequence $ zipWith3 (tableItemToHtml opts td) aligns (repeat 0) cols) >>=+ return . tr . toHtmlFromList++tableItemToHtml opts tag align' width item = do+ contents <- blockListToHtml opts item+ let attrib = [align align'] ++ + if width /= 0 + then [thestyle ("{width: " ++ show (truncate (100*width)) ++ + "%;}")]+ else [] + return $ tag ! attrib $ contents++blockListToHtml :: WriterOptions -> [Block] -> State WriterState Html+blockListToHtml opts lst = + mapM (blockToHtml opts) lst >>= return . toHtmlFromList++-- | Convert list of Pandoc inline elements to HTML.+inlineListToHtml :: WriterOptions -> [Inline] -> State WriterState Html+inlineListToHtml opts lst = + mapM (inlineToHtml opts) lst >>= return . toHtmlFromList++-- | Convert Pandoc inline element to HTML.+inlineToHtml :: WriterOptions -> Inline -> State WriterState Html+inlineToHtml opts inline =+ case inline of + (Str str) -> return $ stringToHtml str+ (Space) -> return $ stringToHtml " "+ (LineBreak) -> return $ br+ (EmDash) -> return $ primHtmlChar "mdash"+ (EnDash) -> return $ primHtmlChar "ndash"+ (Ellipses) -> return $ primHtmlChar "hellip"+ (Apostrophe) -> return $ primHtmlChar "rsquo"+ (Emph lst) -> inlineListToHtml opts lst >>= return . emphasize+ (Strong lst) -> inlineListToHtml opts lst >>= return . strong+ (Code str) -> return $ thecode << str+ (Strikeout lst) -> addToCSS + ".strikeout { text-decoration: line-through; }" >> + inlineListToHtml opts lst >>=+ return . (thespan ! [theclass "strikeout"])+ (Superscript lst) -> inlineListToHtml opts lst >>= return . sup+ (Subscript lst) -> inlineListToHtml opts lst >>= return . sub+ (Quoted quoteType lst) ->+ let (leftQuote, rightQuote) = case quoteType of+ SingleQuote -> (primHtmlChar "lsquo", + primHtmlChar "rsquo")+ DoubleQuote -> (primHtmlChar "ldquo", + primHtmlChar "rdquo")+ in do contents <- inlineListToHtml opts lst+ return $ leftQuote +++ contents +++ rightQuote+ (TeX str) -> (if writerUseASCIIMathML opts+ then modify (\st -> st {stMath = True})+ else return ()) >> return (stringToHtml str)+ (HtmlInline str) -> return $ primHtml str + (Link [Code str] (src,tit)) | "mailto:" `isPrefixOf` src ->+ return $ obfuscateLink opts str src+ (Link txt (src,tit)) | "mailto:" `isPrefixOf` src -> do+ linkText <- inlineListToHtml opts txt + return $ obfuscateLink opts (show linkText) src+ (Link txt (src,tit)) -> do+ linkText <- inlineListToHtml opts txt+ return $ anchor ! ([href src] ++ + if null tit then [] else [title tit]) $ + linkText+ (Image txt (source,tit)) -> do+ alternate <- inlineListToHtml opts txt+ let alternate' = renderHtmlFragment alternate+ let attributes = [src source, title tit] ++ + if null txt + then [] + else [alt alternate']+ return $ image ! attributes + -- note: null title included, as in Markdown.pl + (Note contents) -> do + st <- get+ let notes = stNotes st+ let number = (length notes) + 1+ let ref = show number+ htmlContents <- blockListToNote opts ref contents + -- push contents onto front of notes+ put $ st {stNotes = (htmlContents:notes)} + return $ anchor ! [href ("#fn" ++ ref),+ theclass "footnoteRef",+ identifier ("fnref" ++ ref)] << + sup << ref++blockListToNote :: WriterOptions -> String -> [Block] -> State WriterState Html+blockListToNote opts ref blocks =+ -- If last block is Para or Plain, include the backlink at the end of+ -- that block. Otherwise, insert a new Plain block with the backlink.+ let backlink = [HtmlInline $ " <a href=\"#fnref" ++ ref ++ + "\" class=\"footnoteBackLink\"" +++ " title=\"Jump back to footnote " ++ ref ++ "\">↩</a>"]+ blocks' = if null blocks+ then []+ else let lastBlock = last blocks+ otherBlocks = init blocks+ in case lastBlock of+ (Para lst) -> otherBlocks +++ [Para (lst ++ backlink)]+ (Plain lst) -> otherBlocks +++ [Plain (lst ++ backlink)]+ _ -> otherBlocks ++ [lastBlock,+ Plain backlink]+ in do contents <- blockListToHtml opts blocks'+ return $ li ! [identifier ("fn" ++ ref)] $ contents+
+ src/Text/Pandoc/Writers/LaTeX.hs view
@@ -0,0 +1,281 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.LaTeX+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha + Portability : portable++Conversion of 'Pandoc' format into LaTeX.+-}+module Text.Pandoc.Writers.LaTeX ( writeLaTeX ) where+import Text.Pandoc.Definition+import Text.Pandoc.Shared+import Text.Printf ( printf )+import Data.List ( (\\), isInfixOf )+import Data.Char ( toLower )+import qualified Data.Set as S+import Control.Monad.State++data WriterState = + WriterState { stIncludes :: S.Set String -- strings to include in header+ , stInNote :: Bool -- @True@ if we're in a note+ , stOLLevel :: Int } -- level of ordered list nesting ++-- | Add line to header.+addToHeader :: String -> State WriterState ()+addToHeader str = do+ st <- get+ let includes = stIncludes st+ put st {stIncludes = S.insert str includes}++-- | Convert Pandoc to LaTeX.+writeLaTeX :: WriterOptions -> Pandoc -> String+writeLaTeX options document = + evalState (pandocToLaTeX options document) $ + WriterState { stIncludes = S.empty, stInNote = False, stOLLevel = 1 } ++pandocToLaTeX :: WriterOptions -> Pandoc -> State WriterState String+pandocToLaTeX options (Pandoc meta blocks) = do+ main <- blockListToLaTeX blocks+ head <- if writerStandalone options+ then latexHeader options meta+ else return ""+ let body = writerIncludeBefore options ++ main +++ writerIncludeAfter options+ let toc = if writerTableOfContents options+ then "\\tableofcontents\n\n"+ else "" + let foot = if writerStandalone options+ then "\n\\end{document}\n"+ else ""+ return $ head ++ toc ++ body ++ foot++-- | Insert bibliographic information into LaTeX header.+latexHeader :: WriterOptions -- ^ Options, including LaTeX header+ -> Meta -- ^ Meta with bibliographic information+ -> State WriterState String+latexHeader options (Meta title authors date) = do+ titletext <- if null title+ then return "" + else do title' <- inlineListToLaTeX title+ return $ "\\title{" ++ title' ++ "}\n"+ extras <- get >>= (return . unlines . S.toList. stIncludes)+ let verbatim = if "\\usepackage{fancyvrb}" `isInfixOf` extras+ then "\\VerbatimFootnotes % allows verbatim text in footnotes\n"+ else ""+ let authorstext = "\\author{" ++ + joinWithSep "\\\\" (map stringToLaTeX authors) ++ "}\n"+ let datetext = if date == ""+ then "" + else "\\date{" ++ stringToLaTeX date ++ "}\n"+ let maketitle = if null title then "" else "\\maketitle\n" + let secnumline = if (writerNumberSections options)+ then "" + else "\\setcounter{secnumdepth}{0}\n" + let baseHeader = writerHeader options+ let header = baseHeader ++ extras+ return $ header ++ secnumline ++ verbatim ++ titletext ++ authorstext +++ datetext ++ "\\begin{document}\n" ++ maketitle ++ "\n"++-- escape things as needed for LaTeX++stringToLaTeX :: String -> String+stringToLaTeX = escapeStringUsing latexEscapes+ where latexEscapes = backslashEscapes "{}$%&_#" ++ + [ ('^', "\\^{}")+ , ('\\', "\\textbackslash{}")+ , ('~', "\\ensuremath{\\sim}")+ , ('|', "\\textbar{}")+ , ('<', "\\textless{}")+ , ('>', "\\textgreater{}")+ ]++-- | Remove all code elements from list of inline elements+-- (because it's illegal to have verbatim inside some command arguments)+deVerb :: [Inline] -> [Inline]+deVerb [] = []+deVerb ((Code str):rest) = + (TeX $ "\\texttt{" ++ stringToLaTeX str ++ "}"):(deVerb rest)+deVerb (other:rest) = other:(deVerb rest)++-- | Convert Pandoc block element to LaTeX.+blockToLaTeX :: Block -- ^ Block to convert+ -> State WriterState String +blockToLaTeX Null = return ""+blockToLaTeX (Plain lst) = inlineListToLaTeX lst >>= return . (++ "\n")+blockToLaTeX (Para lst) = inlineListToLaTeX lst >>= return . (++ "\n\n")+blockToLaTeX (BlockQuote lst) = do+ contents <- blockListToLaTeX lst+ return $ "\\begin{quote}\n" ++ contents ++ "\\end{quote}\n"+blockToLaTeX (CodeBlock str) = do+ st <- get+ if stInNote st+ then do addToHeader "\\usepackage{fancyvrb}"+ return $ "\\begin{Verbatim}\n" ++ str ++ "\n\\end{Verbatim}\n"+ else return $ "\\begin{verbatim}\n" ++ str ++ "\n\\end{verbatim}\n"+blockToLaTeX (RawHtml str) = return ""+blockToLaTeX (BulletList lst) = do+ items <- mapM listItemToLaTeX lst+ return $ "\\begin{itemize}\n" ++ concat items ++ "\\end{itemize}\n"+blockToLaTeX (OrderedList (start, numstyle, numdelim) lst) = do+ st <- get+ let oldlevel = stOLLevel st+ put $ st {stOLLevel = oldlevel + 1}+ items <- mapM listItemToLaTeX lst+ put $ st {stOLLevel = oldlevel}+ exemplar <- if numstyle /= DefaultStyle || numdelim /= DefaultDelim+ then do addToHeader "\\usepackage{enumerate}"+ return $ "[" ++ head (orderedListMarkers (1, numstyle, numdelim)) ++ "]"+ else return ""+ let resetcounter = if start /= 1 && oldlevel <= 4+ then "\\setcounter{enum" ++ + map toLower (toRomanNumeral oldlevel) +++ "}{" ++ show (start - 1) ++ "}\n"+ else ""+ return $ "\\begin{enumerate}" ++ exemplar ++ "\n" +++ resetcounter ++ concat items ++ "\\end{enumerate}\n"+blockToLaTeX (DefinitionList lst) = do+ items <- mapM defListItemToLaTeX lst+ return $ "\\begin{description}\n" ++ concat items ++ "\\end{description}\n"+blockToLaTeX HorizontalRule = return $+ "\\begin{center}\\rule{3in}{0.4pt}\\end{center}\n\n"+blockToLaTeX (Header level lst) = do+ text <- inlineListToLaTeX (deVerb lst)+ return $ if (level > 0) && (level <= 3)+ then "\\" ++ (concat (replicate (level - 1) "sub")) ++ + "section{" ++ text ++ "}\n\n"+ else text ++ "\n\n"+blockToLaTeX (Table caption aligns widths heads rows) = do+ headers <- tableRowToLaTeX heads+ captionText <- inlineListToLaTeX caption+ rows' <- mapM tableRowToLaTeX rows+ let colWidths = map (printf "%.2f") widths+ let colDescriptors = concat $ zipWith+ (\width align -> ">{\\PBS" ++ + (case align of + AlignLeft -> "\\raggedright"+ AlignRight -> "\\raggedleft"+ AlignCenter -> "\\centering"+ AlignDefault -> "\\raggedright") +++ "\\hspace{0pt}}p{" ++ width ++ + "\\columnwidth}")+ colWidths aligns+ let tableBody = "\\begin{tabular}{" ++ colDescriptors ++ "}\n" +++ headers ++ "\\hline\n" ++ concat rows' ++ "\\end{tabular}\n" + let centered str = "\\begin{center}\n" ++ str ++ "\\end{center}\n"+ addToHeader "\\usepackage{array}\n\+ \% This is needed because raggedright in table elements redefines \\\\:\n\+ \\\newcommand{\\PreserveBackslash}[1]{\\let\\temp=\\\\#1\\let\\\\=\\temp}\n\+ \\\let\\PBS=\\PreserveBackslash"+ return $ if null captionText+ then centered tableBody ++ "\n"+ else "\\begin{table}[h]\n" ++ centered tableBody ++ + "\\caption{" ++ captionText ++ "}\n" ++ "\\end{table}\n\n" ++blockListToLaTeX lst = mapM blockToLaTeX lst >>= return . concat++tableRowToLaTeX cols = + mapM blockListToLaTeX cols >>= return . (++ "\\\\\n") . (joinWithSep " & ")++listItemToLaTeX lst = blockListToLaTeX lst >>= return . ("\\item "++)++defListItemToLaTeX (term, def) = do+ term' <- inlineListToLaTeX $ deVerb term+ def' <- blockListToLaTeX def+ return $ "\\item[" ++ term' ++ "] " ++ def'++-- | Convert list of inline elements to LaTeX.+inlineListToLaTeX :: [Inline] -- ^ Inlines to convert+ -> State WriterState String+inlineListToLaTeX lst = mapM inlineToLaTeX lst >>= return . concat++isQuoted :: Inline -> Bool+isQuoted (Quoted _ _) = True+isQuoted Apostrophe = True+isQuoted _ = False++-- | Convert inline element to LaTeX+inlineToLaTeX :: Inline -- ^ Inline to convert+ -> State WriterState String+inlineToLaTeX (Emph lst) = do+ contents <- inlineListToLaTeX $ deVerb lst+ return $ "\\emph{" ++ contents ++ "}"+inlineToLaTeX (Strong lst) = do+ contents <- inlineListToLaTeX $ deVerb lst+ return $ "\\textbf{" ++ contents ++ "}"+inlineToLaTeX (Strikeout lst) = do+ contents <- inlineListToLaTeX $ deVerb lst+ addToHeader "\\usepackage[normalem]{ulem}"+ return $ "\\sout{" ++ contents ++ "}"+inlineToLaTeX (Superscript lst) = do+ contents <- inlineListToLaTeX $ deVerb lst+ return $ "\\textsuperscript{" ++ contents ++ "}"+inlineToLaTeX (Subscript lst) = do+ contents <- inlineListToLaTeX $ deVerb lst+ -- oddly, latex includes \textsuperscript but not \textsubscript+ -- so we have to define it:+ addToHeader "\\newcommand{\\textsubscript}[1]{\\ensuremath{_{\\scriptsize\\textrm{#1}}}}"+ return $ "\\textsubscript{" ++ contents ++ "}"+inlineToLaTeX (Code str) = do+ st <- get+ if stInNote st+ then do addToHeader "\\usepackage{fancyvrb}"+ else return ()+ let chr = ((enumFromTo '!' '~') \\ str) !! 0+ return $ "\\verb" ++ [chr] ++ str ++ [chr]+inlineToLaTeX (Quoted SingleQuote lst) = do+ contents <- inlineListToLaTeX lst+ let s1 = if (not (null lst)) && (isQuoted (head lst)) then "\\," else ""+ let s2 = if (not (null lst)) && (isQuoted (last lst)) then "\\," else ""+ return $ "`" ++ s1 ++ contents ++ s2 ++ "'"+inlineToLaTeX (Quoted DoubleQuote lst) = do+ contents <- inlineListToLaTeX lst+ let s1 = if (not (null lst)) && (isQuoted (head lst)) then "\\," else ""+ let s2 = if (not (null lst)) && (isQuoted (last lst)) then "\\," else ""+ return $ "``" ++ s1 ++ contents ++ s2 ++ "''"+inlineToLaTeX Apostrophe = return "'"+inlineToLaTeX EmDash = return "---"+inlineToLaTeX EnDash = return "--"+inlineToLaTeX Ellipses = return "\\ldots{}"+inlineToLaTeX (Str str) = return $ stringToLaTeX str+inlineToLaTeX (TeX str) = return str+inlineToLaTeX (HtmlInline str) = return ""+inlineToLaTeX (LineBreak) = return "\\\\\n"+inlineToLaTeX Space = return " "+inlineToLaTeX (Link text (src, tit)) = do+ addToHeader "\\usepackage[breaklinks=true]{hyperref}"+ case text of+ [Code x] | x == src -> -- autolink+ return $ "\\url{" ++ x ++ "}"+ _ -> do contents <- inlineListToLaTeX $ deVerb text+ return $ "\\href{" ++ src ++ "}{" ++ contents ++ "}"+inlineToLaTeX (Image alternate (source, tit)) = do+ addToHeader "\\usepackage{graphicx}"+ return $ "\\includegraphics{" ++ source ++ "}" +inlineToLaTeX (Note contents) = do+ st <- get+ put (st {stInNote = True})+ contents' <- blockListToLaTeX contents+ st <- get+ put (st {stInNote = False})+ return $ "\\footnote{" ++ stripTrailingNewlines contents' ++ "}"
+ src/Text/Pandoc/Writers/Man.hs view
@@ -0,0 +1,298 @@+{-+Copyright (C) 2007 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.Man + Copyright : Copyright (C) 2007 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to groff man page format.++-}+module Text.Pandoc.Writers.Man ( writeMan) where+import Text.Pandoc.Definition+import Text.Pandoc.Shared +import Text.Printf ( printf )+import Data.List ( isPrefixOf, drop, nub, intersperse )+import Text.PrettyPrint.HughesPJ hiding ( Str )+import Control.Monad.State++type Notes = [[Block]]+type Preprocessors = [String] -- e.g. "t" for tbl+type WriterState = (Notes, Preprocessors)++-- | Convert Pandoc to Man.+writeMan :: WriterOptions -> Pandoc -> String+writeMan opts document = render $ evalState (pandocToMan opts document) ([],[]) ++-- | Return groff man representation of document.+pandocToMan :: WriterOptions -> Pandoc -> State WriterState Doc+pandocToMan opts (Pandoc meta blocks) = do+ let before = writerIncludeBefore opts+ let after = writerIncludeAfter opts+ let before' = if null before then empty else text before+ let after' = if null after then empty else text after+ (head, foot) <- metaToMan opts meta+ body <- blockListToMan opts blocks+ (notes, preprocessors) <- get+ let preamble = if null preprocessors || not (writerStandalone opts)+ then empty+ else text $ ".\\\" " ++ concat (nub preprocessors)+ notes' <- notesToMan opts (reverse notes)+ return $ preamble $$ head $$ before' $$ body $$ notes' $$ foot $$ after'++-- | Insert bibliographic information into Man header and footer.+metaToMan :: WriterOptions -- ^ Options, including Man header+ -> Meta -- ^ Meta with bibliographic information+ -> State WriterState (Doc, Doc)+metaToMan options (Meta title authors date) = do+ titleText <- inlineListToMan options title+ let (cmdName, rest) = break (== ' ') $ render titleText+ let (title', section) = case reverse cmdName of+ (')':d:'(':xs) | d `elem` ['0'..'9'] -> + (text (reverse xs), char d)+ xs -> (text (reverse xs), doubleQuotes empty) + let extras = map (doubleQuotes . text . removeLeadingTrailingSpace) $+ splitBy '|' rest+ let head = (text ".TH") <+> title' <+> section <+> + doubleQuotes (text date) <+> hsep extras+ let foot = case length authors of+ 0 -> empty+ 1 -> text ".SH AUTHOR" $$ (text $ joinWithSep ", " authors)+ 2 -> text ".SH AUTHORS" $$ (text $ joinWithSep ", " authors)+ return $ if writerStandalone options+ then (head, foot)+ else (empty, empty)++-- | Return man representation of notes.+notesToMan :: WriterOptions -> [[Block]] -> State WriterState Doc+notesToMan opts notes =+ if null notes+ then return empty+ else mapM (\(num, note) -> noteToMan opts num note) (zip [1..] notes) >>= + return . (text ".SH NOTES" $$) . vcat++-- | Return man representation of a note.+noteToMan :: WriterOptions -> Int -> [Block] -> State WriterState Doc+noteToMan opts num note = do+ contents <- blockListToMan opts note+ let marker = text "\n.SS [" <> text (show num) <> char ']'+ return $ marker $$ contents ++wrappedMan :: WriterOptions -> [Inline] -> State WriterState Doc+wrappedMan opts sect = do+ let chunks = splitBy Space sect+ chunks' <- mapM (inlineListToMan opts) chunks+ return $ fsep chunks'++-- | Association list of characters to escape.+manEscapes :: [(Char, String)]+manEscapes = [('\160', "\\ "), ('\'', "\\[aq]")] ++ backslashEscapes "\".@\\"++-- | Escape special characters for Man.+escapeString :: String -> String+escapeString = escapeStringUsing manEscapes++-- | Escape a literal (code) section for Man.+escapeCode :: String -> String+escapeCode = escapeStringUsing (manEscapes ++ backslashEscapes "\t ")++-- | Convert Pandoc block element to man.+blockToMan :: WriterOptions -- ^ Options+ -> Block -- ^ Block element+ -> State WriterState Doc +blockToMan opts Null = return empty+blockToMan opts (Plain inlines) = wrappedMan opts inlines+blockToMan opts (Para inlines) = do+ contents <- wrappedMan opts inlines+ return $ text ".PP" $$ contents +blockToMan opts (RawHtml str) = return $ text str+blockToMan opts HorizontalRule = return $ text $ ".PP\n * * * * *"+blockToMan opts (Header level inlines) = do+ contents <- inlineListToMan opts inlines+ let heading = case level of+ 1 -> ".SH "+ _ -> ".SS "+ return $ text heading <> contents +blockToMan opts (CodeBlock str) = return $+ text ".PP" $$ text "\\f[CR]" $$ + text ((unlines . map (" " ++) . lines) (escapeCode str)) <> text "\\f[]"+blockToMan opts (BlockQuote blocks) = do + contents <- blockListToMan opts blocks+ return $ text ".RS" $$ contents $$ text ".RE"+blockToMan opts (Table caption alignments widths headers rows) = + let aligncode AlignLeft = "l"+ aligncode AlignRight = "r"+ aligncode AlignCenter = "c"+ aligncode AlignDefault = "l"+ in do+ caption' <- inlineListToMan opts caption+ modify (\(notes, preprocessors) -> (notes, "t":preprocessors))+ let iwidths = map (printf "w(%0.2fn)" . (70 *)) widths + -- 78n default width - 8n indent = 70n+ let coldescriptions = text $ joinWithSep " " + (zipWith (\align width -> aligncode align ++ width) + alignments iwidths) ++ "."+ colheadings <- mapM (blockListToMan opts) headers+ let makeRow cols = text "T{" $$ + (vcat $ intersperse (text "T}@T{") cols) $$ + text "T}"+ let colheadings' = makeRow colheadings+ body <- mapM (\row -> do + cols <- mapM (blockListToMan opts) row+ return $ makeRow cols) rows+ return $ text ".PP" $$ caption' $$ + text ".TS" $$ text "tab(@);" $$ coldescriptions $$ + colheadings' $$ char '_' $$ vcat body $$ text ".TE"++blockToMan opts (BulletList items) = do+ contents <- mapM (bulletListItemToMan opts) items+ return (vcat contents) +blockToMan opts (OrderedList attribs items) = do+ let markers = take (length items) $ orderedListMarkers attribs + let indent = 1 + (maximum $ map length markers)+ contents <- mapM (\(num, item) -> orderedListItemToMan opts num indent item) $+ zip markers items + return (vcat contents)+blockToMan opts (DefinitionList items) = do + contents <- mapM (definitionListItemToMan opts) items+ return (vcat contents)++-- | Convert bullet list item (list of blocks) to man.+bulletListItemToMan :: WriterOptions -> [Block] -> State WriterState Doc+bulletListItemToMan opts [] = return empty+bulletListItemToMan opts ((Para first):rest) = + bulletListItemToMan opts ((Plain first):rest)+bulletListItemToMan opts ((Plain first):rest) = do+ first' <- blockToMan opts (Plain first) + rest' <- blockListToMan opts rest+ let first'' = text ".IP \\[bu] 2" $$ first'+ let rest'' = if null rest+ then empty+ else text ".RS 2" $$ rest' $$ text ".RE"+ return (first'' $$ rest'') +bulletListItemToMan opts (first:rest) = do+ first' <- blockToMan opts first+ rest' <- blockListToMan opts rest+ return $ text "\\[bu] .RS 2" $$ first' $$ rest' $$ text ".RE"+ +-- | Convert ordered list item (a list of blocks) to man.+orderedListItemToMan :: WriterOptions -- ^ options+ -> String -- ^ order marker for list item+ -> Int -- ^ number of spaces to indent+ -> [Block] -- ^ list item (list of blocks)+ -> State WriterState Doc+orderedListItemToMan _ _ _ [] = return empty+orderedListItemToMan opts num indent ((Para first):rest) = + orderedListItemToMan opts num indent ((Plain first):rest)+orderedListItemToMan opts num indent (first:rest) = do+ first' <- blockToMan opts first+ rest' <- blockListToMan opts rest+ let num' = printf ("%" ++ show (indent - 1) ++ "s") num+ let first'' = text (".IP \"" ++ num' ++ "\" " ++ show indent) $$ first'+ let rest'' = if null rest+ then empty+ else text ".RS 4" $$ rest' $$ text ".RE"+ return $ first'' $$ rest'' ++-- | Convert definition list item (label, list of blocks) to man.+definitionListItemToMan :: WriterOptions+ -> ([Inline],[Block]) + -> State WriterState Doc+definitionListItemToMan opts (label, items) = do+ labelText <- inlineListToMan opts label+ contents <- if null items+ then return empty+ else do + let (first, rest) = case items of+ ((Para x):y) -> (Plain x,y)+ (x:y) -> (x,y)+ rest' <- mapM (\item -> blockToMan opts item)+ rest >>= (return . vcat)+ first' <- blockToMan opts first+ return $ first' $$ text ".RS" $$ rest' $$ text ".RE"+ return $ text ".TP\n.B " <> labelText $+$ contents++-- | Convert list of Pandoc block elements to man.+blockListToMan :: WriterOptions -- ^ Options+ -> [Block] -- ^ List of block elements+ -> State WriterState Doc +blockListToMan opts blocks =+ mapM (blockToMan opts) blocks >>= (return . vcat)++-- | Convert list of Pandoc inline elements to man.+inlineListToMan :: WriterOptions -> [Inline] -> State WriterState Doc+inlineListToMan opts lst = mapM (inlineToMan opts) lst >>= (return . hcat)++-- | Convert Pandoc inline element to man.+inlineToMan :: WriterOptions -> Inline -> State WriterState Doc+inlineToMan opts (Emph lst) = do + contents <- inlineListToMan opts lst+ return $ text "\\f[I]" <> contents <> text "\\f[]"+inlineToMan opts (Strong lst) = do+ contents <- inlineListToMan opts lst+ return $ text "\\f[B]" <> contents <> text "\\f[]"+inlineToMan opts (Strikeout lst) = do+ contents <- inlineListToMan opts lst+ return $ text "[STRIKEOUT:" <> contents <> char ']'+inlineToMan opts (Superscript lst) = do+ contents <- inlineListToMan opts lst+ return $ char '^' <> contents <> char '^'+inlineToMan opts (Subscript lst) = do+ contents <- inlineListToMan opts lst+ return $ char '~' <> contents <> char '~'+inlineToMan opts (Quoted SingleQuote lst) = do+ contents <- inlineListToMan opts lst+ return $ char '`' <> contents <> char '\''+inlineToMan opts (Quoted DoubleQuote lst) = do+ contents <- inlineListToMan opts lst+ return $ text "\\[lq]" <> contents <> text "\\[rq]"+inlineToMan opts EmDash = return $ text "\\[em]"+inlineToMan opts EnDash = return $ text "\\[en]"+inlineToMan opts Apostrophe = return $ char '\''+inlineToMan opts Ellipses = return $ text "\\&..."+inlineToMan opts (Code str) =+ return $ text $ "\\f[B]" ++ escapeCode str ++ "\\f[]"+inlineToMan opts (Str str) = return $ text $ escapeString str+inlineToMan opts (TeX str) = return $ text $ escapeCode str+inlineToMan opts (HtmlInline str) = return $ text $ escapeCode str +inlineToMan opts (LineBreak) = return $ text "\n.PD 0\n.P\n.PD\n"+inlineToMan opts Space = return $ char ' '+inlineToMan opts (Link txt (src, _)) = do+ linktext <- inlineListToMan opts txt+ let srcSuffix = if isPrefixOf "mailto:" src then drop 7 src else src+ return $ if txt == [Code srcSuffix]+ then char '<' <> text srcSuffix <> char '>' + else linktext <> text " (" <> text src <> char ')' +inlineToMan opts (Image alternate (source, tit)) = do+ let txt = if (null alternate) || (alternate == [Str ""]) || + (alternate == [Str source]) -- to prevent autolinks+ then [Str "image"]+ else alternate+ linkPart <- inlineToMan opts (Link txt (source, tit)) + return $ char '[' <> text "IMAGE: " <> linkPart <> char ']'+inlineToMan opts (Note contents) = do + modify (\(notes, prep) -> (contents:notes, prep)) -- add to notes in state+ (notes, _) <- get+ let ref = show $ (length notes)+ return $ char '[' <> text ref <> char ']'+
+ src/Text/Pandoc/Writers/Markdown.hs view
@@ -0,0 +1,343 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.Markdown + Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to markdown-formatted plain text.++Markdown: <http://daringfireball.net/projects/markdown/>+-}+module Text.Pandoc.Writers.Markdown ( writeMarkdown) where+import Text.Pandoc.Definition+import Text.Pandoc.Shared +import Text.Pandoc.Blocks+import Data.List ( group, isPrefixOf, drop, find, intersperse )+import Text.PrettyPrint.HughesPJ hiding ( Str )+import Control.Monad.State++type Notes = [[Block]]+type Refs = KeyTable+type WriterState = (Notes, Refs)++-- | Convert Pandoc to Markdown.+writeMarkdown :: WriterOptions -> Pandoc -> String+writeMarkdown opts document = + render $ evalState (pandocToMarkdown opts document) ([],[]) ++-- | Return markdown representation of document.+pandocToMarkdown :: WriterOptions -> Pandoc -> State WriterState Doc+pandocToMarkdown opts (Pandoc meta blocks) = do+ let before = writerIncludeBefore opts+ let after = writerIncludeAfter opts+ let before' = if null before then empty else text before+ let after' = if null after then empty else text after+ metaBlock <- metaToMarkdown opts meta+ let head = if writerStandalone opts+ then metaBlock $+$ text (writerHeader opts)+ else empty+ let headerBlocks = filter isHeaderBlock blocks+ let toc = if writerTableOfContents opts + then tableOfContents opts headerBlocks+ else empty+ body <- blockListToMarkdown opts blocks+ (notes, _) <- get+ notes' <- notesToMarkdown opts (reverse notes)+ (_, refs) <- get -- note that the notes may contain refs+ refs' <- keyTableToMarkdown opts (reverse refs)+ return $ head $+$ before' $+$ toc $+$ body $+$ text "" $+$ + notes' $+$ text "" $+$ refs' $+$ after'++-- | Return markdown representation of reference key table.+keyTableToMarkdown :: WriterOptions -> KeyTable -> State WriterState Doc+keyTableToMarkdown opts refs = mapM (keyToMarkdown opts) refs >>= return . vcat+ +-- | Return markdown representation of a reference key. +keyToMarkdown :: WriterOptions + -> ([Inline], (String, String)) + -> State WriterState Doc+keyToMarkdown opts (label, (src, tit)) = do+ label' <- inlineListToMarkdown opts label+ let tit' = if null tit then empty else text $ " \"" ++ tit ++ "\""+ return $ text " " <> char '[' <> label' <> char ']' <> text ": " <>+ text src <> tit' ++-- | Return markdown representation of notes.+notesToMarkdown :: WriterOptions -> [[Block]] -> State WriterState Doc+notesToMarkdown opts notes = + mapM (\(num, note) -> noteToMarkdown opts num note) (zip [1..] notes) >>= + return . vcat++-- | Return markdown representation of a note.+noteToMarkdown :: WriterOptions -> Int -> [Block] -> State WriterState Doc+noteToMarkdown opts num note = do+ contents <- blockListToMarkdown opts note+ let marker = text "[^" <> text (show num) <> text "]:"+ return $ hang marker (writerTabStop opts) contents ++wrappedMarkdown :: WriterOptions -> [Inline] -> State WriterState Doc+wrappedMarkdown opts sect = do+ let chunks = splitBy Space sect+ chunks' <- mapM (inlineListToMarkdown opts) chunks+ return $ fsep chunks'++-- | Escape special characters for Markdown.+escapeString :: String -> String+escapeString = escapeStringUsing markdownEscapes+ where markdownEscapes = ('\160', " "):(backslashEscapes "`<\\*_^~")++-- | Convert bibliographic information into Markdown header.+metaToMarkdown :: WriterOptions -> Meta -> State WriterState Doc+metaToMarkdown opts (Meta title authors date) = do+ title' <- titleToMarkdown opts title+ authors' <- authorsToMarkdown authors+ date' <- dateToMarkdown date+ return $ title' $+$ authors' $+$ date'++titleToMarkdown :: WriterOptions -> [Inline] -> State WriterState Doc+titleToMarkdown opts [] = return empty+titleToMarkdown opts lst = do+ contents <- inlineListToMarkdown opts lst+ return $ text "% " <> contents ++authorsToMarkdown :: [String] -> State WriterState Doc+authorsToMarkdown [] = return empty+authorsToMarkdown lst = return $ + text "% " <> text (joinWithSep ", " (map escapeString lst))++dateToMarkdown :: String -> State WriterState Doc+dateToMarkdown [] = return empty+dateToMarkdown str = return $ text "% " <> text (escapeString str)++-- | Construct table of contents from list of header blocks.+tableOfContents :: WriterOptions -> [Block] -> Doc +tableOfContents opts headers =+ let opts' = opts { writerIgnoreNotes = True }+ contents = BulletList $ map elementToListItem $ hierarchicalize headers+ in evalState (blockToMarkdown opts' contents) ([],[])++-- | Converts an Element to a list item for a table of contents,+elementToListItem :: Element -> [Block]+elementToListItem (Blk _) = []+elementToListItem (Sec headerText subsecs) = [Plain headerText] ++ + if null subsecs+ then []+ else [BulletList $ map elementToListItem subsecs]++-- | Convert Pandoc block element to markdown.+blockToMarkdown :: WriterOptions -- ^ Options+ -> Block -- ^ Block element+ -> State WriterState Doc +blockToMarkdown opts Null = return empty+blockToMarkdown opts (Plain inlines) = wrappedMarkdown opts inlines+blockToMarkdown opts (Para inlines) = do+ contents <- wrappedMarkdown opts inlines+ return $ contents <> text "\n"+blockToMarkdown opts (RawHtml str) = return $ text str+blockToMarkdown opts HorizontalRule = return $ text "\n* * * * *\n"+blockToMarkdown opts (Header level inlines) = do+ contents <- inlineListToMarkdown opts inlines+ return $ text ((replicate level '#') ++ " ") <> contents <> text "\n"+blockToMarkdown opts (CodeBlock str) = return $+ (nest (writerTabStop opts) $ vcat $ map text (lines str)) <> text "\n"+blockToMarkdown opts (BlockQuote blocks) = do+ contents <- blockListToMarkdown opts blocks+ let quotedContents = unlines $ map ("> " ++) $ lines $ render contents+ return $ text quotedContents +blockToMarkdown opts (Table caption aligns widths headers rows) = do+ caption' <- inlineListToMarkdown opts caption+ let caption'' = if null caption+ then empty+ else text "" $+$ (text "Table: " <> caption')+ headers' <- mapM (blockListToMarkdown opts) headers+ let widthsInChars = map (floor . (78 *)) widths+ let alignHeader alignment = case alignment of+ AlignLeft -> leftAlignBlock+ AlignCenter -> centerAlignBlock+ AlignRight -> rightAlignBlock+ AlignDefault -> leftAlignBlock + let makeRow = hsepBlocks . (zipWith alignHeader aligns) . + (zipWith docToBlock widthsInChars)+ let head = makeRow headers'+ rows' <- mapM (\row -> do cols <- mapM (blockListToMarkdown opts) row+ return $ makeRow cols) rows+ let tableWidth = sum widthsInChars+ let maxRowHeight = maximum $ map heightOfBlock (head:rows')+ let isMultilineTable = maxRowHeight > 1+ let underline = hsep $ + map (\width -> text $ replicate width '-') widthsInChars+ let border = if isMultilineTable+ then text $ replicate (sum widthsInChars + (length widthsInChars - 1)) '-'+ else empty+ let spacer = if isMultilineTable+ then text ""+ else empty+ let body = vcat $ intersperse spacer $ map blockToDoc rows'+ return $ (nest 2 $ border $+$ (blockToDoc head) $+$ underline $+$ body $+$ + border $+$ caption'') <> text "\n"+blockToMarkdown opts (BulletList items) = do+ contents <- mapM (bulletListItemToMarkdown opts) items+ return $ (vcat contents) <> text "\n"+blockToMarkdown opts (OrderedList attribs items) = do+ let markers = orderedListMarkers attribs+ let markers' = map (\m -> if length m < 3+ then m ++ replicate (3 - length m) ' '+ else m) markers + contents <- mapM (\(item, num) -> orderedListItemToMarkdown opts item num) $+ zip markers' items + return $ (vcat contents) <> text "\n"+blockToMarkdown opts (DefinitionList items) = do+ contents <- mapM (definitionListItemToMarkdown opts) items+ return $ (vcat contents) <> text "\n"++-- | Convert bullet list item (list of blocks) to markdown.+bulletListItemToMarkdown :: WriterOptions -> [Block] -> State WriterState Doc+bulletListItemToMarkdown opts items = do+ contents <- blockListToMarkdown opts items+ return $ hang (text "- ") (writerTabStop opts) contents++-- | Convert ordered list item (a list of blocks) to markdown.+orderedListItemToMarkdown :: WriterOptions -- ^ options+ -> String -- ^ list item marker+ -> [Block] -- ^ list item (list of blocks)+ -> State WriterState Doc+orderedListItemToMarkdown opts marker items = do+ contents <- blockListToMarkdown opts items+ return $ hang (text marker) (writerTabStop opts) contents ++-- | Convert definition list item (label, list of blocks) to markdown.+definitionListItemToMarkdown :: WriterOptions+ -> ([Inline],[Block]) + -> State WriterState Doc+definitionListItemToMarkdown opts (label, items) = do+ labelText <- inlineListToMarkdown opts label+ let tabStop = writerTabStop opts+ let leader = char ':'+ contents <- mapM (\item -> blockToMarkdown opts item >>= + (\txt -> return (leader $$ nest tabStop txt)))+ items >>= return . vcat+ return $ labelText $+$ contents++-- | Convert list of Pandoc block elements to markdown.+blockListToMarkdown :: WriterOptions -- ^ Options+ -> [Block] -- ^ List of block elements+ -> State WriterState Doc +blockListToMarkdown opts blocks =+ mapM (blockToMarkdown opts) blocks >>= return . vcat++-- | Get reference for target; if none exists, create unique one and return.+-- Prefer label if possible; otherwise, generate a unique key.+getReference :: [Inline] -> Target -> State WriterState [Inline]+getReference label (src, tit) = do+ (_,refs) <- get+ case find ((== (src, tit)) . snd) refs of+ Just (ref, _) -> return ref+ Nothing -> do+ let label' = case find ((== label) . fst) refs of+ Just _ -> -- label is used; generate numerical label+ case find (\n -> not (any (== [Str (show n)])+ (map fst refs))) [1..10000] of+ Just x -> [Str (show x)]+ Nothing -> error "no unique label"+ Nothing -> label+ modify (\(notes, refs) -> (notes, (label', (src,tit)):refs))+ return label'++-- | Convert list of Pandoc inline elements to markdown.+inlineListToMarkdown :: WriterOptions -> [Inline] -> State WriterState Doc+inlineListToMarkdown opts lst =+ mapM (inlineToMarkdown opts) lst >>= return . hcat++-- | Convert Pandoc inline element to markdown.+inlineToMarkdown :: WriterOptions -> Inline -> State WriterState Doc+inlineToMarkdown opts (Emph lst) = do + contents <- inlineListToMarkdown opts lst+ return $ char '*' <> contents <> char '*'+inlineToMarkdown opts (Strong lst) = do+ contents <- inlineListToMarkdown opts lst+ return $ text "**" <> contents <> text "**"+inlineToMarkdown opts (Strikeout lst) = do+ contents <- inlineListToMarkdown opts lst+ return $ text "~~" <> contents <> text "~~"+inlineToMarkdown opts (Superscript lst) = do+ contents <- inlineListToMarkdown opts lst+ let contents' = text $ substitute " " "\\ " $ render contents+ return $ char '^' <> contents' <> char '^'+inlineToMarkdown opts (Subscript lst) = do+ contents <- inlineListToMarkdown opts lst+ let contents' = text $ substitute " " "\\ " $ render contents+ return $ char '~' <> contents' <> char '~'+inlineToMarkdown opts (Quoted SingleQuote lst) = do+ contents <- inlineListToMarkdown opts lst+ return $ char '\'' <> contents <> char '\''+inlineToMarkdown opts (Quoted DoubleQuote lst) = do+ contents <- inlineListToMarkdown opts lst+ return $ char '"' <> contents <> char '"'+inlineToMarkdown opts EmDash = return $ text "--"+inlineToMarkdown opts EnDash = return $ char '-'+inlineToMarkdown opts Apostrophe = return $ char '\''+inlineToMarkdown opts Ellipses = return $ text "..."+inlineToMarkdown opts (Code str) =+ let tickGroups = filter (\s -> '`' `elem` s) $ group str + longest = if null tickGroups+ then 0+ else maximum $ map length tickGroups + marker = replicate (longest + 1) '`' + spacer = if (longest == 0) then "" else " " in+ return $ text (marker ++ spacer ++ str ++ spacer ++ marker)+inlineToMarkdown opts (Str str) = return $ text $ escapeString str+inlineToMarkdown opts (TeX str) = return $ text str+inlineToMarkdown opts (HtmlInline str) = return $ text str +inlineToMarkdown opts (LineBreak) = return $ text " \n"+inlineToMarkdown opts Space = return $ char ' '+inlineToMarkdown opts (Link txt (src, tit)) = do+ linktext <- inlineListToMarkdown opts txt+ let linktitle = if null tit then empty else text $ " \"" ++ tit ++ "\""+ let srcSuffix = if isPrefixOf "mailto:" src then drop 7 src else src+ let useRefLinks = writerReferenceLinks opts+ let useAuto = null tit && txt == [Code srcSuffix]+ ref <- if useRefLinks then getReference txt (src, tit) else return []+ reftext <- inlineListToMarkdown opts ref+ return $ if useAuto+ then char '<' <> text srcSuffix <> char '>' + else if useRefLinks+ then let first = char '[' <> linktext <> char ']'+ second = if txt == ref+ then text "[]"+ else char '[' <> reftext <> char ']'+ in first <> second+ else char '[' <> linktext <> char ']' <> + char '(' <> text src <> linktitle <> char ')' +inlineToMarkdown opts (Image alternate (source, tit)) = do+ let txt = if (null alternate) || (alternate == [Str ""]) || + (alternate == [Str source]) -- to prevent autolinks+ then [Str "image"]+ else alternate+ linkPart <- inlineToMarkdown opts (Link txt (source, tit)) + return $ char '!' <> linkPart+inlineToMarkdown opts (Note contents) = do + modify (\(notes, refs) -> (contents:notes, refs)) -- add to notes in state+ (notes, _) <- get+ let ref = show $ (length notes)+ return $ text "[^" <> text ref <> char ']'
+ src/Text/Pandoc/Writers/RST.hs view
@@ -0,0 +1,329 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.RST + Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to reStructuredText.++reStructuredText: <http://docutils.sourceforge.net/rst.html>+-}+module Text.Pandoc.Writers.RST ( writeRST) where+import Text.Pandoc.Definition+import Text.Pandoc.Shared +import Text.Pandoc.Blocks+import Data.List ( isPrefixOf, isSuffixOf, drop, intersperse )+import Text.PrettyPrint.HughesPJ hiding ( Str )+import Control.Monad.State++type Notes = [[Block]]+type Refs = KeyTable+type WriterState = (Notes, Refs, Refs) -- first Refs is links, second pictures++-- | Convert Pandoc to RST.+writeRST :: WriterOptions -> Pandoc -> String+writeRST opts document = + render $ evalState (pandocToRST opts document) ([],[],[]) ++-- | Return RST representation of document.+pandocToRST :: WriterOptions -> Pandoc -> State WriterState Doc+pandocToRST opts (Pandoc meta blocks) = do+ let before = writerIncludeBefore opts+ let after = writerIncludeAfter opts+ before' = if null before then empty else text before+ after' = if null after then empty else text after+ metaBlock <- metaToRST opts meta+ let head = if (writerStandalone opts)+ then metaBlock $+$ text (writerHeader opts)+ else empty+ body <- blockListToRST opts blocks+ (notes, _, _) <- get+ notes' <- notesToRST opts (reverse notes)+ (_, refs, pics) <- get -- note that the notes may contain refs+ refs' <- keyTableToRST opts (reverse refs)+ pics' <- pictTableToRST opts (reverse pics)+ return $ head $+$ before' $+$ body $+$ notes' $+$ text "" $+$ refs' $+$ + pics' $+$ after'++-- | Return RST representation of reference key table.+keyTableToRST :: WriterOptions -> KeyTable -> State WriterState Doc+keyTableToRST opts refs = mapM (keyToRST opts) refs >>= return . vcat+ +-- | Return RST representation of a reference key. +keyToRST :: WriterOptions + -> ([Inline], (String, String)) + -> State WriterState Doc+keyToRST opts (label, (src, tit)) = do+ label' <- inlineListToRST opts label+ return $ text ".. _" <> label' <> text ": " <> text src++-- | Return RST representation of notes.+notesToRST :: WriterOptions -> [[Block]] -> State WriterState Doc+notesToRST opts notes = + mapM (\(num, note) -> noteToRST opts num note) (zip [1..] notes) >>= + return . vcat++-- | Return RST representation of a note.+noteToRST :: WriterOptions -> Int -> [Block] -> State WriterState Doc+noteToRST opts num note = do+ contents <- blockListToRST opts note+ let marker = text ".. [" <> text (show num) <> text "] "+ return $ hang marker 3 contents ++-- | Return RST representation of picture reference table.+pictTableToRST :: WriterOptions -> KeyTable -> State WriterState Doc+pictTableToRST opts refs = mapM (pictToRST opts) refs >>= return . vcat+ +-- | Return RST representation of a picture substitution reference. +pictToRST :: WriterOptions + -> ([Inline], (String, String)) + -> State WriterState Doc+pictToRST opts (label, (src, _)) = do+ label' <- inlineListToRST opts label+ return $ text ".. " <> char '|' <> label' <> char '|' <> text " image:: " <>+ text src++-- | Take list of inline elements and return wrapped doc.+wrappedRST :: WriterOptions -> [Inline] -> State WriterState Doc+wrappedRST opts inlines = + mapM (wrappedRSTSection opts) (splitBy LineBreak inlines) >>= + return . vcat++wrappedRSTSection :: WriterOptions -> [Inline] -> State WriterState Doc+wrappedRSTSection opts sect = do+ let chunks = splitBy Space sect+ chunks' <- mapM (inlineListToRST opts) chunks+ return $ fsep chunks'++-- | Escape special characters for RST.+escapeString :: String -> String+escapeString = escapeStringUsing (backslashEscapes "`\\|*_")++-- | Convert bibliographic information into RST header.+metaToRST :: WriterOptions -> Meta -> State WriterState Doc+metaToRST opts (Meta title authors date) = do+ title' <- titleToRST opts title+ authors' <- authorsToRST authors+ date' <- dateToRST date+ let toc = if writerTableOfContents opts+ then text "" $+$ text ".. contents::"+ else empty+ return $ title' $+$ authors' $+$ date' $+$ toc++titleToRST :: WriterOptions -> [Inline] -> State WriterState Doc+titleToRST opts [] = return empty+titleToRST opts lst = do+ contents <- inlineListToRST opts lst+ let titleLength = length $ render contents+ let border = text (replicate titleLength '=')+ return $ border $+$ contents $+$ border <> text "\n"++authorsToRST :: [String] -> State WriterState Doc+authorsToRST [] = return empty+authorsToRST (first:rest) = do+ rest' <- authorsToRST rest+ return $ (text ":Author: " <> text first) $+$ rest'++dateToRST :: String -> State WriterState Doc+dateToRST [] = return empty+dateToRST str = return $ text ":Date: " <> text (escapeString str)++-- | Convert Pandoc block element to RST. +blockToRST :: WriterOptions -- ^ Options+ -> Block -- ^ Block element+ -> State WriterState Doc +blockToRST opts Null = return empty+blockToRST opts (Plain inlines) = wrappedRST opts inlines+blockToRST opts (Para [TeX str]) =+ let str' = if "\n" `isSuffixOf` str then str ++ "\n" else str ++ "\n\n" in+ return $ hang (text "\n.. raw:: latex\n") 3 $ vcat $ map text (lines str')+blockToRST opts (Para inlines) = do+ contents <- wrappedRST opts inlines+ return $ contents <> text "\n"+blockToRST opts (RawHtml str) = + let str' = if "\n" `isSuffixOf` str then str ++ "\n" else str ++ "\n\n" in+ return $ hang (text "\n.. raw:: html\n") 3 $ vcat $ map text (lines str')+blockToRST opts HorizontalRule = return $ text "--------------\n"+blockToRST opts (Header level inlines) = do+ contents <- inlineListToRST opts inlines+ let headerLength = length $ render contents+ let headerChar = if level > 5 then ' ' else "=-~^'" !! (level - 1)+ let border = text $ replicate headerLength headerChar+ return $ contents $+$ border <> text "\n"+blockToRST opts (CodeBlock str) = return $ (text "::\n") $+$ + (nest (writerTabStop opts) $ vcat $ map text (lines str)) <> text "\n"+blockToRST opts (BlockQuote blocks) = do+ contents <- blockListToRST opts blocks + return $ (nest (writerTabStop opts) contents) <> text "\n"+blockToRST opts (Table caption aligns widths headers rows) = do+ caption' <- inlineListToRST opts caption+ let caption'' = if null caption+ then empty+ else text "" $+$ (text "Table: " <> caption')+ headers' <- mapM (blockListToRST opts) headers+ let widthsInChars = map (floor . (78 *)) widths+ let alignHeader alignment = case alignment of+ AlignLeft -> leftAlignBlock+ AlignCenter -> centerAlignBlock+ AlignRight -> rightAlignBlock+ AlignDefault -> leftAlignBlock + let hpipeBlocks blocks = hcatBlocks [beg, middle, end] + where height = maximum (map heightOfBlock blocks)+ sep = TextBlock 3 height (replicate height " | ")+ beg = TextBlock 2 height (replicate height "| ")+ end = TextBlock 2 height (replicate height " |")+ middle = hcatBlocks $ intersperse sep blocks+ let makeRow = hpipeBlocks . zipWith docToBlock widthsInChars+ let head = makeRow headers'+ rows' <- mapM (\row -> do cols <- mapM (blockListToRST opts) row+ return $ makeRow cols) rows+ let tableWidth = sum widthsInChars+ let maxRowHeight = maximum $ map heightOfBlock (head:rows')+ let border ch = char '+' <> char ch <>+ (hcat $ intersperse (char ch <> char '+' <> char ch) $ + map (\l -> text $ replicate l ch) widthsInChars) <>+ char ch <> char '+'+ let body = vcat $ intersperse (border '-') $ map blockToDoc rows'+ return $ border '-' $+$ blockToDoc head $+$ border '=' $+$ body $+$ + border '-' $$ caption'' $$ text ""+blockToRST opts (BulletList items) = do+ contents <- mapM (bulletListItemToRST opts) items+ -- ensure that sublists have preceding blank line+ return $ text "" $+$ vcat contents <> text "\n"+blockToRST opts (OrderedList (start, style, delim) items) = do+ let markers = if start == 1 && style == DefaultStyle && delim == DefaultDelim + then take (length items) $ repeat "#."+ else take (length items) $ orderedListMarkers + (start, style, delim)+ let maxMarkerLength = maximum $ map length markers+ let markers' = map (\m -> let s = maxMarkerLength - length m+ in m ++ replicate s ' ') markers+ contents <- mapM (\(item, num) -> orderedListItemToRST opts item num) $+ zip markers' items + -- ensure that sublists have preceding blank line+ return $ text "" $+$ vcat contents <> text "\n"+blockToRST opts (DefinitionList items) = do+ contents <- mapM (definitionListItemToRST opts) items+ return $ (vcat contents) <> text "\n"++-- | Convert bullet list item (list of blocks) to RST.+bulletListItemToRST :: WriterOptions -> [Block] -> State WriterState Doc+bulletListItemToRST opts items = do+ contents <- blockListToRST opts items+ return $ hang (text "- ") (writerTabStop opts) contents++-- | Convert ordered list item (a list of blocks) to RST.+orderedListItemToRST :: WriterOptions -- ^ options+ -> String -- ^ marker for list item+ -> [Block] -- ^ list item (list of blocks)+ -> State WriterState Doc+orderedListItemToRST opts marker items = do+ contents <- blockListToRST opts items+ return $ hang (text marker) (writerTabStop opts) contents ++-- | Convert defintion list item (label, list of blocks) to RST.+definitionListItemToRST :: WriterOptions -> ([Inline], [Block]) -> State WriterState Doc+definitionListItemToRST opts (label, items) = do+ label <- inlineListToRST opts label+ contents <- blockListToRST opts items+ return $ label $+$ nest (writerTabStop opts) contents++-- | Convert list of Pandoc block elements to RST.+blockListToRST :: WriterOptions -- ^ Options+ -> [Block] -- ^ List of block elements+ -> State WriterState Doc +blockListToRST opts blocks =+ mapM (blockToRST opts) blocks >>= return . vcat++-- | Convert list of Pandoc inline elements to RST.+inlineListToRST :: WriterOptions -> [Inline] -> State WriterState Doc+inlineListToRST opts lst = mapM (inlineToRST opts) lst >>= return . hcat++-- | Convert Pandoc inline element to RST.+inlineToRST :: WriterOptions -> Inline -> State WriterState Doc+inlineToRST opts (Emph lst) = do + contents <- inlineListToRST opts lst+ return $ char '*' <> contents <> char '*'+inlineToRST opts (Strong lst) = do+ contents <- inlineListToRST opts lst+ return $ text "**" <> contents <> text "**"+inlineToRST opts (Strikeout lst) = do + contents <- inlineListToRST opts lst+ return $ text "[STRIKEOUT:" <> contents <> char ']'+inlineToRST opts (Superscript lst) = do + contents <- inlineListToRST opts lst+ return $ text "\\ :sup:`" <> contents <> text "`\\ "+inlineToRST opts (Subscript lst) = do + contents <- inlineListToRST opts lst+ return $ text "\\ :sub:`" <> contents <> text "`\\ "+inlineToRST opts (Quoted SingleQuote lst) = do+ contents <- inlineListToRST opts lst+ return $ char '\'' <> contents <> char '\''+inlineToRST opts (Quoted DoubleQuote lst) = do+ contents <- inlineListToRST opts lst+ return $ char '"' <> contents <> char '"'+inlineToRST opts EmDash = return $ text "--"+inlineToRST opts EnDash = return $ char '-'+inlineToRST opts Apostrophe = return $ char '\''+inlineToRST opts Ellipses = return $ text "..."+inlineToRST opts (Code str) = return $ text $ "``" ++ str ++ "``"+inlineToRST opts (Str str) = return $ text $ escapeString str+inlineToRST opts (TeX str) = return $ text str+inlineToRST opts (HtmlInline str) = return empty+inlineToRST opts (LineBreak) = return $ char ' ' -- RST doesn't have linebreaks +inlineToRST opts Space = return $ char ' '+inlineToRST opts (Link [Code str] (src, tit)) | src == str ||+ src == "mailto:" ++ str = do+ let srcSuffix = if isPrefixOf "mailto:" src then drop 7 src else src+ return $ text srcSuffix+inlineToRST opts (Link txt (src, tit)) = do+ let useReferenceLinks = writerReferenceLinks opts+ linktext <- inlineListToRST opts $ normalizeSpaces txt+ if useReferenceLinks+ then do (notes, refs, pics) <- get+ let refs' = if (txt, (src, tit)) `elem` refs+ then refs+ else (txt, (src, tit)):refs+ put (notes, refs', pics)+ return $ char '`' <> linktext <> text "`_"+ else return $ char '`' <> linktext <> text " <" <> text src <> text ">`_"+inlineToRST opts (Image alternate (source, tit)) = do+ (notes, refs, pics) <- get+ let labelsUsed = map fst pics + let txt = if null alternate || alternate == [Str ""] || + alternate `elem` labelsUsed+ then [Str $ "image" ++ show (length refs)]+ else alternate+ let pics' = if (txt, (source, tit)) `elem` pics+ then pics+ else (txt, (source, tit)):pics+ put (notes, refs, pics')+ label <- inlineListToRST opts txt+ return $ char '|' <> label <> char '|'+inlineToRST opts (Note contents) = do + -- add to notes in state+ modify (\(notes, refs, pics) -> (contents:notes, refs, pics))+ (notes, _, _) <- get+ let ref = show $ (length notes)+ return $ text " [" <> text ref <> text "]_"
+ src/Text/Pandoc/Writers/RTF.hs view
@@ -0,0 +1,286 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.RTF+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha + Portability : portable++Conversion of 'Pandoc' documents to RTF (rich text format).+-}+module Text.Pandoc.Writers.RTF ( writeRTF ) where+import Text.Pandoc.Definition+import Text.Pandoc.Shared+import Text.Regex ( matchRegexAll, mkRegex )+import Data.List ( isSuffixOf )+import Data.Char ( ord )++-- | Convert Pandoc to a string in rich text format.+writeRTF :: WriterOptions -> Pandoc -> String+writeRTF options (Pandoc meta blocks) = + let head = if writerStandalone options+ then rtfHeader (writerHeader options) meta + else ""+ toc = if writerTableOfContents options+ then tableOfContents $ filter isHeaderBlock blocks+ else "" + foot = if writerStandalone options then "\n}\n" else "" + body = writerIncludeBefore options ++ + concatMap (blockToRTF 0 AlignDefault) blocks ++ + writerIncludeAfter options+ in head ++ toc ++ body ++ foot++-- | Construct table of contents from list of header blocks.+tableOfContents :: [Block] -> String +tableOfContents headers =+ let contentsTree = hierarchicalize headers+ in concatMap (blockToRTF 0 AlignDefault) $ + [Header 1 [Str "Contents"], + BulletList (map elementToListItem contentsTree)]++elementToListItem :: Element -> [Block]+elementToListItem (Blk _) = []+elementToListItem (Sec sectext subsecs) = [Plain sectext] +++ if null subsecs+ then []+ else [BulletList (map elementToListItem subsecs)]++-- | Convert unicode characters (> 127) into rich text format representation.+handleUnicode :: String -> String+handleUnicode [] = []+handleUnicode (c:cs) =+ if ord c > 127 + then '\\':'u':(show (ord c)) ++ "?" ++ handleUnicode cs+ else c:(handleUnicode cs)++-- | Escape special characters.+escapeSpecial :: String -> String+escapeSpecial = escapeStringUsing (('\t',"\\tab "):(backslashEscapes "{\\}"))++-- | Escape strings as needed for rich text format.+stringToRTF :: String -> String+stringToRTF = handleUnicode . escapeSpecial++-- | Escape things as needed for code block in RTF.+codeStringToRTF :: String -> String+codeStringToRTF str = joinWithSep "\\line\n" $ lines (stringToRTF str)++-- | Deal with raw LaTeX.+latexToRTF :: String -> String+latexToRTF str = "{\\cf1 " ++ (stringToRTF str) ++ "\\cf0 } "++-- | Make a paragraph with first-line indent, block indent, and space after.+rtfParSpaced :: Int -- ^ space after (in twips)+ -> Int -- ^ block indent (in twips)+ -> Int -- ^ first line indent (relative to block) (in twips)+ -> Alignment -- ^ alignment+ -> String -- ^ string with content+ -> String +rtfParSpaced spaceAfter indent firstLineIndent alignment content = + let alignString = case alignment of+ AlignLeft -> "\\ql "+ AlignRight -> "\\qr "+ AlignCenter -> "\\qc "+ AlignDefault -> "\\ql "+ in "{\\pard " ++ alignString +++ "\\f0 \\sa" ++ (show spaceAfter) ++ " \\li" ++ (show indent) ++ + " \\fi" ++ (show firstLineIndent) ++ " " ++ content ++ "\\par}\n"++-- | Default paragraph. +rtfPar :: Int -- ^ block indent (in twips)+ -> Int -- ^ first line indent (relative to block) (in twips)+ -> Alignment -- ^ alignment+ -> String -- ^ string with content+ -> String +rtfPar = rtfParSpaced 180 ++-- | Compact paragraph (e.g. for compact list items).+rtfCompact :: Int -- ^ block indent (in twips)+ -> Int -- ^ first line indent (relative to block) (in twips)+ -> Alignment -- ^ alignment+ -> String -- ^ string with content+ -> String +rtfCompact = rtfParSpaced 0 ++-- number of twips to indent+indentIncrement = 720+listIncrement = 360++-- | Returns appropriate bullet list marker for indent level.+bulletMarker :: Int -> String+bulletMarker indent = case indent `mod` 720 of+ 0 -> "\\bullet "+ otherwise -> "\\endash "++-- | Returns appropriate (list of) ordered list markers for indent level.+orderedMarkers :: Int -> ListAttributes -> [String]+orderedMarkers indent (start, style, delim) = + if style == DefaultStyle && delim == DefaultDelim+ then case indent `mod` 720 of+ 0 -> orderedListMarkers (start, Decimal, Period)+ otherwise -> orderedListMarkers (start, LowerAlpha, Period)+ else orderedListMarkers (start, style, delim)++-- | Returns RTF header.+rtfHeader :: String -- ^ header text+ -> Meta -- ^ bibliographic information+ -> String+rtfHeader headerText (Meta title authors date) =+ let titletext = if null title+ then "" + else rtfPar 0 0 AlignCenter $+ "\\b \\fs36 " ++ inlineListToRTF title+ authorstext = if null authors+ then "" + else rtfPar 0 0 AlignCenter (" " ++ (joinWithSep "\\" $+ map stringToRTF authors))+ datetext = if date == "" + then ""+ else rtfPar 0 0 AlignCenter (" " ++ stringToRTF date) in+ let spacer = if null (titletext ++ authorstext ++ datetext)+ then ""+ else rtfPar 0 0 AlignDefault "" in+ headerText ++ titletext ++ authorstext ++ datetext ++ spacer++-- | Convert Pandoc block element to RTF.+blockToRTF :: Int -- ^ indent level+ -> Alignment -- ^ alignment+ -> Block -- ^ block to convert+ -> String+blockToRTF _ _ Null = ""+blockToRTF indent alignment (Plain lst) = + rtfCompact indent 0 alignment $ inlineListToRTF lst+blockToRTF indent alignment (Para lst) = + rtfPar indent 0 alignment $ inlineListToRTF lst+blockToRTF indent alignment (BlockQuote lst) = + concatMap (blockToRTF (indent + indentIncrement) alignment) lst +blockToRTF indent _ (CodeBlock str) =+ rtfPar indent 0 AlignLeft ("\\f1 " ++ (codeStringToRTF str))+blockToRTF _ _ (RawHtml str) = ""+blockToRTF indent alignment (BulletList lst) = spaceAtEnd $ + concatMap (listItemToRTF alignment indent (bulletMarker indent)) lst+blockToRTF indent alignment (OrderedList attribs lst) = spaceAtEnd $ concat $ + zipWith (listItemToRTF alignment indent) (orderedMarkers indent attribs) lst+blockToRTF indent alignment (DefinitionList lst) = spaceAtEnd $ + concatMap (definitionListItemToRTF alignment indent) lst+blockToRTF indent _ HorizontalRule = + rtfPar indent 0 AlignCenter "\\emdash\\emdash\\emdash\\emdash\\emdash"+blockToRTF indent alignment (Header level lst) = rtfPar indent 0 alignment $+ "\\b \\fs" ++ (show (40 - (level * 4))) ++ " " ++ inlineListToRTF lst+blockToRTF indent alignment (Table caption aligns sizes headers rows) = + tableRowToRTF True indent aligns sizes headers ++ + concatMap (tableRowToRTF False indent aligns sizes) rows +++ rtfPar indent 0 alignment (inlineListToRTF caption)++tableRowToRTF :: Bool -> Int -> [Alignment] -> [Float] -> [[Block]] -> String +tableRowToRTF header indent aligns sizes cols =+ let columns = concat $ zipWith (tableItemToRTF indent) aligns cols+ totalTwips = 6 * 1440 -- 6 inches+ rightEdges = tail $ scanl (\sofar new -> sofar + floor (new * totalTwips))+ 0 sizes+ cellDefs = map (\edge -> (if header+ then "\\clbrdrb\\brdrs"+ else "") ++ "\\cellx" ++ show edge)+ rightEdges+ start = "{\n\\trowd \\trgaph120\n" ++ concat cellDefs ++ "\n" +++ "\\trkeep\\intbl\n{\n"+ end = "}\n\\intbl\\row}\n"+ in start ++ columns ++ end++tableItemToRTF :: Int -> Alignment -> [Block] -> String +tableItemToRTF indent alignment item =+ let contents = concatMap (blockToRTF indent alignment) item+ in "{\\intbl " ++ contents ++ "\\cell}\n"++-- | Ensure that there's the same amount of space after compact+-- lists as after regular lists.+spaceAtEnd :: String -> String+spaceAtEnd str = + if isSuffixOf "\\par}\n" str+ then (take ((length str) - 6) str) ++ "\\sa180\\par}\n"+ else str++-- | Convert list item (list of blocks) to RTF.+listItemToRTF :: Alignment -- ^ alignment+ -> Int -- ^ indent level+ -> String -- ^ list start marker+ -> [Block] -- ^ list item (list of blocks)+ -> [Char]+listItemToRTF alignment indent marker [] = + rtfCompact (indent + listIncrement) (0 - listIncrement) alignment + (marker ++ "\\tx" ++ (show listIncrement) ++ "\\tab ") +listItemToRTF alignment indent marker list = + let (first:rest) = map (blockToRTF (indent + listIncrement) alignment) list in+ -- insert the list marker into the (processed) first block+ let modFirst = case matchRegexAll (mkRegex "\\\\fi-?[0-9]+") first of+ Just (before, matched, after, _) -> + before ++ "\\fi" ++ show (0 - listIncrement) ++ + " " ++ marker ++ "\\tx" ++ + show listIncrement ++ "\\tab" ++ after+ Nothing -> first in+ modFirst ++ concat rest++-- | Convert definition list item (label, list of blocks) to RTF.+definitionListItemToRTF :: Alignment -- ^ alignment+ -> Int -- ^ indent level+ -> ([Inline],[Block]) -- ^ list item (list of blocks)+ -> [Char]+definitionListItemToRTF alignment indent (label, items) =+ let labelText = blockToRTF indent alignment (Plain label)+ itemsText = concatMap (blockToRTF (indent + listIncrement) alignment) items+ in labelText ++ itemsText ++-- | Convert list of inline items to RTF.+inlineListToRTF :: [Inline] -- ^ list of inlines to convert+ -> String+inlineListToRTF lst = concatMap inlineToRTF lst++-- | Convert inline item to RTF.+inlineToRTF :: Inline -- ^ inline to convert+ -> String+inlineToRTF (Emph lst) = "{\\i " ++ (inlineListToRTF lst) ++ "} "+inlineToRTF (Strong lst) = "{\\b " ++ (inlineListToRTF lst) ++ "} "+inlineToRTF (Strikeout lst) = "{\\strike " ++ (inlineListToRTF lst) ++ "} "+inlineToRTF (Superscript lst) = "{\\super " ++ (inlineListToRTF lst) ++ "} "+inlineToRTF (Subscript lst) = "{\\sub " ++ (inlineListToRTF lst) ++ "} "+inlineToRTF (Quoted SingleQuote lst) = + "\\u8216'" ++ (inlineListToRTF lst) ++ "\\u8217'"+inlineToRTF (Quoted DoubleQuote lst) = + "\\u8220\"" ++ (inlineListToRTF lst) ++ "\\u8221\""+inlineToRTF Apostrophe = "\\u8217'"+inlineToRTF Ellipses = "\\u8230?"+inlineToRTF EmDash = "\\u8212-"+inlineToRTF EnDash = "\\u8211-"+inlineToRTF (Code str) = "{\\f1 " ++ (codeStringToRTF str) ++ "} "+inlineToRTF (Str str) = stringToRTF str+inlineToRTF (TeX str) = latexToRTF str+inlineToRTF (HtmlInline str) = ""+inlineToRTF (LineBreak) = "\\line "+inlineToRTF Space = " "+inlineToRTF (Link text (src, tit)) = + "{\\field{\\*\\fldinst{HYPERLINK \"" ++ (codeStringToRTF src) ++ + "\"}}{\\fldrslt{\\ul\n" ++ (inlineListToRTF text) ++ "\n}}}\n"+inlineToRTF (Image alternate (source, tit)) = + "{\\cf1 [image: " ++ source ++ "]\\cf0}" +inlineToRTF (Note contents) =+ "{\\super\\chftn}{\\*\\footnote\\chftn\\~\\plain\\pard " ++ + (concatMap (blockToRTF 0 AlignDefault) contents) ++ "}"
+ src/Text/Pandoc/Writers/S5.hs view
@@ -0,0 +1,140 @@+----------------------------------------------------+-- Do not edit this file by hand. Edit +-- 'templates/S5.hs'+-- and run ./fillTemplates.pl Text/Pandoc/Writers/S5.hs+----------------------------------------------------++{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.S5+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Definitions for creation of S5 powerpoint-like HTML.+(See <http://meyerweb.com/eric/tools/s5/>.)+-}+module Text.Pandoc.Writers.S5 (+ -- * Strings+ s5Meta,+ s5Javascript,+ s5CSS,+ s5Links,+ -- * Functions+ writeS5,+ writeS5String,+ insertS5Structure+ ) where+import Text.Pandoc.Shared ( joinWithSep, WriterOptions )+import Text.Pandoc.Writers.HTML ( writeHtml, writeHtmlString )+import Text.Pandoc.Definition+import Text.XHtml.Strict++s5Meta :: String+s5Meta = "<!-- configuration parameters -->\n<meta name=\"defaultView\" content=\"slideshow\" />\n<meta name=\"controlVis\" content=\"hidden\" />\n"++s5Javascript :: String+s5Javascript = "<script type=\"text/javascript\">\n// S5 v1.1 slides.js -- released into the Public Domain\n//\n// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information \n// about all the wonderful and talented contributors to this code!\n\nvar undef;\nvar slideCSS = '';\nvar snum = 0;\nvar smax = 1;\nvar incpos = 0;\nvar number = undef;\nvar s5mode = true;\nvar defaultView = 'slideshow';\nvar controlVis = 'visible';\n\nvar isIE = navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.indexOf('Opera') < 1 ? 1 : 0;\nvar isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;\nvar isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0;\n\nfunction hasClass(object, className) {\n\tif (!object.className) return false;\n\treturn (object.className.search('(^|\\\\s)' + className + '(\\\\s|$)') != -1);\n}\n\nfunction hasValue(object, value) {\n\tif (!object) return false;\n\treturn (object.search('(^|\\\\s)' + value + '(\\\\s|$)') != -1);\n}\n\nfunction removeClass(object,className) {\n\tif (!object) return;\n\tobject.className = object.className.replace(new RegExp('(^|\\\\s)'+className+'(\\\\s|$)'), RegExp.$1+RegExp.$2);\n}\n\nfunction addClass(object,className) {\n\tif (!object || hasClass(object, className)) return;\n\tif (object.className) {\n\t\tobject.className += ' '+className;\n\t} else {\n\t\tobject.className = className;\n\t}\n}\n\nfunction GetElementsWithClassName(elementName,className) {\n\tvar allElements = document.getElementsByTagName(elementName);\n\tvar elemColl = new Array();\n\tfor (var i = 0; i< allElements.length; i++) {\n\t\tif (hasClass(allElements[i], className)) {\n\t\t\telemColl[elemColl.length] = allElements[i];\n\t\t}\n\t}\n\treturn elemColl;\n}\n\nfunction isParentOrSelf(element, id) {\n\tif (element == null || element.nodeName=='BODY') return false;\n\telse if (element.id == id) return true;\n\telse return isParentOrSelf(element.parentNode, id);\n}\n\nfunction nodeValue(node) {\n\tvar result = \"\";\n\tif (node.nodeType == 1) {\n\t\tvar children = node.childNodes;\n\t\tfor (var i = 0; i < children.length; ++i) {\n\t\t\tresult += nodeValue(children[i]);\n\t\t}\t\t\n\t}\n\telse if (node.nodeType == 3) {\n\t\tresult = node.nodeValue;\n\t}\n\treturn(result);\n}\n\nfunction slideLabel() {\n\tvar slideColl = GetElementsWithClassName('*','slide');\n\tvar list = document.getElementById('jumplist');\n\tsmax = slideColl.length;\n\tfor (var n = 0; n < smax; n++) {\n\t\tvar obj = slideColl[n];\n\n\t\tvar did = 'slide' + n.toString();\n\t\tobj.setAttribute('id',did);\n\t\tif (isOp) continue;\n\n\t\tvar otext = '';\n\t\tvar menu = obj.firstChild;\n\t\tif (!menu) continue; // to cope with empty slides\n\t\twhile (menu && menu.nodeType == 3) {\n\t\t\tmenu = menu.nextSibling;\n\t\t}\n\t \tif (!menu) continue; // to cope with slides with only text nodes\n\n\t\tvar menunodes = menu.childNodes;\n\t\tfor (var o = 0; o < menunodes.length; o++) {\n\t\t\totext += nodeValue(menunodes[o]);\n\t\t}\n\t\tlist.options[list.length] = new Option(n + ' : ' + otext, n);\n\t}\n}\n\nfunction currentSlide() {\n\tvar cs;\n\tif (document.getElementById) {\n\t\tcs = document.getElementById('currentSlide');\n\t} else {\n\t\tcs = document.currentSlide;\n\t}\n\tcs.innerHTML = '<span id=\"csHere\">' + snum + '<\\/span> ' + \n\t\t'<span id=\"csSep\">\\/<\\/span> ' + \n\t\t'<span id=\"csTotal\">' + (smax-1) + '<\\/span>';\n\tif (snum == 0) {\n\t\tcs.style.visibility = 'hidden';\n\t} else {\n\t\tcs.style.visibility = 'visible';\n\t}\n}\n\nfunction go(step) {\n\tif (document.getElementById('slideProj').disabled || step == 0) return;\n\tvar jl = document.getElementById('jumplist');\n\tvar cid = 'slide' + snum;\n\tvar ce = document.getElementById(cid);\n\tif (incrementals[snum].length > 0) {\n\t\tfor (var i = 0; i < incrementals[snum].length; i++) {\n\t\t\tremoveClass(incrementals[snum][i], 'current');\n\t\t\tremoveClass(incrementals[snum][i], 'incremental');\n\t\t}\n\t}\n\tif (step != 'j') {\n\t\tsnum += step;\n\t\tlmax = smax - 1;\n\t\tif (snum > lmax) snum = lmax;\n\t\tif (snum < 0) snum = 0;\n\t} else\n\t\tsnum = parseInt(jl.value);\n\tvar nid = 'slide' + snum;\n\tvar ne = document.getElementById(nid);\n\tif (!ne) {\n\t\tne = document.getElementById('slide0');\n\t\tsnum = 0;\n\t}\n\tif (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;}\n\tif (incrementals[snum].length > 0 && incpos == 0) {\n\t\tfor (var i = 0; i < incrementals[snum].length; i++) {\n\t\t\tif (hasClass(incrementals[snum][i], 'current'))\n\t\t\t\tincpos = i + 1;\n\t\t\telse\n\t\t\t\taddClass(incrementals[snum][i], 'incremental');\n\t\t}\n\t}\n\tif (incrementals[snum].length > 0 && incpos > 0)\n\t\taddClass(incrementals[snum][incpos - 1], 'current');\n\tce.style.visibility = 'hidden';\n\tne.style.visibility = 'visible';\n\tjl.selectedIndex = snum;\n\tcurrentSlide();\n\tnumber = 0;\n}\n\nfunction goTo(target) {\n\tif (target >= smax || target == snum) return;\n\tgo(target - snum);\n}\n\nfunction subgo(step) {\n\tif (step > 0) {\n\t\tremoveClass(incrementals[snum][incpos - 1],'current');\n\t\tremoveClass(incrementals[snum][incpos], 'incremental');\n\t\taddClass(incrementals[snum][incpos],'current');\n\t\tincpos++;\n\t} else {\n\t\tincpos--;\n\t\tremoveClass(incrementals[snum][incpos],'current');\n\t\taddClass(incrementals[snum][incpos], 'incremental');\n\t\taddClass(incrementals[snum][incpos - 1],'current');\n\t}\n}\n\nfunction toggle() {\n\tvar slideColl = GetElementsWithClassName('*','slide');\n\tvar slides = document.getElementById('slideProj');\n\tvar outline = document.getElementById('outlineStyle');\n\tif (!slides.disabled) {\n\t\tslides.disabled = true;\n\t\toutline.disabled = false;\n\t\ts5mode = false;\n\t\tfontSize('1em');\n\t\tfor (var n = 0; n < smax; n++) {\n\t\t\tvar slide = slideColl[n];\n\t\t\tslide.style.visibility = 'visible';\n\t\t}\n\t} else {\n\t\tslides.disabled = false;\n\t\toutline.disabled = true;\n\t\ts5mode = true;\n\t\tfontScale();\n\t\tfor (var n = 0; n < smax; n++) {\n\t\t\tvar slide = slideColl[n];\n\t\t\tslide.style.visibility = 'hidden';\n\t\t}\n\t\tslideColl[snum].style.visibility = 'visible';\n\t}\n}\n\nfunction showHide(action) {\n\tvar obj = GetElementsWithClassName('*','hideme')[0];\n\tswitch (action) {\n\tcase 's': obj.style.visibility = 'visible'; break;\n\tcase 'h': obj.style.visibility = 'hidden'; break;\n\tcase 'k':\n\t\tif (obj.style.visibility != 'visible') {\n\t\t\tobj.style.visibility = 'visible';\n\t\t} else {\n\t\t\tobj.style.visibility = 'hidden';\n\t\t}\n\tbreak;\n\t}\n}\n\n// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)\nfunction keys(key) {\n\tif (!key) {\n\t\tkey = event;\n\t\tkey.which = key.keyCode;\n\t}\n\tif (key.which == 84) {\n\t\ttoggle();\n\t\treturn;\n\t}\n\tif (s5mode) {\n\t\tswitch (key.which) {\n\t\t\tcase 10: // return\n\t\t\tcase 13: // enter\n\t\t\t\tif (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;\n\t\t\t\tif (key.target && isParentOrSelf(key.target, 'controls')) return;\n\t\t\t\tif(number != undef) {\n\t\t\t\t\tgoTo(number);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\tcase 32: // spacebar\n\t\t\tcase 34: // page down\n\t\t\tcase 39: // rightkey\n\t\t\tcase 40: // downkey\n\t\t\t\tif(number != undef) {\n\t\t\t\t\tgo(number);\n\t\t\t\t} else if (!incrementals[snum] || incpos >= incrementals[snum].length) {\n\t\t\t\t\tgo(1);\n\t\t\t\t} else {\n\t\t\t\t\tsubgo(1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 33: // page up\n\t\t\tcase 37: // leftkey\n\t\t\tcase 38: // upkey\n\t\t\t\tif(number != undef) {\n\t\t\t\t\tgo(-1 * number);\n\t\t\t\t} else if (!incrementals[snum] || incpos <= 0) {\n\t\t\t\t\tgo(-1);\n\t\t\t\t} else {\n\t\t\t\t\tsubgo(-1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 36: // home\n\t\t\t\tgoTo(0);\n\t\t\t\tbreak;\n\t\t\tcase 35: // end\n\t\t\t\tgoTo(smax-1);\n\t\t\t\tbreak;\n\t\t\tcase 67: // c\n\t\t\t\tshowHide('k');\n\t\t\t\tbreak;\n\t\t}\n\t\tif (key.which < 48 || key.which > 57) {\n\t\t\tnumber = undef;\n\t\t} else {\n\t\t\tif (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;\n\t\t\tif (key.target && isParentOrSelf(key.target, 'controls')) return;\n\t\t\tnumber = (((number != undef) ? number : 0) * 10) + (key.which - 48);\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction clicker(e) {\n\tnumber = undef;\n\tvar target;\n\tif (window.event) {\n\t\ttarget = window.event.srcElement;\n\t\te = window.event;\n\t} else target = e.target;\n\tif (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true;\n\tif (!e.which || e.which == 1) {\n\t\tif (!incrementals[snum] || incpos >= incrementals[snum].length) {\n\t\t\tgo(1);\n\t\t} else {\n\t\t\tsubgo(1);\n\t\t}\n\t}\n}\n\nfunction findSlide(hash) {\n\tvar target = null;\n\tvar slides = GetElementsWithClassName('*','slide');\n\tfor (var i = 0; i < slides.length; i++) {\n\t\tvar targetSlide = slides[i];\n\t\tif ( (targetSlide.name && targetSlide.name == hash)\n\t\t || (targetSlide.id && targetSlide.id == hash) ) {\n\t\t\ttarget = targetSlide;\n\t\t\tbreak;\n\t\t}\n\t}\n\twhile(target != null && target.nodeName != 'BODY') {\n\t\tif (hasClass(target, 'slide')) {\n\t\t\treturn parseInt(target.id.slice(5));\n\t\t}\n\t\ttarget = target.parentNode;\n\t}\n\treturn null;\n}\n\nfunction slideJump() {\n\tif (window.location.hash == null) return;\n\tvar sregex = /^#slide(\\d+)$/;\n\tvar matches = sregex.exec(window.location.hash);\n\tvar dest = null;\n\tif (matches != null) {\n\t\tdest = parseInt(matches[1]);\n\t} else {\n\t\tdest = findSlide(window.location.hash.slice(1));\n\t}\n\tif (dest != null)\n\t\tgo(dest - snum);\n}\n\nfunction fixLinks() {\n\tvar thisUri = window.location.href;\n\tthisUri = thisUri.slice(0, thisUri.length - window.location.hash.length);\n\tvar aelements = document.getElementsByTagName('A');\n\tfor (var i = 0; i < aelements.length; i++) {\n\t\tvar a = aelements[i].href;\n\t\tvar slideID = a.match('\\#slide[0-9]{1,2}');\n\t\tif ((slideID) && (slideID[0].slice(0,1) == '#')) {\n\t\t\tvar dest = findSlide(slideID[0].slice(1));\n\t\t\tif (dest != null) {\n\t\t\t\tif (aelements[i].addEventListener) {\n\t\t\t\t\taelements[i].addEventListener(\"click\", new Function(\"e\",\n\t\t\t\t\t\t\"if (document.getElementById('slideProj').disabled) return;\" +\n\t\t\t\t\t\t\"go(\"+dest+\" - snum); \" +\n\t\t\t\t\t\t\"if (e.preventDefault) e.preventDefault();\"), true);\n\t\t\t\t} else if (aelements[i].attachEvent) {\n\t\t\t\t\taelements[i].attachEvent(\"onclick\", new Function(\"\",\n\t\t\t\t\t\t\"if (document.getElementById('slideProj').disabled) return;\" +\n\t\t\t\t\t\t\"go(\"+dest+\" - snum); \" +\n\t\t\t\t\t\t\"event.returnValue = false;\"));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction externalLinks() {\n\tif (!document.getElementsByTagName) return;\n\tvar anchors = document.getElementsByTagName('a');\n\tfor (var i=0; i<anchors.length; i++) {\n\t\tvar anchor = anchors[i];\n\t\tif (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) {\n\t\t\tanchor.target = '_blank';\n\t\t\taddClass(anchor,'external');\n\t\t}\n\t}\n}\n\nfunction createControls() {\n\tvar controlsDiv = document.getElementById(\"controls\");\n\tif (!controlsDiv) return;\n\tvar hider = ' onmouseover=\"showHide(\\'s\\');\" onmouseout=\"showHide(\\'h\\');\"';\n\tvar hideDiv, hideList = '';\n\tif (controlVis == 'hidden') {\n\t\thideDiv = hider;\n\t} else {\n\t\thideList = hider;\n\t}\n\tcontrolsDiv.innerHTML = '<form action=\"#\" id=\"controlForm\"' + hideDiv + '>' +\n\t'<div id=\"navLinks\">' +\n\t'<a accesskey=\"t\" id=\"toggle\" href=\"javascript:toggle();\">Ø<\\/a>' +\n\t'<a accesskey=\"z\" id=\"prev\" href=\"javascript:go(-1);\">«<\\/a>' +\n\t'<a accesskey=\"x\" id=\"next\" href=\"javascript:go(1);\">»<\\/a>' +\n\t'<div id=\"navList\"' + hideList + '><select id=\"jumplist\" onchange=\"go(\\'j\\');\"><\\/select><\\/div>' +\n\t'<\\/div><\\/form>';\n\tif (controlVis == 'hidden') {\n\t\tvar hidden = document.getElementById('navLinks');\n\t} else {\n\t\tvar hidden = document.getElementById('jumplist');\n\t}\n\taddClass(hidden,'hideme');\n}\n\nfunction fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers\n\tif (!s5mode) return false;\n\tvar vScale = 22; // both yield 32 (after rounding) at 1024x768\n\tvar hScale = 32; // perhaps should auto-calculate based on theme's declared value?\n\tif (window.innerHeight) {\n\t\tvar vSize = window.innerHeight;\n\t\tvar hSize = window.innerWidth;\n\t} else if (document.documentElement.clientHeight) {\n\t\tvar vSize = document.documentElement.clientHeight;\n\t\tvar hSize = document.documentElement.clientWidth;\n\t} else if (document.body.clientHeight) {\n\t\tvar vSize = document.body.clientHeight;\n\t\tvar hSize = document.body.clientWidth;\n\t} else {\n\t\tvar vSize = 700; // assuming 1024x768, minus chrome and such\n\t\tvar hSize = 1024; // these do not account for kiosk mode or Opera Show\n\t}\n\tvar newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale));\n\tfontSize(newSize + 'px');\n\tif (isGe) { // hack to counter incremental reflow bugs\n\t\tvar obj = document.getElementsByTagName('body')[0];\n\t\tobj.style.display = 'none';\n\t\tobj.style.display = 'block';\n\t}\n}\n\nfunction fontSize(value) {\n\tif (!(s5ss = document.getElementById('s5ss'))) {\n\t\tif (!isIE) {\n\t\t\tdocument.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style'));\n\t\t\ts5ss.setAttribute('media','screen, projection');\n\t\t\ts5ss.setAttribute('id','s5ss');\n\t\t} else {\n\t\t\tdocument.createStyleSheet();\n\t\t\tdocument.s5ss = document.styleSheets[document.styleSheets.length - 1];\n\t\t}\n\t}\n\tif (!isIE) {\n\t\twhile (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild);\n\t\ts5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}'));\n\t} else {\n\t\tdocument.s5ss.addRule('body','font-size: ' + value + ' !important;');\n\t}\n}\n\nfunction notOperaFix() {\n\tslideCSS = document.getElementById('slideProj').href;\n\tvar slides = document.getElementById('slideProj');\n\tvar outline = document.getElementById('outlineStyle');\n\tslides.setAttribute('media','screen');\n\toutline.disabled = true;\n\tif (isGe) {\n\t\tslides.setAttribute('href','null'); // Gecko fix\n\t\tslides.setAttribute('href',slideCSS); // Gecko fix\n\t}\n\tif (isIE && document.styleSheets && document.styleSheets[0]) {\n\t\tdocument.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)');\n\t\tdocument.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)');\n\t\tdocument.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)');\n\t}\n}\n\nfunction getIncrementals(obj) {\n\tvar incrementals = new Array();\n\tif (!obj) \n\t\treturn incrementals;\n\tvar children = obj.childNodes;\n\tfor (var i = 0; i < children.length; i++) {\n\t\tvar child = children[i];\n\t\tif (hasClass(child, 'incremental')) {\n\t\t\tif (child.nodeName == 'OL' || child.nodeName == 'UL') {\n\t\t\t\tremoveClass(child, 'incremental');\n\t\t\t\tfor (var j = 0; j < child.childNodes.length; j++) {\n\t\t\t\t\tif (child.childNodes[j].nodeType == 1) {\n\t\t\t\t\t\taddClass(child.childNodes[j], 'incremental');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tincrementals[incrementals.length] = child;\n\t\t\t\tremoveClass(child,'incremental');\n\t\t\t}\n\t\t}\n\t\tif (hasClass(child, 'show-first')) {\n\t\t\tif (child.nodeName == 'OL' || child.nodeName == 'UL') {\n\t\t\t\tremoveClass(child, 'show-first');\n\t\t\t\tif (child.childNodes[isGe].nodeType == 1) {\n\t\t\t\t\tremoveClass(child.childNodes[isGe], 'incremental');\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tincrementals[incrementals.length] = child;\n\t\t\t}\n\t\t}\n\t\tincrementals = incrementals.concat(getIncrementals(child));\n\t}\n\treturn incrementals;\n}\n\nfunction createIncrementals() {\n\tvar incrementals = new Array();\n\tfor (var i = 0; i < smax; i++) {\n\t\tincrementals[i] = getIncrementals(document.getElementById('slide'+i));\n\t}\n\treturn incrementals;\n}\n\nfunction defaultCheck() {\n\tvar allMetas = document.getElementsByTagName('meta');\n\tfor (var i = 0; i< allMetas.length; i++) {\n\t\tif (allMetas[i].name == 'defaultView') {\n\t\t\tdefaultView = allMetas[i].content;\n\t\t}\n\t\tif (allMetas[i].name == 'controlVis') {\n\t\t\tcontrolVis = allMetas[i].content;\n\t\t}\n\t}\n}\n\n// Key trap fix, new function body for trap()\nfunction trap(e) {\n\tif (!e) {\n\t\te = event;\n\t\te.which = e.keyCode;\n\t}\n\ttry {\n\t\tmodifierKey = e.ctrlKey || e.altKey || e.metaKey;\n\t}\n\tcatch(e) {\n\t\tmodifierKey = false;\n\t}\n\treturn modifierKey || e.which == 0;\n}\n\nfunction startup() {\n\tdefaultCheck();\n\tif (!isOp) \n\t\tcreateControls();\n\tslideLabel();\n\tfixLinks();\n\texternalLinks();\n\tfontScale();\n\tif (!isOp) {\n\t\tnotOperaFix();\n\t\tincrementals = createIncrementals();\n\t\tslideJump();\n\t\tif (defaultView == 'outline') {\n\t\t\ttoggle();\n\t\t}\n\t\tdocument.onkeyup = keys;\n\t\tdocument.onkeypress = trap;\n\t\tdocument.onclick = clicker;\n\t}\n}\n\nwindow.onload = startup;\nwindow.onresize = function(){setTimeout('fontScale()', 50);}</script>\n" ++s5CoreCSS :: String+s5CoreCSS = "/* Do not edit or override these styles! The system will likely break if you do. */\n\ndiv#header, div#footer, div#controls, .slide {position: absolute;}\nhtml>body div#header, html>body div#footer, \n html>body div#controls, html>body .slide {position: fixed;}\n.handout {display: none;}\n.layout {display: block;}\n.slide, .hideme, .incremental {visibility: hidden;}\n#slide0 {visibility: visible;}\n"++s5FramingCSS :: String+s5FramingCSS = "/* The following styles size, place, and layer the slide components.\n Edit these if you want to change the overall slide layout.\n The commented lines can be uncommented (and modified, if necessary) \n to help you with the rearrangement process. */\n\n/* target = 1024x768 */\n\ndiv#header, div#footer, .slide {width: 100%; top: 0; left: 0;}\ndiv#header {top: 0; height: 3em; z-index: 1;}\ndiv#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}\n.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2; list-style: none;}\ndiv#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}\ndiv#controls form {position: absolute; bottom: 0; right: 0; width: 100%;\n margin: 0;}\n#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z-index: 10;}\nhtml>body #currentSlide {position: fixed;}\n\n/*\ndiv#header {background: #FCC;}\ndiv#footer {background: #CCF;}\ndiv#controls {background: #BBD;}\ndiv#currentSlide {background: #FFC;}\n*/\n"++s5PrettyCSS :: String+s5PrettyCSS = "/* Following are the presentation styles -- edit away! */\n\nbody {background: #FFF url(bodybg.gif) -16px 0 no-repeat; color: #000; font-size: 2em;}\n:link, :visited {text-decoration: none; color: #00C;}\n#controls :active {color: #88A !important;}\n#controls :focus {outline: 1px dotted #227;}\nh1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}\nul, pre {margin: 0; line-height: 1em;}\nhtml, body {margin: 0; padding: 0;}\n\nblockquote, q {font-style: italic;}\nblockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: center; font-size: 1em;}\nblockquote p {margin: 0;}\nblockquote i {font-style: normal;}\nblockquote b {display: block; margin-top: 0.5em; font-weight: normal; font-size: smaller; font-style: normal;}\nblockquote b i {font-style: italic;}\n\nkbd {font-weight: bold; font-size: 1em;}\nsup {font-size: smaller; line-height: 1px;}\n\n.slide code {padding: 2px 0.25em; font-weight: bold; color: #533;}\n.slide code.bad, code del {color: red;}\n.slide code.old {color: silver;}\n.slide pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 90%;}\n.slide pre code {display: block;}\n.slide ul {margin-left: 5%; margin-right: 7%; list-style: disc;}\n.slide li {margin-top: 0.75em; margin-right: 0;}\n.slide ul ul {line-height: 1;}\n.slide ul ul li {margin: .2em; font-size: 85%; list-style: square;}\n.slide img.leader {display: block; margin: 0 auto;}\n\ndiv#header, div#footer {background: #005; color: #AAB;\n font-family: Verdana, Helvetica, sans-serif;}\ndiv#header {background: #005 url(bodybg.gif) -16px 0 no-repeat;\n line-height: 1px;}\ndiv#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;}\n#footer h1, #footer h2 {display: block; padding: 0 1em;}\n#footer h2 {font-style: italic;}\n\ndiv.long {font-size: 0.75em;}\n.slide h1 {position: absolute; top: 0.7em; left: 87px; z-index: 1;\n margin: 0; padding: 0.3em 0 0 50px; white-space: nowrap;\n font: bold 150%/1em Helvetica, sans-serif; text-transform: capitalize;\n color: #DDE; background: #005;}\n.slide h3 {font-size: 130%;}\nh1 abbr {font-variant: small-caps;}\n\ndiv#controls {position: absolute; left: 50%; bottom: 0;\n width: 50%;\n text-align: right; font: bold 0.9em Verdana, Helvetica, sans-serif;}\nhtml>body div#controls {position: fixed; padding: 0 0 1em 0;\n top: auto;}\ndiv#controls form {position: absolute; bottom: 0; right: 0; width: 100%;\n margin: 0; padding: 0;}\n#controls #navLinks a {padding: 0; margin: 0 0.5em; \n background: #005; border: none; color: #779; \n cursor: pointer;}\n#controls #navList {height: 1em;}\n#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; background: #DDD; color: #227;}\n\n#currentSlide {text-align: center; font-size: 0.5em; color: #449;}\n\n#slide0 {padding-top: 3.5em; font-size: 90%;}\n#slide0 h1 {position: static; margin: 1em 0 0; padding: 0;\n font: bold 2em Helvetica, sans-serif; white-space: normal;\n color: #000; background: transparent;}\n#slide0 h2 {font: bold italic 1em Helvetica, sans-serif; margin: 0.25em;}\n#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}\n#slide0 h4 {margin-top: 0; font-size: 1em;}\n\nul.urls {list-style: none; display: inline; margin: 0;}\n.urls li {display: inline; margin: 0;}\n.note {display: none;}\n.external {border-bottom: 1px dotted gray;}\nhtml>body .external {border-bottom: none;}\n.external:after {content: \" \\274F\"; font-size: smaller; color: #77B;}\n\n.incremental, .incremental *, .incremental *:after {color: #DDE; visibility: visible;}\nimg.incremental {visibility: hidden;}\n.slide .current {color: #B02;}\n\n\n/* diagnostics\n\nli:after {content: \" [\" attr(class) \"]\"; color: #F88;}\n */"++s5OperaCSS :: String+s5OperaCSS = "/* DO NOT CHANGE THESE unless you really want to break Opera Show */\n.slide {\n\tvisibility: visible !important;\n\tposition: static !important;\n\tpage-break-before: always;\n}\n#slide0 {page-break-before: avoid;}\n"++s5OutlineCSS :: String+s5OutlineCSS = "/* don't change this unless you want the layout stuff to show up in the outline view! */\n\n.layout div, #footer *, #controlForm * {display: none;}\n#footer, #controls, #controlForm, #navLinks, #toggle {\n display: block; visibility: visible; margin: 0; padding: 0;}\n#toggle {float: right; padding: 0.5em;}\nhtml>body #toggle {position: fixed; top: 0; right: 0;}\n\n/* making the outline look pretty-ish */\n\n#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;}\n#slide0 h1 {padding-top: 1.5em;}\n.slide h1 {margin: 1.5em 0 0; padding-top: 0.25em;\n border-top: 1px solid #888; border-bottom: 1px solid #AAA;}\n#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;}\n"++s5PrintCSS :: String+s5PrintCSS = "/* The following rule is necessary to have all slides appear in print! DO NOT REMOVE IT! */\n.slide, ul {page-break-inside: avoid; visibility: visible !important;}\nh1 {page-break-after: avoid;}\n\nbody {font-size: 12pt; background: white;}\n* {color: black;}\n\n#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;}\n#slide0 h3 {margin: 0; padding: 0;}\n#slide0 h4 {margin: 0 0 0.5em; padding: 0;}\n#slide0 {margin-bottom: 3em;}\n\nh1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;}\n.extra {background: transparent !important;}\ndiv.extra, pre.extra, .example {font-size: 10pt; color: #333;}\nul.extra a {font-weight: bold;}\np.example {display: none;}\n\n#header {display: none;}\n#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style: italic;}\n#footer h2, #controls {display: none;}\n\n/* The following rule keeps the layout stuff out of print. Remove at your own risk! */\n.layout, .layout * {display: none !important;}\n"++s5CSS :: String+s5CSS = "<style type=\"text/css\" media=\"projection\" id=\"slideProj\">\n" ++ s5CoreCSS ++ "\n" ++ s5FramingCSS ++ "\n" ++ s5PrettyCSS ++ "\n</style>\n<style type=\"text/css\" media=\"projection\" id=\"operaFix\">\n" ++ s5OperaCSS ++ "\n</style>\n<style type=\"text/css\" media=\"screen\" id=\"outlineStyle\">\n" ++ s5OutlineCSS ++ "\n</style>\n<style type=\"text/css\" media=\"print\" id=\"slidePrint\">\n" ++ s5PrintCSS ++ "\n</style>\n"++s5Links :: String+s5Links = "<!-- style sheet links -->\n<link rel=\"stylesheet\" href=\"ui/default/slides.css\" type=\"text/css\" media=\"projection\" id=\"slideProj\" />\n<link rel=\"stylesheet\" href=\"ui/default/outline.css\" type=\"text/css\" media=\"screen\" id=\"outlineStyle\" />\n<link rel=\"stylesheet\" href=\"ui/default/print.css\" type=\"text/css\" media=\"print\" id=\"slidePrint\" />\n<link rel=\"stylesheet\" href=\"ui/default/opera.css\" type=\"text/css\" media=\"projection\" id=\"operaFix\" />\n<!-- S5 JS -->\n<script src=\"ui/default/slides.js\" type=\"text/javascript\"></script>\n"++-- | Converts Pandoc document to an S5 HTML presentation (Html structure).+writeS5 :: WriterOptions -> Pandoc -> Html+writeS5 options = (writeHtml options) . insertS5Structure++-- | Converts Pandoc document to an S5 HTML presentation (string).+writeS5String :: WriterOptions -> Pandoc -> String+writeS5String options = (writeHtmlString options) . insertS5Structure++-- | Inserts HTML needed for an S5 presentation (e.g. around slides).+layoutDiv :: [Inline] -- ^ Title of document (for header or footer)+ -> String -- ^ Date of document (for header or footer)+ -> [Block] -- ^ List of block elements returned+layoutDiv title date = [(RawHtml "<div class=\"layout\">\n<div id=\"controls\"></div>\n<div id=\"currentSlide\"></div>\n<div id=\"header\"></div>\n<div id=\"footer\">\n"), (Header 1 [Str date]), (Header 2 title), (RawHtml "</div>\n</div>\n")]++presentationStart = RawHtml "<div class=\"presentation\">\n\n"++presentationEnd = RawHtml "</div>\n"++slideStart = RawHtml "<div class=\"slide\">\n"++slideEnd = RawHtml "</div>\n"++-- | Returns 'True' if block is a Header 1.+isH1 :: Block -> Bool+isH1 (Header 1 _) = True+isH1 _ = False ++-- | Insert HTML around sections to make individual slides.+insertSlides :: Bool -> [Block] -> [Block]+insertSlides beginning blocks = + let (beforeHead, rest) = break isH1 blocks in+ if (null rest) then + if beginning then+ beforeHead + else+ beforeHead ++ [slideEnd]+ else+ if beginning then+ beforeHead ++ + slideStart:(head rest):(insertSlides False (tail rest))+ else+ beforeHead ++ + slideEnd:slideStart:(head rest):(insertSlides False (tail rest)) ++-- | Insert blocks into 'Pandoc' for slide structure.+insertS5Structure :: Pandoc -> Pandoc+insertS5Structure (Pandoc meta []) = Pandoc meta []+insertS5Structure (Pandoc (Meta title authors date) blocks) = + let slides = insertSlides True blocks + firstSlide = if not (null title)+ then [slideStart, (Header 1 title), + (Header 3 [Str (joinWithSep ", " authors)]),+ (Header 4 [Str date]), slideEnd]+ else []+ newBlocks = (layoutDiv title date) ++ presentationStart:firstSlide +++ slides ++ [presentationEnd]+ in Pandoc (Meta title authors date) newBlocks+
+ src/headers/ConTeXtHeader view
@@ -0,0 +1,61 @@+\enableregime[utf] % use UTF-8++\setupcolors[state=start]+\setupinteraction[state=start, color=middlered] % needed for hyperlinks++\setuppapersize[letter][letter] % use letter paper+\setuplayout[width=middle, backspace=1.5in, cutspace=1.5in,+ height=middle, header=0.75in, footer=0.75in] % page layout+\setuppagenumbering[location={footer,center}] % number pages+\setupbodyfont[11pt] % 11pt font+\setupwhitespace[medium] % inter-paragraph spacing++\setuphead[section][style=\tfc]+\setuphead[subsection][style=\tfb]+\setuphead[subsubsection][style=\bf]++% define title block commands+\unprotect+\def\doctitle#1{\gdef\@title{#1}}+\def\author#1{\gdef\@author{#1}}+\def\date#1{\gdef\@date{#1}}+\date{\currentdate} % Default to today unless specified otherwise.+\def\maketitle{%+ \startalignment[center]+ \blank[2*big]+ {\tfd \@title}+ \blank[3*medium]+ {\tfa \@author}+ \blank[2*medium]+ {\tfa \@date}+ \blank[3*medium]+ \stopalignment}+\protect++% define descr (for definition lists)+\definedescription[descr][+ headstyle=bold,style=normal,align=left,location=hanging,+ width=broad,margin=1cm]++% define ltxitem (for bulleted lists) +\defineitemgroup[ltxitem][levels=4]+\setupitemgroup[ltxitem][1][1]+\setupitemgroup[ltxitem][2][2]+\setupitemgroup[ltxitem][3][3]+\setupitemgroup[ltxitem][4][4,packed]++% define ltxenum (for enumerated lists)+\defineitemgroup[ltxenum][levels=4]+\setupitemgroup[ltxenum][1][n]+\setupitemgroup[ltxenum][2][a]+\setupitemgroup[ltxenum][3][r]+\setupitemgroup[ltxenum][4][A,packed]++\setupthinrules[width=15em] % width of horizontal rules++% for block quotations+\definestartstop [blockquote]+ [before={\startnarrower\switchtobodyfont[11pt]+ \whitespace\setupindenting[no]},+ after={\stopnarrower\whitespace}]+
+ src/headers/DocbookHeader view
@@ -0,0 +1,3 @@+<?xml version="1.0" encoding="utf-8" ?>+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"+ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+ src/headers/LaTeXHeader view
@@ -0,0 +1,5 @@+\documentclass{article}+\usepackage[mathletters]{ucs}+\usepackage[utf8x]{inputenc}+\setlength{\parindent}{0pt}+\setlength{\parskip}{6pt plus 2pt minus 1pt}
+ src/headers/RTFHeader view
@@ -0,0 +1,4 @@+{\rtf1\ansi\deff0{\fonttbl{\f0 \fswiss Helvetica;}{\f1 Courier;}}+{\colortbl;\red255\green0\blue0;\red0\green0\blue255;}+\widowctrl\hyphauto+
+ src/headers/S5Header view
@@ -0,0 +1,3 @@+<!-- configuration parameters -->+<meta name="defaultView" content="slideshow" />+<meta name="controlVis" content="hidden" />
+ src/templates/ASCIIMathML.hs view
@@ -0,0 +1,7 @@+-- | Definitions for use of ASCIIMathML in HTML. +-- (See <http://www1.chapman.edu/~jipsen/mathml/asciimath.html>.)+module Text.Pandoc.ASCIIMathML ( asciiMathMLScript ) where++-- | String containing ASCIIMathML javascript.+asciiMathMLScript :: String+asciiMathMLScript = "<script type=\"text/javascript\">\n@ASCIIMathML.js@</script>\n"
+ src/templates/DefaultHeaders.hs view
@@ -0,0 +1,52 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.DefaultHeaders+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Default headers for Pandoc writers.+-}+module Text.Pandoc.Writers.DefaultHeaders (+ defaultLaTeXHeader,+ defaultConTeXtHeader,+ defaultDocbookHeader,+ defaultS5Header,+ defaultRTFHeader+ ) where+import Text.Pandoc.Writers.S5++defaultLaTeXHeader :: String+defaultLaTeXHeader = "@LaTeXHeader@"++defaultConTeXtHeader :: String+defaultConTeXtHeader = "@ConTeXtHeader@"++defaultDocbookHeader :: String+defaultDocbookHeader = "@DocbookHeader@"++defaultS5Header :: String+defaultS5Header = s5Meta ++ s5CSS ++ s5Javascript++defaultRTFHeader :: String+defaultRTFHeader = "@RTFHeader@"
+ src/templates/Makefile view
@@ -0,0 +1,20 @@+VPATH := ..+PROCESSOR := ./fillTemplates.pl+TARGETS := Text/Pandoc/ASCIIMathML.hs \+ Text/Pandoc/Writers/S5.hs \+ Text/Pandoc/Writers/DefaultHeaders.hs++all: $(TARGETS)++Text/Pandoc/ASCIIMathML.hs: ASCIIMathML.hs $(PROCESSOR) $(VPATH)/ASCIIMathML.js+ perl $(PROCESSOR) $@ $(VPATH)++Text/Pandoc/Writers/S5.hs: S5.hs $(PROCESSOR) $(VPATH)/ui/default/*+ perl $(PROCESSOR) $@ $(VPATH)++Text/Pandoc/Writers/DefaultHeaders.hs: DefaultHeaders.hs $(PROCESSOR) $(VPATH)/headers/*+ perl $(PROCESSOR) $@ $(VPATH)++.PHONY: clean+clean:+ cd $(VPATH); rm -f $(TARGETS)
+ src/templates/S5.hs view
@@ -0,0 +1,133 @@+{-+Copyright (C) 2006-7 John MacFarlane <jgm@berkeley.edu>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program; if not, write to the Free Software+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+-}++{- |+ Module : Text.Pandoc.Writers.S5+ Copyright : Copyright (C) 2006-7 John MacFarlane+ License : GNU GPL, version 2 or above ++ Maintainer : John MacFarlane <jgm@berkeley.edu>+ Stability : alpha+ Portability : portable++Definitions for creation of S5 powerpoint-like HTML.+(See <http://meyerweb.com/eric/tools/s5/>.)+-}+module Text.Pandoc.Writers.S5 (+ -- * Strings+ s5Meta,+ s5Javascript,+ s5CSS,+ s5Links,+ -- * Functions+ writeS5,+ writeS5String,+ insertS5Structure+ ) where+import Text.Pandoc.Shared ( joinWithSep, WriterOptions )+import Text.Pandoc.Writers.HTML ( writeHtml, writeHtmlString )+import Text.Pandoc.Definition+import Text.XHtml.Strict++s5Meta :: String+s5Meta = "<!-- configuration parameters -->\n<meta name=\"defaultView\" content=\"slideshow\" />\n<meta name=\"controlVis\" content=\"hidden\" />\n"++s5Javascript :: String+s5Javascript = "<script type=\"text/javascript\">\n@slides.js@</script>\n" ++s5CoreCSS :: String+s5CoreCSS = "@s5-core.css@"++s5FramingCSS :: String+s5FramingCSS = "@framing.css@"++s5PrettyCSS :: String+s5PrettyCSS = "@pretty.css@"++s5OperaCSS :: String+s5OperaCSS = "@opera.css@"++s5OutlineCSS :: String+s5OutlineCSS = "@outline.css@"++s5PrintCSS :: String+s5PrintCSS = "@print.css@"++s5CSS :: String+s5CSS = "<style type=\"text/css\" media=\"projection\" id=\"slideProj\">\n" ++ s5CoreCSS ++ "\n" ++ s5FramingCSS ++ "\n" ++ s5PrettyCSS ++ "\n</style>\n<style type=\"text/css\" media=\"projection\" id=\"operaFix\">\n" ++ s5OperaCSS ++ "\n</style>\n<style type=\"text/css\" media=\"screen\" id=\"outlineStyle\">\n" ++ s5OutlineCSS ++ "\n</style>\n<style type=\"text/css\" media=\"print\" id=\"slidePrint\">\n" ++ s5PrintCSS ++ "\n</style>\n"++s5Links :: String+s5Links = "<!-- style sheet links -->\n<link rel=\"stylesheet\" href=\"ui/default/slides.css\" type=\"text/css\" media=\"projection\" id=\"slideProj\" />\n<link rel=\"stylesheet\" href=\"ui/default/outline.css\" type=\"text/css\" media=\"screen\" id=\"outlineStyle\" />\n<link rel=\"stylesheet\" href=\"ui/default/print.css\" type=\"text/css\" media=\"print\" id=\"slidePrint\" />\n<link rel=\"stylesheet\" href=\"ui/default/opera.css\" type=\"text/css\" media=\"projection\" id=\"operaFix\" />\n<!-- S5 JS -->\n<script src=\"ui/default/slides.js\" type=\"text/javascript\"></script>\n"++-- | Converts Pandoc document to an S5 HTML presentation (Html structure).+writeS5 :: WriterOptions -> Pandoc -> Html+writeS5 options = (writeHtml options) . insertS5Structure++-- | Converts Pandoc document to an S5 HTML presentation (string).+writeS5String :: WriterOptions -> Pandoc -> String+writeS5String options = (writeHtmlString options) . insertS5Structure++-- | Inserts HTML needed for an S5 presentation (e.g. around slides).+layoutDiv :: [Inline] -- ^ Title of document (for header or footer)+ -> String -- ^ Date of document (for header or footer)+ -> [Block] -- ^ List of block elements returned+layoutDiv title date = [(RawHtml "<div class=\"layout\">\n<div id=\"controls\"></div>\n<div id=\"currentSlide\"></div>\n<div id=\"header\"></div>\n<div id=\"footer\">\n"), (Header 1 [Str date]), (Header 2 title), (RawHtml "</div>\n</div>\n")]++presentationStart = RawHtml "<div class=\"presentation\">\n\n"++presentationEnd = RawHtml "</div>\n"++slideStart = RawHtml "<div class=\"slide\">\n"++slideEnd = RawHtml "</div>\n"++-- | Returns 'True' if block is a Header 1.+isH1 :: Block -> Bool+isH1 (Header 1 _) = True+isH1 _ = False ++-- | Insert HTML around sections to make individual slides.+insertSlides :: Bool -> [Block] -> [Block]+insertSlides beginning blocks = + let (beforeHead, rest) = break isH1 blocks in+ if (null rest) then + if beginning then+ beforeHead + else+ beforeHead ++ [slideEnd]+ else+ if beginning then+ beforeHead ++ + slideStart:(head rest):(insertSlides False (tail rest))+ else+ beforeHead ++ + slideEnd:slideStart:(head rest):(insertSlides False (tail rest)) ++-- | Insert blocks into 'Pandoc' for slide structure.+insertS5Structure :: Pandoc -> Pandoc+insertS5Structure (Pandoc meta []) = Pandoc meta []+insertS5Structure (Pandoc (Meta title authors date) blocks) = + let slides = insertSlides True blocks + firstSlide = if not (null title)+ then [slideStart, (Header 1 title), + (Header 3 [Str (joinWithSep ", " authors)]),+ (Header 4 [Str date]), slideEnd]+ else []+ newBlocks = (layoutDiv title date) ++ presentationStart:firstSlide +++ slides ++ [presentationEnd]+ in Pandoc (Meta title authors date) newBlocks
+ src/templates/fillTemplates.pl view
@@ -0,0 +1,131 @@+#!/usr/bin/env perl+# Fills templates with haskell-escaped strings slurped from input files.+# Takes two arguments, the first specifying the pathname of the target+# relative to the root directory, the second specifying the root directory+# (defaulting to ..). The template is assumed to have the same base name+# as the target and to reside in the templates subdirectory of the root+# directory.++use strict;+use warnings;++# Utility routines:++sub slurp {+ open FILE, $_[0] or die "couldn't open file '$_[0]': $!";+ my $contents = do { local $/; <FILE>;};+ close FILE;+ return $contents;+}++sub escape_for_haskell {+ my ($contents) = @_;++ $contents =~ s/\\/\\\\/g;+ $contents =~ s/\t/\\t/g;+ $contents =~ s/"/\\"/g;+ $contents =~ s/\n/\\n/g;+ return $contents;+}++# Template processors.++my %processor = (+ # --------------------------------------------------------------------------+ 'Text/Pandoc/Writers/S5.hs' => {+ # --------------------------------------------------------------------------+ proc => sub {+ my ($template) = @_;++ my (@files) = qw(slides.js s5-core.css framing.css pretty.css + opera.css outline.css print.css);++ foreach my $file (@files) {+ my $replacement = escape_for_haskell(slurp "ui/default/$file");+ my $escapedfile = $file;+ $escapedfile =~ s/\./\\./g;+ $template =~ s/\@$escapedfile\@/$replacement/;+ } + return $template;+ },+ },+ # --------------------------------------------------------------------------+ 'Text/Pandoc/ASCIIMathML.hs' => {+ # --------------------------------------------------------------------------+ proc => sub {+ my ($template) = @_;++ my $script = escape_for_haskell(slurp "ASCIIMathML.js"); + my $acknowledgements =+ " ASCIIMathML.js - copyright Peter Jipsen,".+ " released under the GPL\\nSee ".+ "http://www1.chapman.edu/~jipsen/mathml/asciimath.html/ ";+ $script =~ s/\/\*.*?\*\//\/\*$acknowledgements\*\//g; # strip comments+ $template =~ s/\@ASCIIMathML\.js@/$script/;++ return $template;+ },+ },+ # --------------------------------------------------------------------------+ 'Text/Pandoc/Writers/DefaultHeaders.hs' => {+ # --------------------------------------------------------------------------+ proc => sub {+ my ($template) = @_;++ my (@headers) = split(/\s/,`ls headers`);+ foreach my $header (@headers) {+ my ($replacement) = escape_for_haskell(slurp "headers/$header");+ $template =~ s/\@$header\@/$replacement/;+ }+ + return $template;+ },+ },+ # --------------------------------------------------------------------------+ # 'foo/bar/baz' => {+ # --------------------------------------------------------------------------+ # template => 'optional-template-filename-defaults-to-baz'+ # proc => sub {+ # my ($template) = @_;+ # # Process.+ # return $template;+ # },+ #},+);++# Main.++my $target = shift @ARGV;+if (!defined $target || !length $target) {+ print STDERR "Available targets:\n\n" . join "\n", keys %processor;+ die "\n\nYou must supply a target!\n";+}++die "No processor exists for '$target'!\n" if ! exists $processor{$target};++my $rootdir = shift @ARGV || '..';+chdir $rootdir or die "Couldn't chdir to '$rootdir': $!";++my $template;+if (exists $processor{$target}->{template}) {+ $template = $processor{$target}->{template};+}+else {+ ($template = $target) =~ s!.*/+!!;+}+$template = "templates/$template";+die "No template exists for '$target'!\n" if ! -f "$template";++open OUTFILE, ">$target" or die "couldn't open file '$target': $!";+print OUTFILE <<END;+----------------------------------------------------+-- Do not edit this file by hand. Edit +-- '$template'+-- and run $0 $target+----------------------------------------------------++END++print OUTFILE $processor{$target}->{proc}->(slurp($template));+print OUTFILE "\n";+close OUTFILE;
+ src/ui/default/blank.gif view
binary file changed (absent → 49 bytes)
+ src/ui/default/bodybg.gif view
binary file changed (absent → 10119 bytes)
+ src/ui/default/framing.css view
@@ -0,0 +1,23 @@+/* The following styles size, place, and layer the slide components.+ Edit these if you want to change the overall slide layout.+ The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */++/* target = 1024x768 */++div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}+div#header {top: 0; height: 3em; z-index: 1;}+div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}+.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2; list-style: none;}+div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;+ margin: 0;}+#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z-index: 10;}+html>body #currentSlide {position: fixed;}++/*+div#header {background: #FCC;}+div#footer {background: #CCF;}+div#controls {background: #BBD;}+div#currentSlide {background: #FFC;}+*/
+ src/ui/default/iepngfix.htc view
@@ -0,0 +1,42 @@+<public:component> +<public:attach event="onpropertychange" onevent="doFix()" /> + +<script> + +// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com +// Free usage permitted as long as this notice remains intact. + +// This must be a path to a blank image. That's all the configuration you need here. +var blankImg = 'ui/default/blank.gif'; + +var f = 'DXImageTransform.Microsoft.AlphaImageLoader'; + +function filt(s, m) { + if (filters[f]) { + filters[f].enabled = s ? true : false; + if (s) with (filters[f]) { src = s; sizingMethod = m } + } else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")'; +} + +function doFix() { + if ((parseFloat(navigator.userAgent.match(/MSIE (\S+)/)[1]) < 5.5) || + (event && !/(background|src)/.test(event.propertyName))) return; + + if (tagName == 'IMG') { + if ((/\.png$/i).test(src)) { + filt(src, 'image'); // was 'scale' + src = blankImg; + } else if (src.indexOf(blankImg) < 0) filt(); + } else if (style.backgroundImage) { + if (style.backgroundImage.match(/^url[("']+(.*\.png)[)"']+$/i)) { + var s = RegExp.$1; + style.backgroundImage = ''; + filt(s, 'crop'); + } else filt(); + } +} + +doFix(); + +</script> +</public:component>
+ src/ui/default/opera.css view
@@ -0,0 +1,7 @@+/* DO NOT CHANGE THESE unless you really want to break Opera Show */+.slide {+ visibility: visible !important;+ position: static !important;+ page-break-before: always;+}+#slide0 {page-break-before: avoid;}
+ src/ui/default/outline.css view
@@ -0,0 +1,15 @@+/* don't change this unless you want the layout stuff to show up in the outline view! */++.layout div, #footer *, #controlForm * {display: none;}+#footer, #controls, #controlForm, #navLinks, #toggle {+ display: block; visibility: visible; margin: 0; padding: 0;}+#toggle {float: right; padding: 0.5em;}+html>body #toggle {position: fixed; top: 0; right: 0;}++/* making the outline look pretty-ish */++#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;}+#slide0 h1 {padding-top: 1.5em;}+.slide h1 {margin: 1.5em 0 0; padding-top: 0.25em;+ border-top: 1px solid #888; border-bottom: 1px solid #AAA;}+#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;}
+ src/ui/default/pretty.css view
@@ -0,0 +1,86 @@+/* Following are the presentation styles -- edit away! */++body {background: #FFF url(bodybg.gif) -16px 0 no-repeat; color: #000; font-size: 2em;}+:link, :visited {text-decoration: none; color: #00C;}+#controls :active {color: #88A !important;}+#controls :focus {outline: 1px dotted #227;}+h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}+ul, pre {margin: 0; line-height: 1em;}+html, body {margin: 0; padding: 0;}++blockquote, q {font-style: italic;}+blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: center; font-size: 1em;}+blockquote p {margin: 0;}+blockquote i {font-style: normal;}+blockquote b {display: block; margin-top: 0.5em; font-weight: normal; font-size: smaller; font-style: normal;}+blockquote b i {font-style: italic;}++kbd {font-weight: bold; font-size: 1em;}+sup {font-size: smaller; line-height: 1px;}++.slide code {padding: 2px 0.25em; font-weight: bold; color: #533;}+.slide code.bad, code del {color: red;}+.slide code.old {color: silver;}+.slide pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 90%;}+.slide pre code {display: block;}+.slide ul {margin-left: 5%; margin-right: 7%; list-style: disc;}+.slide li {margin-top: 0.75em; margin-right: 0;}+.slide ul ul {line-height: 1;}+.slide ul ul li {margin: .2em; font-size: 85%; list-style: square;}+.slide img.leader {display: block; margin: 0 auto;}++div#header, div#footer {background: #005; color: #AAB;+ font-family: Verdana, Helvetica, sans-serif;}+div#header {background: #005 url(bodybg.gif) -16px 0 no-repeat;+ line-height: 1px;}+div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;}+#footer h1, #footer h2 {display: block; padding: 0 1em;}+#footer h2 {font-style: italic;}++div.long {font-size: 0.75em;}+.slide h1 {position: absolute; top: 0.7em; left: 87px; z-index: 1;+ margin: 0; padding: 0.3em 0 0 50px; white-space: nowrap;+ font: bold 150%/1em Helvetica, sans-serif; text-transform: capitalize;+ color: #DDE; background: #005;}+.slide h3 {font-size: 130%;}+h1 abbr {font-variant: small-caps;}++div#controls {position: absolute; left: 50%; bottom: 0;+ width: 50%;+ text-align: right; font: bold 0.9em Verdana, Helvetica, sans-serif;}+html>body div#controls {position: fixed; padding: 0 0 1em 0;+ top: auto;}+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;+ margin: 0; padding: 0;}+#controls #navLinks a {padding: 0; margin: 0 0.5em; + background: #005; border: none; color: #779; + cursor: pointer;}+#controls #navList {height: 1em;}+#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; background: #DDD; color: #227;}++#currentSlide {text-align: center; font-size: 0.5em; color: #449;}++#slide0 {padding-top: 3.5em; font-size: 90%;}+#slide0 h1 {position: static; margin: 1em 0 0; padding: 0;+ font: bold 2em Helvetica, sans-serif; white-space: normal;+ color: #000; background: transparent;}+#slide0 h2 {font: bold italic 1em Helvetica, sans-serif; margin: 0.25em;}+#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}+#slide0 h4 {margin-top: 0; font-size: 1em;}++ul.urls {list-style: none; display: inline; margin: 0;}+.urls li {display: inline; margin: 0;}+.note {display: none;}+.external {border-bottom: 1px dotted gray;}+html>body .external {border-bottom: none;}+.external:after {content: " \274F"; font-size: smaller; color: #77B;}++.incremental, .incremental *, .incremental *:after {color: #DDE; visibility: visible;}+img.incremental {visibility: hidden;}+.slide .current {color: #B02;}+++/* diagnostics++li:after {content: " [" attr(class) "]"; color: #F88;}+ */
+ src/ui/default/print.css view
@@ -0,0 +1,24 @@+/* The following rule is necessary to have all slides appear in print! DO NOT REMOVE IT! */+.slide, ul {page-break-inside: avoid; visibility: visible !important;}+h1 {page-break-after: avoid;}++body {font-size: 12pt; background: white;}+* {color: black;}++#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;}+#slide0 h3 {margin: 0; padding: 0;}+#slide0 h4 {margin: 0 0 0.5em; padding: 0;}+#slide0 {margin-bottom: 3em;}++h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;}+.extra {background: transparent !important;}+div.extra, pre.extra, .example {font-size: 10pt; color: #333;}+ul.extra a {font-weight: bold;}+p.example {display: none;}++#header {display: none;}+#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style: italic;}+#footer h2, #controls {display: none;}++/* The following rule keeps the layout stuff out of print. Remove at your own risk! */+.layout, .layout * {display: none !important;}
+ src/ui/default/s5-core.css view
@@ -0,0 +1,9 @@+/* Do not edit or override these styles! The system will likely break if you do. */++div#header, div#footer, div#controls, .slide {position: absolute;}+html>body div#header, html>body div#footer, + html>body div#controls, html>body .slide {position: fixed;}+.handout {display: none;}+.layout {display: block;}+.slide, .hideme, .incremental {visibility: hidden;}+#slide0 {visibility: visible;}
+ src/ui/default/slides.css view
@@ -0,0 +1,3 @@+@import url(s5-core.css); /* required to make the slide show run at all */+@import url(framing.css); /* sets basic placement and size of slide components */+@import url(pretty.css); /* stuff that makes the slides look better than blah */
+ src/ui/default/slides.js view
@@ -0,0 +1,553 @@+// S5 v1.1 slides.js -- released into the Public Domain+//+// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information +// about all the wonderful and talented contributors to this code!++var undef;+var slideCSS = '';+var snum = 0;+var smax = 1;+var incpos = 0;+var number = undef;+var s5mode = true;+var defaultView = 'slideshow';+var controlVis = 'visible';++var isIE = navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.indexOf('Opera') < 1 ? 1 : 0;+var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;+var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0;++function hasClass(object, className) {+ if (!object.className) return false;+ return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1);+}++function hasValue(object, value) {+ if (!object) return false;+ return (object.search('(^|\\s)' + value + '(\\s|$)') != -1);+}++function removeClass(object,className) {+ if (!object) return;+ object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2);+}++function addClass(object,className) {+ if (!object || hasClass(object, className)) return;+ if (object.className) {+ object.className += ' '+className;+ } else {+ object.className = className;+ }+}++function GetElementsWithClassName(elementName,className) {+ var allElements = document.getElementsByTagName(elementName);+ var elemColl = new Array();+ for (var i = 0; i< allElements.length; i++) {+ if (hasClass(allElements[i], className)) {+ elemColl[elemColl.length] = allElements[i];+ }+ }+ return elemColl;+}++function isParentOrSelf(element, id) {+ if (element == null || element.nodeName=='BODY') return false;+ else if (element.id == id) return true;+ else return isParentOrSelf(element.parentNode, id);+}++function nodeValue(node) {+ var result = "";+ if (node.nodeType == 1) {+ var children = node.childNodes;+ for (var i = 0; i < children.length; ++i) {+ result += nodeValue(children[i]);+ } + }+ else if (node.nodeType == 3) {+ result = node.nodeValue;+ }+ return(result);+}++function slideLabel() {+ var slideColl = GetElementsWithClassName('*','slide');+ var list = document.getElementById('jumplist');+ smax = slideColl.length;+ for (var n = 0; n < smax; n++) {+ var obj = slideColl[n];++ var did = 'slide' + n.toString();+ obj.setAttribute('id',did);+ if (isOp) continue;++ var otext = '';+ var menu = obj.firstChild;+ if (!menu) continue; // to cope with empty slides+ while (menu && menu.nodeType == 3) {+ menu = menu.nextSibling;+ }+ if (!menu) continue; // to cope with slides with only text nodes++ var menunodes = menu.childNodes;+ for (var o = 0; o < menunodes.length; o++) {+ otext += nodeValue(menunodes[o]);+ }+ list.options[list.length] = new Option(n + ' : ' + otext, n);+ }+}++function currentSlide() {+ var cs;+ if (document.getElementById) {+ cs = document.getElementById('currentSlide');+ } else {+ cs = document.currentSlide;+ }+ cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' + + '<span id="csSep">\/<\/span> ' + + '<span id="csTotal">' + (smax-1) + '<\/span>';+ if (snum == 0) {+ cs.style.visibility = 'hidden';+ } else {+ cs.style.visibility = 'visible';+ }+}++function go(step) {+ if (document.getElementById('slideProj').disabled || step == 0) return;+ var jl = document.getElementById('jumplist');+ var cid = 'slide' + snum;+ var ce = document.getElementById(cid);+ if (incrementals[snum].length > 0) {+ for (var i = 0; i < incrementals[snum].length; i++) {+ removeClass(incrementals[snum][i], 'current');+ removeClass(incrementals[snum][i], 'incremental');+ }+ }+ if (step != 'j') {+ snum += step;+ lmax = smax - 1;+ if (snum > lmax) snum = lmax;+ if (snum < 0) snum = 0;+ } else+ snum = parseInt(jl.value);+ var nid = 'slide' + snum;+ var ne = document.getElementById(nid);+ if (!ne) {+ ne = document.getElementById('slide0');+ snum = 0;+ }+ if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;}+ if (incrementals[snum].length > 0 && incpos == 0) {+ for (var i = 0; i < incrementals[snum].length; i++) {+ if (hasClass(incrementals[snum][i], 'current'))+ incpos = i + 1;+ else+ addClass(incrementals[snum][i], 'incremental');+ }+ }+ if (incrementals[snum].length > 0 && incpos > 0)+ addClass(incrementals[snum][incpos - 1], 'current');+ ce.style.visibility = 'hidden';+ ne.style.visibility = 'visible';+ jl.selectedIndex = snum;+ currentSlide();+ number = 0;+}++function goTo(target) {+ if (target >= smax || target == snum) return;+ go(target - snum);+}++function subgo(step) {+ if (step > 0) {+ removeClass(incrementals[snum][incpos - 1],'current');+ removeClass(incrementals[snum][incpos], 'incremental');+ addClass(incrementals[snum][incpos],'current');+ incpos++;+ } else {+ incpos--;+ removeClass(incrementals[snum][incpos],'current');+ addClass(incrementals[snum][incpos], 'incremental');+ addClass(incrementals[snum][incpos - 1],'current');+ }+}++function toggle() {+ var slideColl = GetElementsWithClassName('*','slide');+ var slides = document.getElementById('slideProj');+ var outline = document.getElementById('outlineStyle');+ if (!slides.disabled) {+ slides.disabled = true;+ outline.disabled = false;+ s5mode = false;+ fontSize('1em');+ for (var n = 0; n < smax; n++) {+ var slide = slideColl[n];+ slide.style.visibility = 'visible';+ }+ } else {+ slides.disabled = false;+ outline.disabled = true;+ s5mode = true;+ fontScale();+ for (var n = 0; n < smax; n++) {+ var slide = slideColl[n];+ slide.style.visibility = 'hidden';+ }+ slideColl[snum].style.visibility = 'visible';+ }+}++function showHide(action) {+ var obj = GetElementsWithClassName('*','hideme')[0];+ switch (action) {+ case 's': obj.style.visibility = 'visible'; break;+ case 'h': obj.style.visibility = 'hidden'; break;+ case 'k':+ if (obj.style.visibility != 'visible') {+ obj.style.visibility = 'visible';+ } else {+ obj.style.visibility = 'hidden';+ }+ break;+ }+}++// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)+function keys(key) {+ if (!key) {+ key = event;+ key.which = key.keyCode;+ }+ if (key.which == 84) {+ toggle();+ return;+ }+ if (s5mode) {+ switch (key.which) {+ case 10: // return+ case 13: // enter+ if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;+ if (key.target && isParentOrSelf(key.target, 'controls')) return;+ if(number != undef) {+ goTo(number);+ break;+ }+ case 32: // spacebar+ case 34: // page down+ case 39: // rightkey+ case 40: // downkey+ if(number != undef) {+ go(number);+ } else if (!incrementals[snum] || incpos >= incrementals[snum].length) {+ go(1);+ } else {+ subgo(1);+ }+ break;+ case 33: // page up+ case 37: // leftkey+ case 38: // upkey+ if(number != undef) {+ go(-1 * number);+ } else if (!incrementals[snum] || incpos <= 0) {+ go(-1);+ } else {+ subgo(-1);+ }+ break;+ case 36: // home+ goTo(0);+ break;+ case 35: // end+ goTo(smax-1);+ break;+ case 67: // c+ showHide('k');+ break;+ }+ if (key.which < 48 || key.which > 57) {+ number = undef;+ } else {+ if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;+ if (key.target && isParentOrSelf(key.target, 'controls')) return;+ number = (((number != undef) ? number : 0) * 10) + (key.which - 48);+ }+ }+ return false;+}++function clicker(e) {+ number = undef;+ var target;+ if (window.event) {+ target = window.event.srcElement;+ e = window.event;+ } else target = e.target;+ if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true;+ if (!e.which || e.which == 1) {+ if (!incrementals[snum] || incpos >= incrementals[snum].length) {+ go(1);+ } else {+ subgo(1);+ }+ }+}++function findSlide(hash) {+ var target = null;+ var slides = GetElementsWithClassName('*','slide');+ for (var i = 0; i < slides.length; i++) {+ var targetSlide = slides[i];+ if ( (targetSlide.name && targetSlide.name == hash)+ || (targetSlide.id && targetSlide.id == hash) ) {+ target = targetSlide;+ break;+ }+ }+ while(target != null && target.nodeName != 'BODY') {+ if (hasClass(target, 'slide')) {+ return parseInt(target.id.slice(5));+ }+ target = target.parentNode;+ }+ return null;+}++function slideJump() {+ if (window.location.hash == null) return;+ var sregex = /^#slide(\d+)$/;+ var matches = sregex.exec(window.location.hash);+ var dest = null;+ if (matches != null) {+ dest = parseInt(matches[1]);+ } else {+ dest = findSlide(window.location.hash.slice(1));+ }+ if (dest != null)+ go(dest - snum);+}++function fixLinks() {+ var thisUri = window.location.href;+ thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length);+ var aelements = document.getElementsByTagName('A');+ for (var i = 0; i < aelements.length; i++) {+ var a = aelements[i].href;+ var slideID = a.match('\#slide[0-9]{1,2}');+ if ((slideID) && (slideID[0].slice(0,1) == '#')) {+ var dest = findSlide(slideID[0].slice(1));+ if (dest != null) {+ if (aelements[i].addEventListener) {+ aelements[i].addEventListener("click", new Function("e",+ "if (document.getElementById('slideProj').disabled) return;" ++ "go("+dest+" - snum); " ++ "if (e.preventDefault) e.preventDefault();"), true);+ } else if (aelements[i].attachEvent) {+ aelements[i].attachEvent("onclick", new Function("",+ "if (document.getElementById('slideProj').disabled) return;" ++ "go("+dest+" - snum); " ++ "event.returnValue = false;"));+ }+ }+ }+ }+}++function externalLinks() {+ if (!document.getElementsByTagName) return;+ var anchors = document.getElementsByTagName('a');+ for (var i=0; i<anchors.length; i++) {+ var anchor = anchors[i];+ if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) {+ anchor.target = '_blank';+ addClass(anchor,'external');+ }+ }+}++function createControls() {+ var controlsDiv = document.getElementById("controls");+ if (!controlsDiv) return;+ var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"';+ var hideDiv, hideList = '';+ if (controlVis == 'hidden') {+ hideDiv = hider;+ } else {+ hideList = hider;+ }+ controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' ++ '<div id="navLinks">' ++ '<a accesskey="t" id="toggle" href="javascript:toggle();">Ø<\/a>' ++ '<a accesskey="z" id="prev" href="javascript:go(-1);">«<\/a>' ++ '<a accesskey="x" id="next" href="javascript:go(1);">»<\/a>' ++ '<div id="navList"' + hideList + '><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' ++ '<\/div><\/form>';+ if (controlVis == 'hidden') {+ var hidden = document.getElementById('navLinks');+ } else {+ var hidden = document.getElementById('jumplist');+ }+ addClass(hidden,'hideme');+}++function fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers+ if (!s5mode) return false;+ var vScale = 22; // both yield 32 (after rounding) at 1024x768+ var hScale = 32; // perhaps should auto-calculate based on theme's declared value?+ if (window.innerHeight) {+ var vSize = window.innerHeight;+ var hSize = window.innerWidth;+ } else if (document.documentElement.clientHeight) {+ var vSize = document.documentElement.clientHeight;+ var hSize = document.documentElement.clientWidth;+ } else if (document.body.clientHeight) {+ var vSize = document.body.clientHeight;+ var hSize = document.body.clientWidth;+ } else {+ var vSize = 700; // assuming 1024x768, minus chrome and such+ var hSize = 1024; // these do not account for kiosk mode or Opera Show+ }+ var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale));+ fontSize(newSize + 'px');+ if (isGe) { // hack to counter incremental reflow bugs+ var obj = document.getElementsByTagName('body')[0];+ obj.style.display = 'none';+ obj.style.display = 'block';+ }+}++function fontSize(value) {+ if (!(s5ss = document.getElementById('s5ss'))) {+ if (!isIE) {+ document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style'));+ s5ss.setAttribute('media','screen, projection');+ s5ss.setAttribute('id','s5ss');+ } else {+ document.createStyleSheet();+ document.s5ss = document.styleSheets[document.styleSheets.length - 1];+ }+ }+ if (!isIE) {+ while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild);+ s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}'));+ } else {+ document.s5ss.addRule('body','font-size: ' + value + ' !important;');+ }+}++function notOperaFix() {+ slideCSS = document.getElementById('slideProj').href;+ var slides = document.getElementById('slideProj');+ var outline = document.getElementById('outlineStyle');+ slides.setAttribute('media','screen');+ outline.disabled = true;+ if (isGe) {+ slides.setAttribute('href','null'); // Gecko fix+ slides.setAttribute('href',slideCSS); // Gecko fix+ }+ if (isIE && document.styleSheets && document.styleSheets[0]) {+ document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)');+ document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)');+ document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)');+ }+}++function getIncrementals(obj) {+ var incrementals = new Array();+ if (!obj) + return incrementals;+ var children = obj.childNodes;+ for (var i = 0; i < children.length; i++) {+ var child = children[i];+ if (hasClass(child, 'incremental')) {+ if (child.nodeName == 'OL' || child.nodeName == 'UL') {+ removeClass(child, 'incremental');+ for (var j = 0; j < child.childNodes.length; j++) {+ if (child.childNodes[j].nodeType == 1) {+ addClass(child.childNodes[j], 'incremental');+ }+ }+ } else {+ incrementals[incrementals.length] = child;+ removeClass(child,'incremental');+ }+ }+ if (hasClass(child, 'show-first')) {+ if (child.nodeName == 'OL' || child.nodeName == 'UL') {+ removeClass(child, 'show-first');+ if (child.childNodes[isGe].nodeType == 1) {+ removeClass(child.childNodes[isGe], 'incremental');+ }+ } else {+ incrementals[incrementals.length] = child;+ }+ }+ incrementals = incrementals.concat(getIncrementals(child));+ }+ return incrementals;+}++function createIncrementals() {+ var incrementals = new Array();+ for (var i = 0; i < smax; i++) {+ incrementals[i] = getIncrementals(document.getElementById('slide'+i));+ }+ return incrementals;+}++function defaultCheck() {+ var allMetas = document.getElementsByTagName('meta');+ for (var i = 0; i< allMetas.length; i++) {+ if (allMetas[i].name == 'defaultView') {+ defaultView = allMetas[i].content;+ }+ if (allMetas[i].name == 'controlVis') {+ controlVis = allMetas[i].content;+ }+ }+}++// Key trap fix, new function body for trap()+function trap(e) {+ if (!e) {+ e = event;+ e.which = e.keyCode;+ }+ try {+ modifierKey = e.ctrlKey || e.altKey || e.metaKey;+ }+ catch(e) {+ modifierKey = false;+ }+ return modifierKey || e.which == 0;+}++function startup() {+ defaultCheck();+ if (!isOp) + createControls();+ slideLabel();+ fixLinks();+ externalLinks();+ fontScale();+ if (!isOp) {+ notOperaFix();+ incrementals = createIncrementals();+ slideJump();+ if (defaultView == 'outline') {+ toggle();+ }+ document.onkeyup = keys;+ document.onkeypress = trap;+ document.onclick = clicker;+ }+}++window.onload = startup;+window.onresize = function(){setTimeout('fontScale()', 50);}
+ src/wrappers/common.sh view
@@ -0,0 +1,43 @@+THIS=${0##*/}++NEWLINE='+'++err () { echo "$*" | fold -s -w ${COLUMNS:-110} >&2; }+errn () { printf "$*" | fold -s -w ${COLUMNS:-110} >&2; }++usage () {+ err "$1 - $2" # short description+ err "See the $1(1) man page for usage."+}++# Portable which(1).+pathfind () {+ oldifs="$IFS"; IFS=':'+ for _p in $PATH; do+ if [ -x "$_p/$*" ] && [ -f "$_p/$*" ]; then+ IFS="$oldifs"+ return 0+ fi+ done+ IFS="$oldifs"+ return 1+}++for p in pandoc $REQUIRED; do+ pathfind $p || {+ err "You need '$p' to use this program!"+ exit 1+ }+done++CONF=$(pandoc --dump-args "$@" 2>&1) || {+ errcode=$?+ echo "$CONF" | sed -e '/^pandoc \[OPTIONS\] \[FILES\]/,$d' >&2+ [ $errcode -eq 2 ] && usage "$THIS" "$SYNOPSIS"+ exit $errcode+}++OUTPUT=$(echo "$CONF" | sed -ne '1p')+ARGS=$(echo "$CONF" | sed -e '1d')+
+ src/wrappers/hsmarkdown.in view
@@ -0,0 +1,5 @@+#!/bin/sh+# hsmarkdown - intended as a drop-in replacement for Markdown.pl.+# Uses pandoc to convert from markdown to HTML, using --strict mode+# for maximum compatibility with official markdown syntax.+exec pandoc --from markdown --to html --strict -- "$@"
+ src/wrappers/html2markdown.in view
@@ -0,0 +1,157 @@+#!/bin/sh -e+# converts HTML from a URL, file, or stdin to markdown+# uses an available program to fetch URL and tidy to normalize it first++REQUIRED="tidy"+SYNOPSIS="converts HTML from a URL, file, or STDIN to markdown-formatted text."++### common.sh++grab_url_with () {+ url="${1:?internal error: grab_url_with: url required}"++ shift+ cmdline="$@"++ prog=+ prog_opts=+ if [ -n "$cmdline" ]; then+ eval "set -- $cmdline"+ prog=$1+ shift+ prog_opts="$@"+ fi++ if [ -z "$prog" ]; then+ # Locate a sensible web grabber (note the order).+ for p in wget lynx w3m curl links w3c; do+ if pathfind $p; then+ prog=$p+ break+ fi+ done++ [ -n "$prog" ] || {+ errn "$THIS: Couldn't find a program to fetch the file from URL "+ err "(e.g. wget, w3m, lynx, w3c, or curl)."+ return 1+ }+ else+ pathfind "$prog" || {+ err "$THIS: No such web grabber '$prog' found; aborting."+ return 1+ }+ fi++ # Setup proper base options for known grabbers.+ base_opts=+ case "$prog" in+ wget) base_opts="-O-" ;;+ lynx) base_opts="-source" ;;+ w3m) base_opts="-dump_source" ;;+ curl) base_opts="" ;;+ links) base_opts="-source" ;;+ w3c) base_opts="-n -get" ;;+ *) err "$THIS: unhandled web grabber '$prog'; hope it succeeds."+ esac++ err "$THIS: invoking '$prog $base_opts $prog_opts $url'..."+ eval "set -- $base_opts $prog_opts"+ $prog "$@" "$url"+}++# Parse command-line arguments+parse_arguments () {+ while [ $# -gt 0 ]; do+ case "$1" in+ --encoding=*)+ wholeopt="$1"+ # extract encoding from after =+ encoding="${wholeopt#*=}" ;;+ -e|--encoding|-encoding)+ shift+ encoding="$1" ;; + --grabber=*)+ wholeopt="$1"+ # extract encoding from after =+ grabber="\"${wholeopt#*=}\"" ;;+ -g|--grabber|-grabber)+ shift+ grabber="$1" ;; + *)+ if [ -z "$argument" ]; then+ argument="$1"+ else+ err "Warning: extra argument '$1' will be ignored."+ fi ;;+ esac+ shift+ done+}++argument=+encoding=+grabber=++oldifs="$IFS"+IFS=$NEWLINE+parse_arguments $ARGS+IFS="$oldifs"++inurl=+if [ -n "$argument" ] && ! [ -f "$argument" ]; then+ # Treat given argument as an URL.+ inurl="$argument"+fi++if [ -n "$inurl" ]; then+ err "Attempting to fetch file from '$inurl'..."++ ### tempdir.sh++ grabber_out=$THIS_TEMPDIR/grabber.out+ grabber_log=$THIS_TEMPDIR/grabber.log+ if ! grab_url_with "$inurl" "$grabber" 1>$grabber_out 2>$grabber_log; then+ errn "grab_url_with failed"+ if [ -f $grabber_log ]; then+ err " with the following error log."+ err+ cat >&2 $grabber_log+ else+ err .+ fi+ exit 1+ fi++ argument="$grabber_out"+fi++if [ -z "$encoding" ] && [ "x$argument" != "x" ]; then+ # Try to determine character encoding if not specified+ # and input is not STDIN.+ encoding=$(+ head "$argument" |+ LC_ALL=C tr 'A-Z' 'a-z' |+ sed -ne '/<meta .*content-type.*charset=/ {+ s/.*charset=["'\'']*\([-a-zA-Z0-9]*\).*["'\'']*/\1/p+ }'+ )+fi++if [ -n "$encoding" ] && pathfind iconv; then+ alias to_utf8='iconv -f "$encoding" -t utf-8'+else # assume UTF-8+ alias to_utf8='cat'+fi ++if [ -z "$argument" ]; then+ tidy -asxhtml -utf8 2>/dev/null | pandoc --ignore-args -r html -w markdown "$@"+else+ if [ -f "$argument" ]; then+ to_utf8 "$argument" | + tidy -asxhtml -utf8 2>/dev/null | pandoc --ignore-args -r html -w markdown "$@"+ else+ err "File '$argument' not found."+ exit 1+ fi+fi
+ src/wrappers/markdown2pdf.in view
@@ -0,0 +1,81 @@+#!/bin/sh -e++REQUIRED="pdflatex"+SYNOPSIS="converts markdown-formatted text to PDF, using pdflatex."++### common.sh++### tempdir.sh++texname=output+logfile=$THIS_TEMPDIR/log++pandoc -s -r markdown -w latex "$@" -o $THIS_TEMPDIR/$texname.tex++if [ "$OUTPUT" = "-" ]; then+ firstinfile="$(echo $ARGS | sed -ne '1p')"+ firstinfilebase="${firstinfile%.*}"+ destname="${firstinfilebase:-stdin}.pdf"+else+ destname="$OUTPUT"+fi++(+ origdir=$(pwd)+ cd $THIS_TEMPDIR+ TEXINPUTS=$origdir:$TEXINPUTS:+ export TEXINPUTS+ finished=no+ runs=0+ while [ $finished = "no" ]; do+ pdflatex -interaction=batchmode $texname.tex >/dev/null || {+ errcode=$?+ err "${THIS}: pdfLaTeX failed with error code $errcode"+ [ -f $texname.log ] && {+ err "${THIS}: error context:"+ sed -ne '/^!/,/^[[:space:]]*$/p' \+ -ne '/^[Ll]a[Tt]e[Xx] [Ww]arning/,/^[[:space:]]*$/p' \+ -ne '/^[Ee]rror/,/^[[:space:]]*$/p' $texname.log >&2+ if grep -q "File \`ucs.sty' not found" $texname.log; then+ err "${THIS}: Please install the 'unicode' package from CTAN:"+ err " http://www.ctan.org/tex-archive/macros/latex/contrib/unicode/"+ fi+ if grep -q "File \`ulem.sty' not found" $texname.log; then+ err "${THIS}: Please install the 'ulem' package from CTAN:"+ err " http://www.ctan.org/tex-archive/macros/latex/contrib/misc/ulem.sty"+ fi+ }+ exit $errcode+ }+ if [ $runs -lt 3 ] && + ((grep -q "LaTeX Warning: There were undefined references." $texname.log) ||+ (echo "$@" | grep -q -- "--toc\|--table-of-contents")); then+ runs=$(($runs + 1))+ if grep -q "LaTeX Warning:.*[Cc]itation" $texname.log; then+ bibtex $texname 2>&1 >bibtex.err+ if [ $runs -gt 2 ]; then+ if grep -q "error message" bibtex.err ||+ grep -q "Warning" bibtex.err; then+ cat bibtex.err >&2+ fi+ fi+ fi+ else+ finished=yes+ fi+ done+) || exit $?++is_target_exists=+if [ -f "$destname" ]; then+ is_target_exists=1+ mv "$destname" "$destname~" +fi++mv -f $THIS_TEMPDIR/$texname.pdf "$destname"++errn "Created $destname"+[ -z "$is_target_exists" ] || {+ errn " (previous file has been backed up as $destname~)"+}+err .
+ src/wrappers/tempdir.sh view
@@ -0,0 +1,18 @@+# As a security measure refuse to proceed if mktemp is not available.+pathfind mktemp || { err "Couldn't find 'mktemp'; aborting."; exit 1; }++# Avoid issues with /tmp directory on Windows/Cygwin +cygwin=+cygwin=$(uname | sed -ne '/^CYGWIN/p')+if [ -n "$cygwin" ]; then+ TMPDIR=.+ export TMPDIR+fi++THIS_TEMPDIR=+THIS_TEMPDIR="$(mktemp -d -t $THIS.XXXXXXXX)" || exit 1+readonly THIS_TEMPDIR++trap 'exitcode=$?+ [ -z "$THIS_TEMPDIR" ] || rm -rf "$THIS_TEMPDIR"+ exit $exitcode' 0 1 2 3 13 15
+ tests/MarkdownTest_1.0.3/MarkdownTest.pl view
@@ -0,0 +1,176 @@+#!/usr/bin/perl++#+# MarkdownTester -- Run tests for Markdown implementations+#+# Copyright (c) 2004-2005 John Gruber+# <http://daringfireball.net/projects/markdown/>+#++use strict;+use warnings;+use Getopt::Long;+use Benchmark;++our $VERSION = '1.0.2';+# Sat 24 Dec 2005++my $time_start = new Benchmark;+my $test_dir = "Tests";+my $script = "./Markdown.pl";+my $use_tidy = 0;+my ($flag_version);++GetOptions (+ "script=s" => \$script,+ "testdir=s" => \$test_dir,+ "tidy" => \$use_tidy,+ "version" => \$flag_version,+ );++if($flag_version) {+ my $progname = $0;+ $progname =~ s{.*/}{};+ die "$progname version $VERSION\n";+}++unless (-d $test_dir) { die "'$test_dir' is not a directory.\n"; }+unless (-f $script) { die "$script does not exist.\n"; }+unless (-x $script) { die "$script is not executable.\n"; }++my $tests_passed = 0;+my $tests_failed = 0;++TEST:+foreach my $testfile (glob "$test_dir/*.text") {+ my $testname = $testfile;+ $testname =~ s{.*/(.+)\.text$}{$1}i; + print "$testname ... ";++ # Look for a corresponding .html file for each .text file:+ my $resultfile = $testfile;+ $resultfile =~ s{\.text$}{\.html}i;+ unless (-f $resultfile) {+ print "'$resultfile' does not exist.\n\n";+ next TEST;+ }+ + # open(TEST, $testfile) || die("Can't open testfile: $!");+ open(RESULT, $resultfile) || die("Can't open resultfile: $!");+ undef $/;+ # my $t_input = <TEST>;+ my $t_result = <RESULT>;++ my $t_output = `'$script' '$testfile'`;++ # Normalize the output and expected result strings:+ $t_result =~ s/\s+\z//; # trim trailing whitespace+ $t_output =~ s/\s+\z//; # trim trailing whitespace+ if ($use_tidy) {+ # Escape the strings, pass them through to CLI tidy tool for tag-level equivalency+ $t_result =~ s{'}{'\\''}g; # escape ' chars for shell+ $t_output =~ s{'}{'\\''}g;+ $t_result = `echo '$t_result' | tidy --show-body-only 1 --quiet 1 --show-warnings 0`;+ $t_output = `echo '$t_output' | tidy --show-body-only 1 --quiet 1 --show-warnings 0`;+ }++ if ($t_output eq $t_result) {+ print "OK\n";+ $tests_passed++;+ }+ else {+ print "FAILED\n\n";+# This part added by JM to print diffs+ open(OUT, '>tmp1') or die $!;+ print OUT $t_output or die $!;+ open(RES, '>tmp2') or die $!;+ print RES $t_result or die $!;+ print `diff tmp1 tmp2`;+ close RES;+ close OUT;+ print "\n";+ `rm tmp?`;+# End of added part+ $tests_failed++;+ }+}++print "\n\n";+print "$tests_passed passed; $tests_failed failed.\n";++my $time_end = new Benchmark;+my $time_diff = timediff($time_end, $time_start);+print "Benchmark: ", timestr($time_diff), "\n";+++__END__++=pod++=head1 NAME++B<MarkdownTest>+++=head1 SYNOPSIS++B<MarkdownTest.pl> [ B<--options> ] [ I<file> ... ]+++=head1 DESCRIPTION+++=head1 OPTIONS++Use "--" to end switch parsing. For example, to open a file named "-z", use:++ MarkdownTest.pl -- -z++=over 4++=item B<--script>++Specify the path to the Markdown script to test. Defaults to+"./Markdown.pl". Example:++ ./MarkdownTest.pl --script ./PHP-Markdown/php-markdown++=item B<--testdir>++Specify the path to a directory containing test data. Defaults to "Tests".++=item B<--tidy>++Flag to turn on using the command line 'tidy' tool to normalize HTML+output before comparing script output to the expected test result.+Assumes that the 'tidy' command is available in your PATH. Defaults to+off.++=back++++=head1 BUGS++++=head1 VERSION HISTORY++1.0 Mon 13 Dec 2004-2005++1.0.1 Mon 19 Sep 2005++ + Better handling of case when foo.text exists, but foo.html doesn't.+ It now prints a message and moves on, rather than dying.+++=head1 COPYRIGHT AND LICENSE++Copyright (c) 2004-2005 John Gruber +<http://daringfireball.net/> +All rights reserved.++This is free software; you may redistribute it and/or modify it under+the same terms as Perl itself.++=cut
+ tests/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html view
@@ -0,0 +1,17 @@+<p>AT&T has an ampersand in their name.</p>++<p>AT&T is another way to write it.</p>++<p>This & that.</p>++<p>4 < 5.</p>++<p>6 > 5.</p>++<p>Here's a <a href="http://example.com/?foo=1&bar=2">link</a> with an ampersand in the URL.</p>++<p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&T">AT&T</a>.</p>++<p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p>++<p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p>
+ tests/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text view
@@ -0,0 +1,21 @@+AT&T has an ampersand in their name.++AT&T is another way to write it.++This & that.++4 < 5.++6 > 5.++Here's a [link] [1] with an ampersand in the URL.++Here's a link with an amersand in the link text: [AT&T] [2].++Here's an inline [link](/script?foo=1&bar=2).++Here's an inline [link](</script?foo=1&bar=2>).+++[1]: http://example.com/?foo=1&bar=2+[2]: http://att.com/ "AT&T"
+ tests/MarkdownTest_1.0.3/Tests/Auto links.html view
@@ -0,0 +1,18 @@+<p>Link: <a href="http://example.com/">http://example.com/</a>.</p>++<p>With an ampersand: <a href="http://example.com/?foo=1&bar=2">http://example.com/?foo=1&bar=2</a></p>++<ul>+<li>In a list?</li>+<li><a href="http://example.com/">http://example.com/</a></li>+<li>It should.</li>+</ul>++<blockquote>+ <p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p>+</blockquote>++<p>Auto-links should not occur here: <code><http://example.com/></code></p>++<pre><code>or here: <http://example.com/>+</code></pre>
+ tests/MarkdownTest_1.0.3/Tests/Auto links.text view
@@ -0,0 +1,13 @@+Link: <http://example.com/>.++With an ampersand: <http://example.com/?foo=1&bar=2>++* In a list?+* <http://example.com/>+* It should.++> Blockquoted: <http://example.com/>++Auto-links should not occur here: `<http://example.com/>`++ or here: <http://example.com/>
+ tests/MarkdownTest_1.0.3/Tests/Backslash escapes.html view
@@ -0,0 +1,118 @@+<p>These should all get escaped:</p>++<p>Backslash: \</p>++<p>Backtick: `</p>++<p>Asterisk: *</p>++<p>Underscore: _</p>++<p>Left brace: {</p>++<p>Right brace: }</p>++<p>Left bracket: [</p>++<p>Right bracket: ]</p>++<p>Left paren: (</p>++<p>Right paren: )</p>++<p>Greater-than: ></p>++<p>Hash: #</p>++<p>Period: .</p>++<p>Bang: !</p>++<p>Plus: +</p>++<p>Minus: -</p>++<p>These should not, because they occur within a code block:</p>++<pre><code>Backslash: \\++Backtick: \`++Asterisk: \*++Underscore: \_++Left brace: \{++Right brace: \}++Left bracket: \[++Right bracket: \]++Left paren: \(++Right paren: \)++Greater-than: \>++Hash: \#++Period: \.++Bang: \!++Plus: \+++Minus: \-+</code></pre>++<p>Nor should these, which occur in code spans:</p>++<p>Backslash: <code>\\</code></p>++<p>Backtick: <code>\`</code></p>++<p>Asterisk: <code>\*</code></p>++<p>Underscore: <code>\_</code></p>++<p>Left brace: <code>\{</code></p>++<p>Right brace: <code>\}</code></p>++<p>Left bracket: <code>\[</code></p>++<p>Right bracket: <code>\]</code></p>++<p>Left paren: <code>\(</code></p>++<p>Right paren: <code>\)</code></p>++<p>Greater-than: <code>\></code></p>++<p>Hash: <code>\#</code></p>++<p>Period: <code>\.</code></p>++<p>Bang: <code>\!</code></p>++<p>Plus: <code>\+</code></p>++<p>Minus: <code>\-</code></p>+++<p>These should get escaped, even though they're matching pairs for+other Markdown constructs:</p>++<p>*asterisks*</p>++<p>_underscores_</p>++<p>`backticks`</p>++<p>This is a code span with a literal backslash-backtick sequence: <code>\`</code></p>++<p>This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.</p>++<p>This is a tag with backslashes <span attr='\\backslashes\\'>bar</span>.</p>
+ tests/MarkdownTest_1.0.3/Tests/Backslash escapes.text view
@@ -0,0 +1,120 @@+These should all get escaped:++Backslash: \\++Backtick: \`++Asterisk: \*++Underscore: \_++Left brace: \{++Right brace: \}++Left bracket: \[++Right bracket: \]++Left paren: \(++Right paren: \)++Greater-than: \>++Hash: \#++Period: \.++Bang: \!++Plus: \+++Minus: \-++++These should not, because they occur within a code block:++ Backslash: \\++ Backtick: \`++ Asterisk: \*++ Underscore: \_++ Left brace: \{++ Right brace: \}++ Left bracket: \[++ Right bracket: \]++ Left paren: \(++ Right paren: \)++ Greater-than: \>++ Hash: \#++ Period: \.++ Bang: \!++ Plus: \+++ Minus: \-+++Nor should these, which occur in code spans:++Backslash: `\\`++Backtick: `` \` ``++Asterisk: `\*`++Underscore: `\_`++Left brace: `\{`++Right brace: `\}`++Left bracket: `\[`++Right bracket: `\]`++Left paren: `\(`++Right paren: `\)`++Greater-than: `\>`++Hash: `\#`++Period: `\.`++Bang: `\!`++Plus: `\+`++Minus: `\-`+++These should get escaped, even though they're matching pairs for+other Markdown constructs:++\*asterisks\*++\_underscores\_++\`backticks\`++This is a code span with a literal backslash-backtick sequence: `` \` ``++This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.++This is a tag with backslashes <span attr='\\backslashes\\'>bar</span>.
+ tests/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html view
@@ -0,0 +1,15 @@+<blockquote>+ <p>Example:</p>++<pre><code>sub status {+ print "working";+}+</code></pre>+ + <p>Or:</p>++<pre><code>sub status {+ return "working";+}+</code></pre>+</blockquote>
+ tests/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text view
@@ -0,0 +1,11 @@+> Example:+> +> sub status {+> print "working";+> }+> +> Or:+> +> sub status {+> return "working";+> }
+ tests/MarkdownTest_1.0.3/Tests/Code Blocks.html view
@@ -0,0 +1,18 @@+<pre><code>code block on the first line+</code></pre>++<p>Regular text.</p>++<pre><code>code block indented by spaces+</code></pre>++<p>Regular text.</p>++<pre><code>the lines in this block +all contain trailing spaces +</code></pre>++<p>Regular Text.</p>++<pre><code>code block on the last line+</code></pre>
+ tests/MarkdownTest_1.0.3/Tests/Code Blocks.text view
@@ -0,0 +1,14 @@+ code block on the first line+ +Regular text.++ code block indented by spaces++Regular text.++ the lines in this block + all contain trailing spaces ++Regular Text.++ code block on the last line
+ tests/MarkdownTest_1.0.3/Tests/Code Spans.html view
@@ -0,0 +1,6 @@+<p><code><test a="</code> content of attribute <code>"></code></p>++<p>Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span></p>++<p>Here's how you put <code>`backticks`</code> in a code span.</p>+
+ tests/MarkdownTest_1.0.3/Tests/Code Spans.text view
@@ -0,0 +1,6 @@+`<test a="` content of attribute `">`++Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span>++Here's how you put `` `backticks` `` in a code span.+
+ tests/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html view
@@ -0,0 +1,8 @@+<p>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.</p>++<p>Here's one with a bullet.+* criminey.</p>
+ tests/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text view
@@ -0,0 +1,8 @@+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.++Here's one with a bullet.+* criminey.
+ tests/MarkdownTest_1.0.3/Tests/Horizontal rules.html view
@@ -0,0 +1,71 @@+<p>Dashes:</p>++<hr />++<hr />++<hr />++<hr />++<pre><code>---+</code></pre>++<hr />++<hr />++<hr />++<hr />++<pre><code>- - -+</code></pre>++<p>Asterisks:</p>++<hr />++<hr />++<hr />++<hr />++<pre><code>***+</code></pre>++<hr />++<hr />++<hr />++<hr />++<pre><code>* * *+</code></pre>++<p>Underscores:</p>++<hr />++<hr />++<hr />++<hr />++<pre><code>___+</code></pre>++<hr />++<hr />++<hr />++<hr />++<pre><code>_ _ _+</code></pre>
+ tests/MarkdownTest_1.0.3/Tests/Horizontal rules.text view
@@ -0,0 +1,67 @@+Dashes:++---++ ---+ + ---++ ---++ ---++- - -++ - - -+ + - - -++ - - -++ - - -+++Asterisks:++***++ ***+ + ***++ ***++ ***++* * *++ * * *+ + * * *++ * * *++ * * *+++Underscores:++___++ ___+ + ___++ ___++ ___++_ _ _++ _ _ _+ + _ _ _++ _ _ _++ _ _ _
+ tests/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html view
@@ -0,0 +1,15 @@+<p>Simple block on one line:</p>++<div>foo</div>++<p>And nested without indentation:</p>++<div>+<div>+<div>+foo+</div>+<div style=">"/>+</div>+<div>bar</div>+</div>
+ tests/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text view
@@ -0,0 +1,15 @@+Simple block on one line:++<div>foo</div>++And nested without indentation:++<div>+<div>+<div>+foo+</div>+<div style=">"/>+</div>+<div>bar</div>+</div>
+ tests/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html view
@@ -0,0 +1,72 @@+<p>Here's a simple block:</p>++<div>+ foo+</div>++<p>This should be a code block, though:</p>++<pre><code><div>+ foo+</div>+</code></pre>++<p>As should this:</p>++<pre><code><div>foo</div>+</code></pre>++<p>Now, nested:</p>++<div>+ <div>+ <div>+ foo+ </div>+ </div>+</div>++<p>This should just be an HTML comment:</p>++<!-- Comment -->++<p>Multiline:</p>++<!--+Blah+Blah+-->++<p>Code block:</p>++<pre><code><!-- Comment -->+</code></pre>++<p>Just plain comment, with trailing spaces on the line:</p>++<!-- foo --> ++<p>Code:</p>++<pre><code><hr />+</code></pre>++<p>Hr's:</p>++<hr>++<hr/>++<hr />++<hr> ++<hr/> ++<hr /> ++<hr class="foo" id="bar" />++<hr class="foo" id="bar"/>++<hr class="foo" id="bar" >
+ tests/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text view
@@ -0,0 +1,69 @@+Here's a simple block:++<div>+ foo+</div>++This should be a code block, though:++ <div>+ foo+ </div>++As should this:++ <div>foo</div>++Now, nested:++<div>+ <div>+ <div>+ foo+ </div>+ </div>+</div>++This should just be an HTML comment:++<!-- Comment -->++Multiline:++<!--+Blah+Blah+-->++Code block:++ <!-- Comment -->++Just plain comment, with trailing spaces on the line:++<!-- foo --> ++Code:++ <hr />+ +Hr's:++<hr>++<hr/>++<hr />++<hr> ++<hr/> ++<hr /> ++<hr class="foo" id="bar" />++<hr class="foo" id="bar"/>++<hr class="foo" id="bar" >+
+ tests/MarkdownTest_1.0.3/Tests/Inline HTML comments.html view
@@ -0,0 +1,13 @@+<p>Paragraph one.</p>++<!-- This is a simple comment -->++<!--+ This is another comment.+-->++<p>Paragraph two.</p>++<!-- one comment block -- -- with two comments -->++<p>The end.</p>
+ tests/MarkdownTest_1.0.3/Tests/Inline HTML comments.text view
@@ -0,0 +1,13 @@+Paragraph one.++<!-- This is a simple comment -->++<!--+ This is another comment.+-->++Paragraph two.++<!-- one comment block -- -- with two comments -->++The end.
+ tests/MarkdownTest_1.0.3/Tests/Links, inline style.html view
@@ -0,0 +1,11 @@+<p>Just a <a href="/url/">URL</a>.</p>++<p><a href="/url/" title="title">URL and title</a>.</p>++<p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p>++<p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p>++<p><a href="/url/" title="title has spaces afterward">URL and title</a>.</p>++<p><a href="">Empty</a>.</p>
+ tests/MarkdownTest_1.0.3/Tests/Links, inline style.text view
@@ -0,0 +1,12 @@+Just a [URL](/url/).++[URL and title](/url/ "title").++[URL and title](/url/ "title preceded by two spaces").++[URL and title](/url/ "title preceded by a tab").++[URL and title](/url/ "title has spaces afterward" ).+++[Empty]().
+ tests/MarkdownTest_1.0.3/Tests/Links, reference style.html view
@@ -0,0 +1,52 @@+<p>Foo <a href="/url/" title="Title">bar</a>.</p>++<p>Foo <a href="/url/" title="Title">bar</a>.</p>++<p>Foo <a href="/url/" title="Title">bar</a>.</p>++<p>With <a href="/url/">embedded [brackets]</a>.</p>++<p>Indented <a href="/url">once</a>.</p>++<p>Indented <a href="/url">twice</a>.</p>++<p>Indented <a href="/url">thrice</a>.</p>++<p>Indented [four][] times.</p>++<pre><code>[four]: /url+</code></pre>++<hr />++<p><a href="foo">this</a> should work</p>++<p>So should <a href="foo">this</a>.</p>++<p>And <a href="foo">this</a>.</p>++<p>And <a href="foo">this</a>.</p>++<p>And <a href="foo">this</a>.</p>++<p>But not [that] [].</p>++<p>Nor [that][].</p>++<p>Nor [that].</p>++<p>[Something in brackets like <a href="foo">this</a> should work]</p>++<p>[Same with <a href="foo">this</a>.]</p>++<p>In this case, <a href="/somethingelse/">this</a> points to something else.</p>++<p>Backslashing should suppress [this] and [this].</p>++<hr />++<p>Here's one where the <a href="/url/">link+breaks</a> across lines.</p>++<p>Here's another where the <a href="/url/">link +breaks</a> across lines, but with a line-ending space.</p>
+ tests/MarkdownTest_1.0.3/Tests/Links, reference style.text view
@@ -0,0 +1,71 @@+Foo [bar] [1].++Foo [bar][1].++Foo [bar]+[1].++[1]: /url/ "Title"+++With [embedded [brackets]] [b].+++Indented [once][].++Indented [twice][].++Indented [thrice][].++Indented [four][] times.++ [once]: /url++ [twice]: /url++ [thrice]: /url++ [four]: /url+++[b]: /url/++* * *++[this] [this] should work++So should [this][this].++And [this] [].++And [this][].++And [this].++But not [that] [].++Nor [that][].++Nor [that].++[Something in brackets like [this][] should work]++[Same with [this].]++In this case, [this](/somethingelse/) points to something else.++Backslashing should suppress \[this] and [this\].++[this]: foo+++* * *++Here's one where the [link+breaks] across lines.++Here's another where the [link +breaks] across lines, but with a line-ending space.+++[link breaks]: /url/
+ tests/MarkdownTest_1.0.3/Tests/Links, shortcut references.html view
@@ -0,0 +1,9 @@+<p>This is the <a href="/simple">simple case</a>.</p>++<p>This one has a <a href="/foo">line+break</a>.</p>++<p>This one has a <a href="/foo">line +break</a> with a line-ending space.</p>++<p><a href="/that">this</a> and the <a href="/other">other</a></p>
+ tests/MarkdownTest_1.0.3/Tests/Links, shortcut references.text view
@@ -0,0 +1,20 @@+This is the [simple case].++[simple case]: /simple++++This one has a [line+break].++This one has a [line +break] with a line-ending space.++[line break]: /foo+++[this] [that] and the [other]++[this]: /this+[that]: /that+[other]: /other
+ tests/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html view
@@ -0,0 +1,3 @@+<p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p>++<p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p>
+ tests/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text view
@@ -0,0 +1,7 @@+Foo [bar][].++Foo [bar](/url/ "Title with "quotes" inside").+++ [bar]: /url/ "Title with "quotes" inside"+
+ tests/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html view
@@ -0,0 +1,314 @@+<h1>Markdown: Basics</h1>++<ul id="ProjectSubmenu">+ <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>+ <li><a class="selected" title="Markdown Basics">Basics</a></li>+ <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>+ <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>+ <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>+</ul>++<h2>Getting the Gist of Markdown's Formatting Syntax</h2>++<p>This page offers a brief overview of what it's like to use Markdown.+The <a href="/projects/markdown/syntax" title="Markdown Syntax">syntax page</a> provides complete, detailed documentation for+every feature, but Markdown should be very easy to pick up simply by+looking at a few examples of it in action. The examples on this page+are written in a before/after style, showing example syntax and the+HTML output produced by Markdown.</p>++<p>It's also helpful to simply try Markdown out; the <a href="/projects/markdown/dingus" title="Markdown Dingus">Dingus</a> is a+web application that allows you type your own Markdown-formatted text+and translate it to XHTML.</p>++<p><strong>Note:</strong> This document is itself written using Markdown; you+can <a href="/projects/markdown/basics.text">see the source for it by adding '.text' to the URL</a>.</p>++<h2>Paragraphs, Headers, Blockquotes</h2>++<p>A paragraph is simply one or more consecutive lines of text, separated+by one or more blank lines. (A blank line is any line that looks like a+blank line -- a line containing nothing spaces or tabs is considered+blank.) Normal paragraphs should not be intended with spaces or tabs.</p>++<p>Markdown offers two styles of headers: <em>Setext</em> and <em>atx</em>.+Setext-style headers for <code><h1></code> and <code><h2></code> are created by+"underlining" with equal signs (<code>=</code>) and hyphens (<code>-</code>), respectively.+To create an atx-style header, you put 1-6 hash marks (<code>#</code>) at the+beginning of the line -- the number of hashes equals the resulting+HTML header level.</p>++<p>Blockquotes are indicated using email-style '<code>></code>' angle brackets.</p>++<p>Markdown:</p>++<pre><code>A First Level Header+====================++A Second Level Header+---------------------++Now is the time for all good men to come to+the aid of their country. This is just a+regular paragraph.++The quick brown fox jumped over the lazy+dog's back.++### Header 3++> This is a blockquote.+> +> This is the second paragraph in the blockquote.+>+> ## This is an H2 in a blockquote+</code></pre>++<p>Output:</p>++<pre><code><h1>A First Level Header</h1>++<h2>A Second Level Header</h2>++<p>Now is the time for all good men to come to+the aid of their country. This is just a+regular paragraph.</p>++<p>The quick brown fox jumped over the lazy+dog's back.</p>++<h3>Header 3</h3>++<blockquote>+ <p>This is a blockquote.</p>++ <p>This is the second paragraph in the blockquote.</p>++ <h2>This is an H2 in a blockquote</h2>+</blockquote>+</code></pre>++<h3>Phrase Emphasis</h3>++<p>Markdown uses asterisks and underscores to indicate spans of emphasis.</p>++<p>Markdown:</p>++<pre><code>Some of these words *are emphasized*.+Some of these words _are emphasized also_.++Use two asterisks for **strong emphasis**.+Or, if you prefer, __use two underscores instead__.+</code></pre>++<p>Output:</p>++<pre><code><p>Some of these words <em>are emphasized</em>.+Some of these words <em>are emphasized also</em>.</p>++<p>Use two asterisks for <strong>strong emphasis</strong>.+Or, if you prefer, <strong>use two underscores instead</strong>.</p>+</code></pre>++<h2>Lists</h2>++<p>Unordered (bulleted) lists use asterisks, pluses, and hyphens (<code>*</code>,+<code>+</code>, and <code>-</code>) as list markers. These three markers are+interchangable; this:</p>++<pre><code>* Candy.+* Gum.+* Booze.+</code></pre>++<p>this:</p>++<pre><code>+ Candy.++ Gum.++ Booze.+</code></pre>++<p>and this:</p>++<pre><code>- Candy.+- Gum.+- Booze.+</code></pre>++<p>all produce the same output:</p>++<pre><code><ul>+<li>Candy.</li>+<li>Gum.</li>+<li>Booze.</li>+</ul>+</code></pre>++<p>Ordered (numbered) lists use regular numbers, followed by periods, as+list markers:</p>++<pre><code>1. Red+2. Green+3. Blue+</code></pre>++<p>Output:</p>++<pre><code><ol>+<li>Red</li>+<li>Green</li>+<li>Blue</li>+</ol>+</code></pre>++<p>If you put blank lines between items, you'll get <code><p></code> tags for the+list item text. You can create multi-paragraph list items by indenting+the paragraphs by 4 spaces or 1 tab:</p>++<pre><code>* A list item.++ With multiple paragraphs.++* Another item in the list.+</code></pre>++<p>Output:</p>++<pre><code><ul>+<li><p>A list item.</p>+<p>With multiple paragraphs.</p></li>+<li><p>Another item in the list.</p></li>+</ul>+</code></pre>++<h3>Links</h3>++<p>Markdown supports two styles for creating links: <em>inline</em> and+<em>reference</em>. With both styles, you use square brackets to delimit the+text you want to turn into a link.</p>++<p>Inline-style links use parentheses immediately after the link text.+For example:</p>++<pre><code>This is an [example link](http://example.com/).+</code></pre>++<p>Output:</p>++<pre><code><p>This is an <a href="http://example.com/">+example link</a>.</p>+</code></pre>++<p>Optionally, you may include a title attribute in the parentheses:</p>++<pre><code>This is an [example link](http://example.com/ "With a Title").+</code></pre>++<p>Output:</p>++<pre><code><p>This is an <a href="http://example.com/" title="With a Title">+example link</a>.</p>+</code></pre>++<p>Reference-style links allow you to refer to your links by names, which+you define elsewhere in your document:</p>++<pre><code>I get 10 times more traffic from [Google][1] than from+[Yahoo][2] or [MSN][3].++[1]: http://google.com/ "Google"+[2]: http://search.yahoo.com/ "Yahoo Search"+[3]: http://search.msn.com/ "MSN Search"+</code></pre>++<p>Output:</p>++<pre><code><p>I get 10 times more traffic from <a href="http://google.com/"+title="Google">Google</a> than from <a href="http://search.yahoo.com/"+title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"+title="MSN Search">MSN</a>.</p>+</code></pre>++<p>The title attribute is optional. Link names may contain letters,+numbers and spaces, but are <em>not</em> case sensitive:</p>++<pre><code>I start my morning with a cup of coffee and+[The New York Times][NY Times].++[ny times]: http://www.nytimes.com/+</code></pre>++<p>Output:</p>++<pre><code><p>I start my morning with a cup of coffee and+<a href="http://www.nytimes.com/">The New York Times</a>.</p>+</code></pre>++<h3>Images</h3>++<p>Image syntax is very much like link syntax.</p>++<p>Inline (titles are optional):</p>++<pre><code>+</code></pre>++<p>Reference-style:</p>++<pre><code>![alt text][id]++[id]: /path/to/img.jpg "Title"+</code></pre>++<p>Both of the above examples produce the same output:</p>++<pre><code><img src="/path/to/img.jpg" alt="alt text" title="Title" />+</code></pre>++<h3>Code</h3>++<p>In a regular paragraph, you can create code span by wrapping text in+backtick quotes. Any ampersands (<code>&</code>) and angle brackets (<code><</code> or+<code>></code>) will automatically be translated into HTML entities. This makes+it easy to use Markdown to write about HTML example code:</p>++<pre><code>I strongly recommend against using any `<blink>` tags.++I wish SmartyPants used named entities like `&mdash;`+instead of decimal-encoded entites like `&#8212;`.+</code></pre>++<p>Output:</p>++<pre><code><p>I strongly recommend against using any+<code>&lt;blink&gt;</code> tags.</p>++<p>I wish SmartyPants used named entities like+<code>&amp;mdash;</code> instead of decimal-encoded+entites like <code>&amp;#8212;</code>.</p>+</code></pre>++<p>To specify an entire block of pre-formatted code, indent every line of+the block by 4 spaces or 1 tab. Just like with code spans, <code>&</code>, <code><</code>,+and <code>></code> characters will be escaped automatically.</p>++<p>Markdown:</p>++<pre><code>If you want your page to validate under XHTML 1.0 Strict,+you've got to put paragraph tags in your blockquotes:++ <blockquote>+ <p>For example.</p>+ </blockquote>+</code></pre>++<p>Output:</p>++<pre><code><p>If you want your page to validate under XHTML 1.0 Strict,+you've got to put paragraph tags in your blockquotes:</p>++<pre><code>&lt;blockquote&gt;+ &lt;p&gt;For example.&lt;/p&gt;+&lt;/blockquote&gt;+</code></pre>+</code></pre>
+ tests/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text view
@@ -0,0 +1,306 @@+Markdown: Basics+================++<ul id="ProjectSubmenu">+ <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>+ <li><a class="selected" title="Markdown Basics">Basics</a></li>+ <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>+ <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>+ <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>+</ul>+++Getting the Gist of Markdown's Formatting Syntax+------------------------------------------------++This page offers a brief overview of what it's like to use Markdown.+The [syntax page] [s] provides complete, detailed documentation for+every feature, but Markdown should be very easy to pick up simply by+looking at a few examples of it in action. The examples on this page+are written in a before/after style, showing example syntax and the+HTML output produced by Markdown.++It's also helpful to simply try Markdown out; the [Dingus] [d] is a+web application that allows you type your own Markdown-formatted text+and translate it to XHTML.++**Note:** This document is itself written using Markdown; you+can [see the source for it by adding '.text' to the URL] [src].++ [s]: /projects/markdown/syntax "Markdown Syntax"+ [d]: /projects/markdown/dingus "Markdown Dingus"+ [src]: /projects/markdown/basics.text+++## Paragraphs, Headers, Blockquotes ##++A paragraph is simply one or more consecutive lines of text, separated+by one or more blank lines. (A blank line is any line that looks like a+blank line -- a line containing nothing spaces or tabs is considered+blank.) Normal paragraphs should not be intended with spaces or tabs.++Markdown offers two styles of headers: *Setext* and *atx*.+Setext-style headers for `<h1>` and `<h2>` are created by+"underlining" with equal signs (`=`) and hyphens (`-`), respectively.+To create an atx-style header, you put 1-6 hash marks (`#`) at the+beginning of the line -- the number of hashes equals the resulting+HTML header level.++Blockquotes are indicated using email-style '`>`' angle brackets.++Markdown:++ A First Level Header+ ====================+ + A Second Level Header+ ---------------------++ Now is the time for all good men to come to+ the aid of their country. This is just a+ regular paragraph.++ The quick brown fox jumped over the lazy+ dog's back.+ + ### Header 3++ > This is a blockquote.+ > + > This is the second paragraph in the blockquote.+ >+ > ## This is an H2 in a blockquote+++Output:++ <h1>A First Level Header</h1>+ + <h2>A Second Level Header</h2>+ + <p>Now is the time for all good men to come to+ the aid of their country. This is just a+ regular paragraph.</p>+ + <p>The quick brown fox jumped over the lazy+ dog's back.</p>+ + <h3>Header 3</h3>+ + <blockquote>+ <p>This is a blockquote.</p>+ + <p>This is the second paragraph in the blockquote.</p>+ + <h2>This is an H2 in a blockquote</h2>+ </blockquote>++++### Phrase Emphasis ###++Markdown uses asterisks and underscores to indicate spans of emphasis.++Markdown:++ Some of these words *are emphasized*.+ Some of these words _are emphasized also_.+ + Use two asterisks for **strong emphasis**.+ Or, if you prefer, __use two underscores instead__.++Output:++ <p>Some of these words <em>are emphasized</em>.+ Some of these words <em>are emphasized also</em>.</p>+ + <p>Use two asterisks for <strong>strong emphasis</strong>.+ Or, if you prefer, <strong>use two underscores instead</strong>.</p>+ +++## Lists ##++Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,+`+`, and `-`) as list markers. These three markers are+interchangable; this:++ * Candy.+ * Gum.+ * Booze.++this:++ + Candy.+ + Gum.+ + Booze.++and this:++ - Candy.+ - Gum.+ - Booze.++all produce the same output:++ <ul>+ <li>Candy.</li>+ <li>Gum.</li>+ <li>Booze.</li>+ </ul>++Ordered (numbered) lists use regular numbers, followed by periods, as+list markers:++ 1. Red+ 2. Green+ 3. Blue++Output:++ <ol>+ <li>Red</li>+ <li>Green</li>+ <li>Blue</li>+ </ol>++If you put blank lines between items, you'll get `<p>` tags for the+list item text. You can create multi-paragraph list items by indenting+the paragraphs by 4 spaces or 1 tab:++ * A list item.+ + With multiple paragraphs.++ * Another item in the list.++Output:++ <ul>+ <li><p>A list item.</p>+ <p>With multiple paragraphs.</p></li>+ <li><p>Another item in the list.</p></li>+ </ul>+ +++### Links ###++Markdown supports two styles for creating links: *inline* and+*reference*. With both styles, you use square brackets to delimit the+text you want to turn into a link.++Inline-style links use parentheses immediately after the link text.+For example:++ This is an [example link](http://example.com/).++Output:++ <p>This is an <a href="http://example.com/">+ example link</a>.</p>++Optionally, you may include a title attribute in the parentheses:++ This is an [example link](http://example.com/ "With a Title").++Output:++ <p>This is an <a href="http://example.com/" title="With a Title">+ example link</a>.</p>++Reference-style links allow you to refer to your links by names, which+you define elsewhere in your document:++ I get 10 times more traffic from [Google][1] than from+ [Yahoo][2] or [MSN][3].++ [1]: http://google.com/ "Google"+ [2]: http://search.yahoo.com/ "Yahoo Search"+ [3]: http://search.msn.com/ "MSN Search"++Output:++ <p>I get 10 times more traffic from <a href="http://google.com/"+ title="Google">Google</a> than from <a href="http://search.yahoo.com/"+ title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"+ title="MSN Search">MSN</a>.</p>++The title attribute is optional. Link names may contain letters,+numbers and spaces, but are *not* case sensitive:++ I start my morning with a cup of coffee and+ [The New York Times][NY Times].++ [ny times]: http://www.nytimes.com/++Output:++ <p>I start my morning with a cup of coffee and+ <a href="http://www.nytimes.com/">The New York Times</a>.</p>+++### Images ###++Image syntax is very much like link syntax.++Inline (titles are optional):++ ++Reference-style:++ ![alt text][id]++ [id]: /path/to/img.jpg "Title"++Both of the above examples produce the same output:++ <img src="/path/to/img.jpg" alt="alt text" title="Title" />++++### Code ###++In a regular paragraph, you can create code span by wrapping text in+backtick quotes. Any ampersands (`&`) and angle brackets (`<` or+`>`) will automatically be translated into HTML entities. This makes+it easy to use Markdown to write about HTML example code:++ I strongly recommend against using any `<blink>` tags.++ I wish SmartyPants used named entities like `—`+ instead of decimal-encoded entites like `—`.++Output:++ <p>I strongly recommend against using any+ <code><blink></code> tags.</p>+ + <p>I wish SmartyPants used named entities like+ <code>&mdash;</code> instead of decimal-encoded+ entites like <code>&#8212;</code>.</p>+++To specify an entire block of pre-formatted code, indent every line of+the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`,+and `>` characters will be escaped automatically.++Markdown:++ If you want your page to validate under XHTML 1.0 Strict,+ you've got to put paragraph tags in your blockquotes:++ <blockquote>+ <p>For example.</p>+ </blockquote>++Output:++ <p>If you want your page to validate under XHTML 1.0 Strict,+ you've got to put paragraph tags in your blockquotes:</p>+ + <pre><code><blockquote>+ <p>For example.</p>+ </blockquote>+ </code></pre>
+ tests/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html view
@@ -0,0 +1,942 @@+<h1>Markdown: Syntax</h1>++<ul id="ProjectSubmenu">+ <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>+ <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>+ <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>+ <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>+ <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>+</ul>++<ul>+<li><a href="#overview">Overview</a>+<ul>+<li><a href="#philosophy">Philosophy</a></li>+<li><a href="#html">Inline HTML</a></li>+<li><a href="#autoescape">Automatic Escaping for Special Characters</a></li>+</ul></li>+<li><a href="#block">Block Elements</a>+<ul>+<li><a href="#p">Paragraphs and Line Breaks</a></li>+<li><a href="#header">Headers</a></li>+<li><a href="#blockquote">Blockquotes</a></li>+<li><a href="#list">Lists</a></li>+<li><a href="#precode">Code Blocks</a></li>+<li><a href="#hr">Horizontal Rules</a></li>+</ul></li>+<li><a href="#span">Span Elements</a>+<ul>+<li><a href="#link">Links</a></li>+<li><a href="#em">Emphasis</a></li>+<li><a href="#code">Code</a></li>+<li><a href="#img">Images</a></li>+</ul></li>+<li><a href="#misc">Miscellaneous</a>+<ul>+<li><a href="#backslash">Backslash Escapes</a></li>+<li><a href="#autolink">Automatic Links</a></li>+</ul></li>+</ul>++<p><strong>Note:</strong> This document is itself written using Markdown; you+can <a href="/projects/markdown/syntax.text">see the source for it by adding '.text' to the URL</a>.</p>++<hr />++<h2 id="overview">Overview</h2>++<h3 id="philosophy">Philosophy</h3>++<p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p>++<p>Readability, however, is emphasized above all else. A Markdown-formatted+document should be publishable as-is, as plain text, without looking+like it's been marked up with tags or formatting instructions. While+Markdown's syntax has been influenced by several existing text-to-HTML+filters -- including <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a>, <a href="http://www.aaronsw.com/2002/atx/">atx</a>, <a href="http://textism.com/tools/textile/">Textile</a>, <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>,+<a href="http://www.triptico.com/software/grutatxt.html">Grutatext</a>, and <a href="http://ettext.taint.org/doc/">EtText</a> -- the single biggest source of+inspiration for Markdown's syntax is the format of plain text email.</p>++<p>To this end, Markdown's syntax is comprised entirely of punctuation+characters, which punctuation characters have been carefully chosen so+as to look like what they mean. E.g., asterisks around a word actually+look like *emphasis*. Markdown lists look like, well, lists. Even+blockquotes look like quoted passages of text, assuming you've ever+used email.</p>++<h3 id="html">Inline HTML</h3>++<p>Markdown's syntax is intended for one purpose: to be used as a+format for <em>writing</em> for the web.</p>++<p>Markdown is not a replacement for HTML, or even close to it. Its+syntax is very small, corresponding only to a very small subset of+HTML tags. The idea is <em>not</em> to create a syntax that makes it easier+to insert HTML tags. In my opinion, HTML tags are already easy to+insert. The idea for Markdown is to make it easy to read, write, and+edit prose. HTML is a <em>publishing</em> format; Markdown is a <em>writing</em>+format. Thus, Markdown's formatting syntax only addresses issues that+can be conveyed in plain text.</p>++<p>For any markup that is not covered by Markdown's syntax, you simply+use HTML itself. There's no need to preface it or delimit it to+indicate that you're switching from Markdown to HTML; you just use+the tags.</p>++<p>The only restrictions are that block-level HTML elements -- e.g. <code><div></code>,+<code><table></code>, <code><pre></code>, <code><p></code>, etc. -- must be separated from surrounding+content by blank lines, and the start and end tags of the block should+not be indented with tabs or spaces. Markdown is smart enough not+to add extra (unwanted) <code><p></code> tags around HTML block-level tags.</p>++<p>For example, to add an HTML table to a Markdown article:</p>++<pre><code>This is a regular paragraph.++<table>+ <tr>+ <td>Foo</td>+ </tr>+</table>++This is another regular paragraph.+</code></pre>++<p>Note that Markdown formatting syntax is not processed within block-level+HTML tags. E.g., you can't use Markdown-style <code>*emphasis*</code> inside an+HTML block.</p>++<p>Span-level HTML tags -- e.g. <code><span></code>, <code><cite></code>, or <code><del></code> -- can be+used anywhere in a Markdown paragraph, list item, or header. If you+want, you can even use HTML tags instead of Markdown formatting; e.g. if+you'd prefer to use HTML <code><a></code> or <code><img></code> tags instead of Markdown's+link or image syntax, go right ahead.</p>++<p>Unlike block-level HTML tags, Markdown syntax <em>is</em> processed within+span-level tags.</p>++<h3 id="autoescape">Automatic Escaping for Special Characters</h3>++<p>In HTML, there are two characters that demand special treatment: <code><</code>+and <code>&</code>. Left angle brackets are used to start tags; ampersands are+used to denote HTML entities. If you want to use them as literal+characters, you must escape them as entities, e.g. <code>&lt;</code>, and+<code>&amp;</code>.</p>++<p>Ampersands in particular are bedeviling for web writers. If you want to+write about 'AT&T', you need to write '<code>AT&amp;T</code>'. You even need to+escape ampersands within URLs. Thus, if you want to link to:</p>++<pre><code>http://images.google.com/images?num=30&q=larry+bird+</code></pre>++<p>you need to encode the URL as:</p>++<pre><code>http://images.google.com/images?num=30&amp;q=larry+bird+</code></pre>++<p>in your anchor tag <code>href</code> attribute. Needless to say, this is easy to+forget, and is probably the single most common source of HTML validation+errors in otherwise well-marked-up web sites.</p>++<p>Markdown allows you to use these characters naturally, taking care of+all the necessary escaping for you. If you use an ampersand as part of+an HTML entity, it remains unchanged; otherwise it will be translated+into <code>&amp;</code>.</p>++<p>So, if you want to include a copyright symbol in your article, you can write:</p>++<pre><code>&copy;+</code></pre>++<p>and Markdown will leave it alone. But if you write:</p>++<pre><code>AT&T+</code></pre>++<p>Markdown will translate it to:</p>++<pre><code>AT&amp;T+</code></pre>++<p>Similarly, because Markdown supports <a href="#html">inline HTML</a>, if you use+angle brackets as delimiters for HTML tags, Markdown will treat them as+such. But if you write:</p>++<pre><code>4 < 5+</code></pre>++<p>Markdown will translate it to:</p>++<pre><code>4 &lt; 5+</code></pre>++<p>However, inside Markdown code spans and blocks, angle brackets and+ampersands are <em>always</em> encoded automatically. This makes it easy to use+Markdown to write about HTML code. (As opposed to raw HTML, which is a+terrible format for writing about HTML syntax, because every single <code><</code>+and <code>&</code> in your example code needs to be escaped.)</p>++<hr />++<h2 id="block">Block Elements</h2>++<h3 id="p">Paragraphs and Line Breaks</h3>++<p>A paragraph is simply one or more consecutive lines of text, separated+by one or more blank lines. (A blank line is any line that looks like a+blank line -- a line containing nothing but spaces or tabs is considered+blank.) Normal paragraphs should not be intended with spaces or tabs.</p>++<p>The implication of the "one or more consecutive lines of text" rule is+that Markdown supports "hard-wrapped" text paragraphs. This differs+significantly from most other text-to-HTML formatters (including Movable+Type's "Convert Line Breaks" option) which translate every line break+character in a paragraph into a <code><br /></code> tag.</p>++<p>When you <em>do</em> want to insert a <code><br /></code> break tag using Markdown, you+end a line with two or more spaces, then type return.</p>++<p>Yes, this takes a tad more effort to create a <code><br /></code>, but a simplistic+"every line break is a <code><br /></code>" rule wouldn't work for Markdown.+Markdown's email-style <a href="#blockquote">blockquoting</a> and multi-paragraph <a href="#list">list items</a>+work best -- and look better -- when you format them with hard breaks.</p>++<h3 id="header">Headers</h3>++<p>Markdown supports two styles of headers, <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a> and <a href="http://www.aaronsw.com/2002/atx/">atx</a>.</p>++<p>Setext-style headers are "underlined" using equal signs (for first-level+headers) and dashes (for second-level headers). For example:</p>++<pre><code>This is an H1+=============++This is an H2+-------------+</code></pre>++<p>Any number of underlining <code>=</code>'s or <code>-</code>'s will work.</p>++<p>Atx-style headers use 1-6 hash characters at the start of the line,+corresponding to header levels 1-6. For example:</p>++<pre><code># This is an H1++## This is an H2++###### This is an H6+</code></pre>++<p>Optionally, you may "close" atx-style headers. This is purely+cosmetic -- you can use this if you think it looks better. The+closing hashes don't even need to match the number of hashes+used to open the header. (The number of opening hashes+determines the header level.) :</p>++<pre><code># This is an H1 #++## This is an H2 ##++### This is an H3 ######+</code></pre>++<h3 id="blockquote">Blockquotes</h3>++<p>Markdown uses email-style <code>></code> characters for blockquoting. If you're+familiar with quoting passages of text in an email message, then you+know how to create a blockquote in Markdown. It looks best if you hard+wrap the text and put a <code>></code> before every line:</p>++<pre><code>> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,+> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.+> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.+> +> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse+> id sem consectetuer libero luctus adipiscing.+</code></pre>++<p>Markdown allows you to be lazy and only put the <code>></code> before the first+line of a hard-wrapped paragraph:</p>++<pre><code>> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,+consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.+Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.++> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse+id sem consectetuer libero luctus adipiscing.+</code></pre>++<p>Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by+adding additional levels of <code>></code>:</p>++<pre><code>> This is the first level of quoting.+>+> > This is nested blockquote.+>+> Back to the first level.+</code></pre>++<p>Blockquotes can contain other Markdown elements, including headers, lists,+and code blocks:</p>++<pre><code>> ## This is a header.+> +> 1. This is the first list item.+> 2. This is the second list item.+> +> Here's some example code:+> +> return shell_exec("echo $input | $markdown_script");+</code></pre>++<p>Any decent text editor should make email-style quoting easy. For+example, with BBEdit, you can make a selection and choose Increase+Quote Level from the Text menu.</p>++<h3 id="list">Lists</h3>++<p>Markdown supports ordered (numbered) and unordered (bulleted) lists.</p>++<p>Unordered lists use asterisks, pluses, and hyphens -- interchangably+-- as list markers:</p>++<pre><code>* Red+* Green+* Blue+</code></pre>++<p>is equivalent to:</p>++<pre><code>+ Red++ Green++ Blue+</code></pre>++<p>and:</p>++<pre><code>- Red+- Green+- Blue+</code></pre>++<p>Ordered lists use numbers followed by periods:</p>++<pre><code>1. Bird+2. McHale+3. Parish+</code></pre>++<p>It's important to note that the actual numbers you use to mark the+list have no effect on the HTML output Markdown produces. The HTML+Markdown produces from the above list is:</p>++<pre><code><ol>+<li>Bird</li>+<li>McHale</li>+<li>Parish</li>+</ol>+</code></pre>++<p>If you instead wrote the list in Markdown like this:</p>++<pre><code>1. Bird+1. McHale+1. Parish+</code></pre>++<p>or even:</p>++<pre><code>3. Bird+1. McHale+8. Parish+</code></pre>++<p>you'd get the exact same HTML output. The point is, if you want to,+you can use ordinal numbers in your ordered Markdown lists, so that+the numbers in your source match the numbers in your published HTML.+But if you want to be lazy, you don't have to.</p>++<p>If you do use lazy list numbering, however, you should still start the+list with the number 1. At some point in the future, Markdown may support+starting ordered lists at an arbitrary number.</p>++<p>List markers typically start at the left margin, but may be indented by+up to three spaces. List markers must be followed by one or more spaces+or a tab.</p>++<p>To make lists look nice, you can wrap items with hanging indents:</p>++<pre><code>* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.+ Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,+ viverra nec, fringilla in, laoreet vitae, risus.+* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.+ Suspendisse id sem consectetuer libero luctus adipiscing.+</code></pre>++<p>But if you want to be lazy, you don't have to:</p>++<pre><code>* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.+Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,+viverra nec, fringilla in, laoreet vitae, risus.+* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.+Suspendisse id sem consectetuer libero luctus adipiscing.+</code></pre>++<p>If list items are separated by blank lines, Markdown will wrap the+items in <code><p></code> tags in the HTML output. For example, this input:</p>++<pre><code>* Bird+* Magic+</code></pre>++<p>will turn into:</p>++<pre><code><ul>+<li>Bird</li>+<li>Magic</li>+</ul>+</code></pre>++<p>But this:</p>++<pre><code>* Bird++* Magic+</code></pre>++<p>will turn into:</p>++<pre><code><ul>+<li><p>Bird</p></li>+<li><p>Magic</p></li>+</ul>+</code></pre>++<p>List items may consist of multiple paragraphs. Each subsequent+paragraph in a list item must be intended by either 4 spaces+or one tab:</p>++<pre><code>1. This is a list item with two paragraphs. Lorem ipsum dolor+ sit amet, consectetuer adipiscing elit. Aliquam hendrerit+ mi posuere lectus.++ Vestibulum enim wisi, viverra nec, fringilla in, laoreet+ vitae, risus. Donec sit amet nisl. Aliquam semper ipsum+ sit amet velit.++2. Suspendisse id sem consectetuer libero luctus adipiscing.+</code></pre>++<p>It looks nice if you indent every line of the subsequent+paragraphs, but here again, Markdown will allow you to be+lazy:</p>++<pre><code>* This is a list item with two paragraphs.++ This is the second paragraph in the list item. You're+only required to indent the first line. Lorem ipsum dolor+sit amet, consectetuer adipiscing elit.++* Another item in the same list.+</code></pre>++<p>To put a blockquote within a list item, the blockquote's <code>></code>+delimiters need to be indented:</p>++<pre><code>* A list item with a blockquote:++ > This is a blockquote+ > inside a list item.+</code></pre>++<p>To put a code block within a list item, the code block needs+to be indented <em>twice</em> -- 8 spaces or two tabs:</p>++<pre><code>* A list item with a code block:++ <code goes here>+</code></pre>++<p>It's worth noting that it's possible to trigger an ordered list by+accident, by writing something like this:</p>++<pre><code>1986. What a great season.+</code></pre>++<p>In other words, a <em>number-period-space</em> sequence at the beginning of a+line. To avoid this, you can backslash-escape the period:</p>++<pre><code>1986\. What a great season.+</code></pre>++<h3 id="precode">Code Blocks</h3>++<p>Pre-formatted code blocks are used for writing about programming or+markup source code. Rather than forming normal paragraphs, the lines+of a code block are interpreted literally. Markdown wraps a code block+in both <code><pre></code> and <code><code></code> tags.</p>++<p>To produce a code block in Markdown, simply indent every line of the+block by at least 4 spaces or 1 tab. For example, given this input:</p>++<pre><code>This is a normal paragraph:++ This is a code block.+</code></pre>++<p>Markdown will generate:</p>++<pre><code><p>This is a normal paragraph:</p>++<pre><code>This is a code block.+</code></pre>+</code></pre>++<p>One level of indentation -- 4 spaces or 1 tab -- is removed from each+line of the code block. For example, this:</p>++<pre><code>Here is an example of AppleScript:++ tell application "Foo"+ beep+ end tell+</code></pre>++<p>will turn into:</p>++<pre><code><p>Here is an example of AppleScript:</p>++<pre><code>tell application "Foo"+ beep+end tell+</code></pre>+</code></pre>++<p>A code block continues until it reaches a line that is not indented+(or the end of the article).</p>++<p>Within a code block, ampersands (<code>&</code>) and angle brackets (<code><</code> and <code>></code>)+are automatically converted into HTML entities. This makes it very+easy to include example HTML source code using Markdown -- just paste+it and indent it, and Markdown will handle the hassle of encoding the+ampersands and angle brackets. For example, this:</p>++<pre><code> <div class="footer">+ &copy; 2004 Foo Corporation+ </div>+</code></pre>++<p>will turn into:</p>++<pre><code><pre><code>&lt;div class="footer"&gt;+ &amp;copy; 2004 Foo Corporation+&lt;/div&gt;+</code></pre>+</code></pre>++<p>Regular Markdown syntax is not processed within code blocks. E.g.,+asterisks are just literal asterisks within a code block. This means+it's also easy to use Markdown to write about Markdown's own syntax.</p>++<h3 id="hr">Horizontal Rules</h3>++<p>You can produce a horizontal rule tag (<code><hr /></code>) by placing three or+more hyphens, asterisks, or underscores on a line by themselves. If you+wish, you may use spaces between the hyphens or asterisks. Each of the+following lines will produce a horizontal rule:</p>++<pre><code>* * *++***++*****++- - -++---------------------------------------++_ _ _+</code></pre>++<hr />++<h2 id="span">Span Elements</h2>++<h3 id="link">Links</h3>++<p>Markdown supports two style of links: <em>inline</em> and <em>reference</em>.</p>++<p>In both styles, the link text is delimited by [square brackets].</p>++<p>To create an inline link, use a set of regular parentheses immediately+after the link text's closing square bracket. Inside the parentheses,+put the URL where you want the link to point, along with an <em>optional</em>+title for the link, surrounded in quotes. For example:</p>++<pre><code>This is [an example](http://example.com/ "Title") inline link.++[This link](http://example.net/) has no title attribute.+</code></pre>++<p>Will produce:</p>++<pre><code><p>This is <a href="http://example.com/" title="Title">+an example</a> inline link.</p>++<p><a href="http://example.net/">This link</a> has no+title attribute.</p>+</code></pre>++<p>If you're referring to a local resource on the same server, you can+use relative paths:</p>++<pre><code>See my [About](/about/) page for details.+</code></pre>++<p>Reference-style links use a second set of square brackets, inside+which you place a label of your choosing to identify the link:</p>++<pre><code>This is [an example][id] reference-style link.+</code></pre>++<p>You can optionally use a space to separate the sets of brackets:</p>++<pre><code>This is [an example] [id] reference-style link.+</code></pre>++<p>Then, anywhere in the document, you define your link label like this,+on a line by itself:</p>++<pre><code>[id]: http://example.com/ "Optional Title Here"+</code></pre>++<p>That is:</p>++<ul>+<li>Square brackets containing the link identifier (optionally+indented from the left margin using up to three spaces);</li>+<li>followed by a colon;</li>+<li>followed by one or more spaces (or tabs);</li>+<li>followed by the URL for the link;</li>+<li>optionally followed by a title attribute for the link, enclosed+in double or single quotes.</li>+</ul>++<p>The link URL may, optionally, be surrounded by angle brackets:</p>++<pre><code>[id]: <http://example.com/> "Optional Title Here"+</code></pre>++<p>You can put the title attribute on the next line and use extra spaces+or tabs for padding, which tends to look better with longer URLs:</p>++<pre><code>[id]: http://example.com/longish/path/to/resource/here+ "Optional Title Here"+</code></pre>++<p>Link definitions are only used for creating links during Markdown+processing, and are stripped from your document in the HTML output.</p>++<p>Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are <em>not</em> case sensitive. E.g. these two links:</p>++<pre><code>[link text][a]+[link text][A]+</code></pre>++<p>are equivalent.</p>++<p>The <em>implicit link name</em> shortcut allows you to omit the name of the+link, in which case the link text itself is used as the name.+Just use an empty set of square brackets -- e.g., to link the word+"Google" to the google.com web site, you could simply write:</p>++<pre><code>[Google][]+</code></pre>++<p>And then define the link:</p>++<pre><code>[Google]: http://google.com/+</code></pre>++<p>Because link names may contain spaces, this shortcut even works for+multiple words in the link text:</p>++<pre><code>Visit [Daring Fireball][] for more information.+</code></pre>++<p>And then define the link:</p>++<pre><code>[Daring Fireball]: http://daringfireball.net/+</code></pre>++<p>Link definitions can be placed anywhere in your Markdown document. I+tend to put them immediately after each paragraph in which they're+used, but if you want, you can put them all at the end of your+document, sort of like footnotes.</p>++<p>Here's an example of reference links in action:</p>++<pre><code>I get 10 times more traffic from [Google] [1] than from+[Yahoo] [2] or [MSN] [3].++ [1]: http://google.com/ "Google"+ [2]: http://search.yahoo.com/ "Yahoo Search"+ [3]: http://search.msn.com/ "MSN Search"+</code></pre>++<p>Using the implicit link name shortcut, you could instead write:</p>++<pre><code>I get 10 times more traffic from [Google][] than from+[Yahoo][] or [MSN][].++ [google]: http://google.com/ "Google"+ [yahoo]: http://search.yahoo.com/ "Yahoo Search"+ [msn]: http://search.msn.com/ "MSN Search"+</code></pre>++<p>Both of the above examples will produce the following HTML output:</p>++<pre><code><p>I get 10 times more traffic from <a href="http://google.com/"+title="Google">Google</a> than from+<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>+or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>+</code></pre>++<p>For comparison, here is the same paragraph written using+Markdown's inline link style:</p>++<pre><code>I get 10 times more traffic from [Google](http://google.com/ "Google")+than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or+[MSN](http://search.msn.com/ "MSN Search").+</code></pre>++<p>The point of reference-style links is not that they're easier to+write. The point is that with reference-style links, your document+source is vastly more readable. Compare the above examples: using+reference-style links, the paragraph itself is only 81 characters+long; with inline-style links, it's 176 characters; and as raw HTML,+it's 234 characters. In the raw HTML, there's more markup than there+is text.</p>++<p>With Markdown's reference-style links, a source document much more+closely resembles the final output, as rendered in a browser. By+allowing you to move the markup-related metadata out of the paragraph,+you can add links without interrupting the narrative flow of your+prose.</p>++<h3 id="em">Emphasis</h3>++<p>Markdown treats asterisks (<code>*</code>) and underscores (<code>_</code>) as indicators of+emphasis. Text wrapped with one <code>*</code> or <code>_</code> will be wrapped with an+HTML <code><em></code> tag; double <code>*</code>'s or <code>_</code>'s will be wrapped with an HTML+<code><strong></code> tag. E.g., this input:</p>++<pre><code>*single asterisks*++_single underscores_++**double asterisks**++__double underscores__+</code></pre>++<p>will produce:</p>++<pre><code><em>single asterisks</em>++<em>single underscores</em>++<strong>double asterisks</strong>++<strong>double underscores</strong>+</code></pre>++<p>You can use whichever style you prefer; the lone restriction is that+the same character must be used to open and close an emphasis span.</p>++<p>Emphasis can be used in the middle of a word:</p>++<pre><code>un*fucking*believable+</code></pre>++<p>But if you surround an <code>*</code> or <code>_</code> with spaces, it'll be treated as a+literal asterisk or underscore.</p>++<p>To produce a literal asterisk or underscore at a position where it+would otherwise be used as an emphasis delimiter, you can backslash+escape it:</p>++<pre><code>\*this text is surrounded by literal asterisks\*+</code></pre>++<h3 id="code">Code</h3>++<p>To indicate a span of code, wrap it with backtick quotes (<code>`</code>).+Unlike a pre-formatted code block, a code span indicates code within a+normal paragraph. For example:</p>++<pre><code>Use the `printf()` function.+</code></pre>++<p>will produce:</p>++<pre><code><p>Use the <code>printf()</code> function.</p>+</code></pre>++<p>To include a literal backtick character within a code span, you can use+multiple backticks as the opening and closing delimiters:</p>++<pre><code>``There is a literal backtick (`) here.``+</code></pre>++<p>which will produce this:</p>++<pre><code><p><code>There is a literal backtick (`) here.</code></p>+</code></pre>++<p>The backtick delimiters surrounding a code span may include spaces --+one after the opening, one before the closing. This allows you to place+literal backtick characters at the beginning or end of a code span:</p>++<pre><code>A single backtick in a code span: `` ` ``++A backtick-delimited string in a code span: `` `foo` ``+</code></pre>++<p>will produce:</p>++<pre><code><p>A single backtick in a code span: <code>`</code></p>++<p>A backtick-delimited string in a code span: <code>`foo`</code></p>+</code></pre>++<p>With a code span, ampersands and angle brackets are encoded as HTML+entities automatically, which makes it easy to include example HTML+tags. Markdown will turn this:</p>++<pre><code>Please don't use any `<blink>` tags.+</code></pre>++<p>into:</p>++<pre><code><p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>+</code></pre>++<p>You can write this:</p>++<pre><code>`&#8212;` is the decimal-encoded equivalent of `&mdash;`.+</code></pre>++<p>to produce:</p>++<pre><code><p><code>&amp;#8212;</code> is the decimal-encoded+equivalent of <code>&amp;mdash;</code>.</p>+</code></pre>++<h3 id="img">Images</h3>++<p>Admittedly, it's fairly difficult to devise a "natural" syntax for+placing images into a plain text document format.</p>++<p>Markdown uses an image syntax that is intended to resemble the syntax+for links, allowing for two styles: <em>inline</em> and <em>reference</em>.</p>++<p>Inline image syntax looks like this:</p>++<pre><code>+++</code></pre>++<p>That is:</p>++<ul>+<li>An exclamation mark: <code>!</code>;</li>+<li>followed by a set of square brackets, containing the <code>alt</code>+attribute text for the image;</li>+<li>followed by a set of parentheses, containing the URL or path to+the image, and an optional <code>title</code> attribute enclosed in double+or single quotes.</li>+</ul>++<p>Reference-style image syntax looks like this:</p>++<pre><code>![Alt text][id]+</code></pre>++<p>Where "id" is the name of a defined image reference. Image references+are defined using syntax identical to link references:</p>++<pre><code>[id]: url/to/image "Optional title attribute"+</code></pre>++<p>As of this writing, Markdown has no syntax for specifying the+dimensions of an image; if this is important to you, you can simply+use regular HTML <code><img></code> tags.</p>++<hr />++<h2 id="misc">Miscellaneous</h2>++<h3 id="autolink">Automatic Links</h3>++<p>Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:</p>++<pre><code><http://example.com/>+</code></pre>++<p>Markdown will turn this into:</p>++<pre><code><a href="http://example.com/">http://example.com/</a>+</code></pre>++<p>Automatic links for email addresses work similarly, except that+Markdown will also perform a bit of randomized decimal and hex+entity-encoding to help obscure your address from address-harvesting+spambots. For example, Markdown will turn this:</p>++<pre><code><address@example.com>+</code></pre>++<p>into something like this:</p>++<pre><code><a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;+&#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;+&#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;+&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>+</code></pre>++<p>which will render in a browser as a clickable link to "address@example.com".</p>++<p>(This sort of entity-encoding trick will indeed fool many, if not+most, address-harvesting bots, but it definitely won't fool all of+them. It's better than nothing, but an address published in this way+will probably eventually start receiving spam.)</p>++<h3 id="backslash">Backslash Escapes</h3>++<p>Markdown allows you to use backslash escapes to generate literal+characters which would otherwise have special meaning in Markdown's+formatting syntax. For example, if you wanted to surround a word with+literal asterisks (instead of an HTML <code><em></code> tag), you can backslashes+before the asterisks, like this:</p>++<pre><code>\*literal asterisks\*+</code></pre>++<p>Markdown provides backslash escapes for the following characters:</p>++<pre><code>\ backslash+` backtick+* asterisk+_ underscore+{} curly braces+[] square brackets+() parentheses+# hash mark++ plus sign+- minus sign (hyphen)+. dot+! exclamation mark+</code></pre>
+ tests/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text view
@@ -0,0 +1,888 @@+Markdown: Syntax+================++<ul id="ProjectSubmenu">+ <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>+ <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>+ <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>+ <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>+ <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>+</ul>+++* [Overview](#overview)+ * [Philosophy](#philosophy)+ * [Inline HTML](#html)+ * [Automatic Escaping for Special Characters](#autoescape)+* [Block Elements](#block)+ * [Paragraphs and Line Breaks](#p)+ * [Headers](#header)+ * [Blockquotes](#blockquote)+ * [Lists](#list)+ * [Code Blocks](#precode)+ * [Horizontal Rules](#hr)+* [Span Elements](#span)+ * [Links](#link)+ * [Emphasis](#em)+ * [Code](#code)+ * [Images](#img)+* [Miscellaneous](#misc)+ * [Backslash Escapes](#backslash)+ * [Automatic Links](#autolink)+++**Note:** This document is itself written using Markdown; you+can [see the source for it by adding '.text' to the URL][src].++ [src]: /projects/markdown/syntax.text++* * *++<h2 id="overview">Overview</h2>++<h3 id="philosophy">Philosophy</h3>++Markdown is intended to be as easy-to-read and easy-to-write as is feasible.++Readability, however, is emphasized above all else. A Markdown-formatted+document should be publishable as-is, as plain text, without looking+like it's been marked up with tags or formatting instructions. While+Markdown's syntax has been influenced by several existing text-to-HTML+filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4],+[Grutatext] [5], and [EtText] [6] -- the single biggest source of+inspiration for Markdown's syntax is the format of plain text email.++ [1]: http://docutils.sourceforge.net/mirror/setext.html+ [2]: http://www.aaronsw.com/2002/atx/+ [3]: http://textism.com/tools/textile/+ [4]: http://docutils.sourceforge.net/rst.html+ [5]: http://www.triptico.com/software/grutatxt.html+ [6]: http://ettext.taint.org/doc/++To this end, Markdown's syntax is comprised entirely of punctuation+characters, which punctuation characters have been carefully chosen so+as to look like what they mean. E.g., asterisks around a word actually+look like \*emphasis\*. Markdown lists look like, well, lists. Even+blockquotes look like quoted passages of text, assuming you've ever+used email.++++<h3 id="html">Inline HTML</h3>++Markdown's syntax is intended for one purpose: to be used as a+format for *writing* for the web.++Markdown is not a replacement for HTML, or even close to it. Its+syntax is very small, corresponding only to a very small subset of+HTML tags. The idea is *not* to create a syntax that makes it easier+to insert HTML tags. In my opinion, HTML tags are already easy to+insert. The idea for Markdown is to make it easy to read, write, and+edit prose. HTML is a *publishing* format; Markdown is a *writing*+format. Thus, Markdown's formatting syntax only addresses issues that+can be conveyed in plain text.++For any markup that is not covered by Markdown's syntax, you simply+use HTML itself. There's no need to preface it or delimit it to+indicate that you're switching from Markdown to HTML; you just use+the tags.++The only restrictions are that block-level HTML elements -- e.g. `<div>`,+`<table>`, `<pre>`, `<p>`, etc. -- must be separated from surrounding+content by blank lines, and the start and end tags of the block should+not be indented with tabs or spaces. Markdown is smart enough not+to add extra (unwanted) `<p>` tags around HTML block-level tags.++For example, to add an HTML table to a Markdown article:++ This is a regular paragraph.++ <table>+ <tr>+ <td>Foo</td>+ </tr>+ </table>++ This is another regular paragraph.++Note that Markdown formatting syntax is not processed within block-level+HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an+HTML block.++Span-level HTML tags -- e.g. `<span>`, `<cite>`, or `<del>` -- can be+used anywhere in a Markdown paragraph, list item, or header. If you+want, you can even use HTML tags instead of Markdown formatting; e.g. if+you'd prefer to use HTML `<a>` or `<img>` tags instead of Markdown's+link or image syntax, go right ahead.++Unlike block-level HTML tags, Markdown syntax *is* processed within+span-level tags.+++<h3 id="autoescape">Automatic Escaping for Special Characters</h3>++In HTML, there are two characters that demand special treatment: `<`+and `&`. Left angle brackets are used to start tags; ampersands are+used to denote HTML entities. If you want to use them as literal+characters, you must escape them as entities, e.g. `<`, and+`&`.++Ampersands in particular are bedeviling for web writers. If you want to+write about 'AT&T', you need to write '`AT&T`'. You even need to+escape ampersands within URLs. Thus, if you want to link to:++ http://images.google.com/images?num=30&q=larry+bird++you need to encode the URL as:++ http://images.google.com/images?num=30&q=larry+bird++in your anchor tag `href` attribute. Needless to say, this is easy to+forget, and is probably the single most common source of HTML validation+errors in otherwise well-marked-up web sites.++Markdown allows you to use these characters naturally, taking care of+all the necessary escaping for you. If you use an ampersand as part of+an HTML entity, it remains unchanged; otherwise it will be translated+into `&`.++So, if you want to include a copyright symbol in your article, you can write:++ ©++and Markdown will leave it alone. But if you write:++ AT&T++Markdown will translate it to:++ AT&T++Similarly, because Markdown supports [inline HTML](#html), if you use+angle brackets as delimiters for HTML tags, Markdown will treat them as+such. But if you write:++ 4 < 5++Markdown will translate it to:++ 4 < 5++However, inside Markdown code spans and blocks, angle brackets and+ampersands are *always* encoded automatically. This makes it easy to use+Markdown to write about HTML code. (As opposed to raw HTML, which is a+terrible format for writing about HTML syntax, because every single `<`+and `&` in your example code needs to be escaped.)+++* * *+++<h2 id="block">Block Elements</h2>+++<h3 id="p">Paragraphs and Line Breaks</h3>++A paragraph is simply one or more consecutive lines of text, separated+by one or more blank lines. (A blank line is any line that looks like a+blank line -- a line containing nothing but spaces or tabs is considered+blank.) Normal paragraphs should not be intended with spaces or tabs.++The implication of the "one or more consecutive lines of text" rule is+that Markdown supports "hard-wrapped" text paragraphs. This differs+significantly from most other text-to-HTML formatters (including Movable+Type's "Convert Line Breaks" option) which translate every line break+character in a paragraph into a `<br />` tag.++When you *do* want to insert a `<br />` break tag using Markdown, you+end a line with two or more spaces, then type return.++Yes, this takes a tad more effort to create a `<br />`, but a simplistic+"every line break is a `<br />`" rule wouldn't work for Markdown.+Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l]+work best -- and look better -- when you format them with hard breaks.++ [bq]: #blockquote+ [l]: #list++++<h3 id="header">Headers</h3>++Markdown supports two styles of headers, [Setext] [1] and [atx] [2].++Setext-style headers are "underlined" using equal signs (for first-level+headers) and dashes (for second-level headers). For example:++ This is an H1+ =============++ This is an H2+ -------------++Any number of underlining `=`'s or `-`'s will work.++Atx-style headers use 1-6 hash characters at the start of the line,+corresponding to header levels 1-6. For example:++ # This is an H1++ ## This is an H2++ ###### This is an H6++Optionally, you may "close" atx-style headers. This is purely+cosmetic -- you can use this if you think it looks better. The+closing hashes don't even need to match the number of hashes+used to open the header. (The number of opening hashes+determines the header level.) :++ # This is an H1 #++ ## This is an H2 ##++ ### This is an H3 ######+++<h3 id="blockquote">Blockquotes</h3>++Markdown uses email-style `>` characters for blockquoting. If you're+familiar with quoting passages of text in an email message, then you+know how to create a blockquote in Markdown. It looks best if you hard+wrap the text and put a `>` before every line:++ > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,+ > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.+ > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.+ > + > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse+ > id sem consectetuer libero luctus adipiscing.++Markdown allows you to be lazy and only put the `>` before the first+line of a hard-wrapped paragraph:++ > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,+ consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.+ Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.++ > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse+ id sem consectetuer libero luctus adipiscing.++Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by+adding additional levels of `>`:++ > This is the first level of quoting.+ >+ > > This is nested blockquote.+ >+ > Back to the first level.++Blockquotes can contain other Markdown elements, including headers, lists,+and code blocks:++ > ## This is a header.+ > + > 1. This is the first list item.+ > 2. This is the second list item.+ > + > Here's some example code:+ > + > return shell_exec("echo $input | $markdown_script");++Any decent text editor should make email-style quoting easy. For+example, with BBEdit, you can make a selection and choose Increase+Quote Level from the Text menu.+++<h3 id="list">Lists</h3>++Markdown supports ordered (numbered) and unordered (bulleted) lists.++Unordered lists use asterisks, pluses, and hyphens -- interchangably+-- as list markers:++ * Red+ * Green+ * Blue++is equivalent to:++ + Red+ + Green+ + Blue++and:++ - Red+ - Green+ - Blue++Ordered lists use numbers followed by periods:++ 1. Bird+ 2. McHale+ 3. Parish++It's important to note that the actual numbers you use to mark the+list have no effect on the HTML output Markdown produces. The HTML+Markdown produces from the above list is:++ <ol>+ <li>Bird</li>+ <li>McHale</li>+ <li>Parish</li>+ </ol>++If you instead wrote the list in Markdown like this:++ 1. Bird+ 1. McHale+ 1. Parish++or even:++ 3. Bird+ 1. McHale+ 8. Parish++you'd get the exact same HTML output. The point is, if you want to,+you can use ordinal numbers in your ordered Markdown lists, so that+the numbers in your source match the numbers in your published HTML.+But if you want to be lazy, you don't have to.++If you do use lazy list numbering, however, you should still start the+list with the number 1. At some point in the future, Markdown may support+starting ordered lists at an arbitrary number.++List markers typically start at the left margin, but may be indented by+up to three spaces. List markers must be followed by one or more spaces+or a tab.++To make lists look nice, you can wrap items with hanging indents:++ * Lorem ipsum dolor sit amet, consectetuer adipiscing elit.+ Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,+ viverra nec, fringilla in, laoreet vitae, risus.+ * Donec sit amet nisl. Aliquam semper ipsum sit amet velit.+ Suspendisse id sem consectetuer libero luctus adipiscing.++But if you want to be lazy, you don't have to:++ * Lorem ipsum dolor sit amet, consectetuer adipiscing elit.+ Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,+ viverra nec, fringilla in, laoreet vitae, risus.+ * Donec sit amet nisl. Aliquam semper ipsum sit amet velit.+ Suspendisse id sem consectetuer libero luctus adipiscing.++If list items are separated by blank lines, Markdown will wrap the+items in `<p>` tags in the HTML output. For example, this input:++ * Bird+ * Magic++will turn into:++ <ul>+ <li>Bird</li>+ <li>Magic</li>+ </ul>++But this:++ * Bird++ * Magic++will turn into:++ <ul>+ <li><p>Bird</p></li>+ <li><p>Magic</p></li>+ </ul>++List items may consist of multiple paragraphs. Each subsequent+paragraph in a list item must be intended by either 4 spaces+or one tab:++ 1. This is a list item with two paragraphs. Lorem ipsum dolor+ sit amet, consectetuer adipiscing elit. Aliquam hendrerit+ mi posuere lectus.++ Vestibulum enim wisi, viverra nec, fringilla in, laoreet+ vitae, risus. Donec sit amet nisl. Aliquam semper ipsum+ sit amet velit.++ 2. Suspendisse id sem consectetuer libero luctus adipiscing.++It looks nice if you indent every line of the subsequent+paragraphs, but here again, Markdown will allow you to be+lazy:++ * This is a list item with two paragraphs.++ This is the second paragraph in the list item. You're+ only required to indent the first line. Lorem ipsum dolor+ sit amet, consectetuer adipiscing elit.++ * Another item in the same list.++To put a blockquote within a list item, the blockquote's `>`+delimiters need to be indented:++ * A list item with a blockquote:++ > This is a blockquote+ > inside a list item.++To put a code block within a list item, the code block needs+to be indented *twice* -- 8 spaces or two tabs:++ * A list item with a code block:++ <code goes here>+++It's worth noting that it's possible to trigger an ordered list by+accident, by writing something like this:++ 1986. What a great season.++In other words, a *number-period-space* sequence at the beginning of a+line. To avoid this, you can backslash-escape the period:++ 1986\. What a great season.++++<h3 id="precode">Code Blocks</h3>++Pre-formatted code blocks are used for writing about programming or+markup source code. Rather than forming normal paragraphs, the lines+of a code block are interpreted literally. Markdown wraps a code block+in both `<pre>` and `<code>` tags.++To produce a code block in Markdown, simply indent every line of the+block by at least 4 spaces or 1 tab. For example, given this input:++ This is a normal paragraph:++ This is a code block.++Markdown will generate:++ <p>This is a normal paragraph:</p>++ <pre><code>This is a code block.+ </code></pre>++One level of indentation -- 4 spaces or 1 tab -- is removed from each+line of the code block. For example, this:++ Here is an example of AppleScript:++ tell application "Foo"+ beep+ end tell++will turn into:++ <p>Here is an example of AppleScript:</p>++ <pre><code>tell application "Foo"+ beep+ end tell+ </code></pre>++A code block continues until it reaches a line that is not indented+(or the end of the article).++Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)+are automatically converted into HTML entities. This makes it very+easy to include example HTML source code using Markdown -- just paste+it and indent it, and Markdown will handle the hassle of encoding the+ampersands and angle brackets. For example, this:++ <div class="footer">+ © 2004 Foo Corporation+ </div>++will turn into:++ <pre><code><div class="footer">+ &copy; 2004 Foo Corporation+ </div>+ </code></pre>++Regular Markdown syntax is not processed within code blocks. E.g.,+asterisks are just literal asterisks within a code block. This means+it's also easy to use Markdown to write about Markdown's own syntax.++++<h3 id="hr">Horizontal Rules</h3>++You can produce a horizontal rule tag (`<hr />`) by placing three or+more hyphens, asterisks, or underscores on a line by themselves. If you+wish, you may use spaces between the hyphens or asterisks. Each of the+following lines will produce a horizontal rule:++ * * *++ ***++ *****+ + - - -++ ---------------------------------------++ _ _ _+++* * *++<h2 id="span">Span Elements</h2>++<h3 id="link">Links</h3>++Markdown supports two style of links: *inline* and *reference*.++In both styles, the link text is delimited by [square brackets].++To create an inline link, use a set of regular parentheses immediately+after the link text's closing square bracket. Inside the parentheses,+put the URL where you want the link to point, along with an *optional*+title for the link, surrounded in quotes. For example:++ This is [an example](http://example.com/ "Title") inline link.++ [This link](http://example.net/) has no title attribute.++Will produce:++ <p>This is <a href="http://example.com/" title="Title">+ an example</a> inline link.</p>++ <p><a href="http://example.net/">This link</a> has no+ title attribute.</p>++If you're referring to a local resource on the same server, you can+use relative paths:++ See my [About](/about/) page for details.++Reference-style links use a second set of square brackets, inside+which you place a label of your choosing to identify the link:++ This is [an example][id] reference-style link.++You can optionally use a space to separate the sets of brackets:++ This is [an example] [id] reference-style link.++Then, anywhere in the document, you define your link label like this,+on a line by itself:++ [id]: http://example.com/ "Optional Title Here"++That is:++* Square brackets containing the link identifier (optionally+ indented from the left margin using up to three spaces);+* followed by a colon;+* followed by one or more spaces (or tabs);+* followed by the URL for the link;+* optionally followed by a title attribute for the link, enclosed+ in double or single quotes.++The link URL may, optionally, be surrounded by angle brackets:++ [id]: <http://example.com/> "Optional Title Here"++You can put the title attribute on the next line and use extra spaces+or tabs for padding, which tends to look better with longer URLs:++ [id]: http://example.com/longish/path/to/resource/here+ "Optional Title Here"++Link definitions are only used for creating links during Markdown+processing, and are stripped from your document in the HTML output.++Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links:++ [link text][a]+ [link text][A]++are equivalent.++The *implicit link name* shortcut allows you to omit the name of the+link, in which case the link text itself is used as the name.+Just use an empty set of square brackets -- e.g., to link the word+"Google" to the google.com web site, you could simply write:++ [Google][]++And then define the link:++ [Google]: http://google.com/++Because link names may contain spaces, this shortcut even works for+multiple words in the link text:++ Visit [Daring Fireball][] for more information.++And then define the link:+ + [Daring Fireball]: http://daringfireball.net/++Link definitions can be placed anywhere in your Markdown document. I+tend to put them immediately after each paragraph in which they're+used, but if you want, you can put them all at the end of your+document, sort of like footnotes.++Here's an example of reference links in action:++ I get 10 times more traffic from [Google] [1] than from+ [Yahoo] [2] or [MSN] [3].++ [1]: http://google.com/ "Google"+ [2]: http://search.yahoo.com/ "Yahoo Search"+ [3]: http://search.msn.com/ "MSN Search"++Using the implicit link name shortcut, you could instead write:++ I get 10 times more traffic from [Google][] than from+ [Yahoo][] or [MSN][].++ [google]: http://google.com/ "Google"+ [yahoo]: http://search.yahoo.com/ "Yahoo Search"+ [msn]: http://search.msn.com/ "MSN Search"++Both of the above examples will produce the following HTML output:++ <p>I get 10 times more traffic from <a href="http://google.com/"+ title="Google">Google</a> than from+ <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>+ or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>++For comparison, here is the same paragraph written using+Markdown's inline link style:++ I get 10 times more traffic from [Google](http://google.com/ "Google")+ than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or+ [MSN](http://search.msn.com/ "MSN Search").++The point of reference-style links is not that they're easier to+write. The point is that with reference-style links, your document+source is vastly more readable. Compare the above examples: using+reference-style links, the paragraph itself is only 81 characters+long; with inline-style links, it's 176 characters; and as raw HTML,+it's 234 characters. In the raw HTML, there's more markup than there+is text.++With Markdown's reference-style links, a source document much more+closely resembles the final output, as rendered in a browser. By+allowing you to move the markup-related metadata out of the paragraph,+you can add links without interrupting the narrative flow of your+prose.+++<h3 id="em">Emphasis</h3>++Markdown treats asterisks (`*`) and underscores (`_`) as indicators of+emphasis. Text wrapped with one `*` or `_` will be wrapped with an+HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML+`<strong>` tag. E.g., this input:++ *single asterisks*++ _single underscores_++ **double asterisks**++ __double underscores__++will produce:++ <em>single asterisks</em>++ <em>single underscores</em>++ <strong>double asterisks</strong>++ <strong>double underscores</strong>++You can use whichever style you prefer; the lone restriction is that+the same character must be used to open and close an emphasis span.++Emphasis can be used in the middle of a word:++ un*fucking*believable++But if you surround an `*` or `_` with spaces, it'll be treated as a+literal asterisk or underscore.++To produce a literal asterisk or underscore at a position where it+would otherwise be used as an emphasis delimiter, you can backslash+escape it:++ \*this text is surrounded by literal asterisks\*++++<h3 id="code">Code</h3>++To indicate a span of code, wrap it with backtick quotes (`` ` ``).+Unlike a pre-formatted code block, a code span indicates code within a+normal paragraph. For example:++ Use the `printf()` function.++will produce:++ <p>Use the <code>printf()</code> function.</p>++To include a literal backtick character within a code span, you can use+multiple backticks as the opening and closing delimiters:++ ``There is a literal backtick (`) here.``++which will produce this:++ <p><code>There is a literal backtick (`) here.</code></p>++The backtick delimiters surrounding a code span may include spaces --+one after the opening, one before the closing. This allows you to place+literal backtick characters at the beginning or end of a code span:++ A single backtick in a code span: `` ` ``+ + A backtick-delimited string in a code span: `` `foo` ``++will produce:++ <p>A single backtick in a code span: <code>`</code></p>+ + <p>A backtick-delimited string in a code span: <code>`foo`</code></p>++With a code span, ampersands and angle brackets are encoded as HTML+entities automatically, which makes it easy to include example HTML+tags. Markdown will turn this:++ Please don't use any `<blink>` tags.++into:++ <p>Please don't use any <code><blink></code> tags.</p>++You can write this:++ `—` is the decimal-encoded equivalent of `—`.++to produce:++ <p><code>&#8212;</code> is the decimal-encoded+ equivalent of <code>&mdash;</code>.</p>++++<h3 id="img">Images</h3>++Admittedly, it's fairly difficult to devise a "natural" syntax for+placing images into a plain text document format.++Markdown uses an image syntax that is intended to resemble the syntax+for links, allowing for two styles: *inline* and *reference*.++Inline image syntax looks like this:++ ++ ++That is:++* An exclamation mark: `!`;+* followed by a set of square brackets, containing the `alt`+ attribute text for the image;+* followed by a set of parentheses, containing the URL or path to+ the image, and an optional `title` attribute enclosed in double+ or single quotes.++Reference-style image syntax looks like this:++ ![Alt text][id]++Where "id" is the name of a defined image reference. Image references+are defined using syntax identical to link references:++ [id]: url/to/image "Optional title attribute"++As of this writing, Markdown has no syntax for specifying the+dimensions of an image; if this is important to you, you can simply+use regular HTML `<img>` tags.+++* * *+++<h2 id="misc">Miscellaneous</h2>++<h3 id="autolink">Automatic Links</h3>++Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:++ <http://example.com/>+ +Markdown will turn this into:++ <a href="http://example.com/">http://example.com/</a>++Automatic links for email addresses work similarly, except that+Markdown will also perform a bit of randomized decimal and hex+entity-encoding to help obscure your address from address-harvesting+spambots. For example, Markdown will turn this:++ <address@example.com>++into something like this:++ <a href="mailto:addre+ ss@example.co+ m">address@exa+ mple.com</a>++which will render in a browser as a clickable link to "address@example.com".++(This sort of entity-encoding trick will indeed fool many, if not+most, address-harvesting bots, but it definitely won't fool all of+them. It's better than nothing, but an address published in this way+will probably eventually start receiving spam.)++++<h3 id="backslash">Backslash Escapes</h3>++Markdown allows you to use backslash escapes to generate literal+characters which would otherwise have special meaning in Markdown's+formatting syntax. For example, if you wanted to surround a word with+literal asterisks (instead of an HTML `<em>` tag), you can backslashes+before the asterisks, like this:++ \*literal asterisks\*++Markdown provides backslash escapes for the following characters:++ \ backslash+ ` backtick+ * asterisk+ _ underscore+ {} curly braces+ [] square brackets+ () parentheses+ # hash mark+ + plus sign+ - minus sign (hyphen)+ . dot+ ! exclamation mark+
+ tests/MarkdownTest_1.0.3/Tests/Nested blockquotes.html view
@@ -0,0 +1,9 @@+<blockquote>+ <p>foo</p>+ + <blockquote>+ <p>bar</p>+ </blockquote>+ + <p>foo</p>+</blockquote>
+ tests/MarkdownTest_1.0.3/Tests/Nested blockquotes.text view
@@ -0,0 +1,5 @@+> foo+>+> > bar+>+> foo
+ tests/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html view
@@ -0,0 +1,148 @@+<h2>Unordered</h2>++<p>Asterisks tight:</p>++<ul>+<li>asterisk 1</li>+<li>asterisk 2</li>+<li>asterisk 3</li>+</ul>++<p>Asterisks loose:</p>++<ul>+<li><p>asterisk 1</p></li>+<li><p>asterisk 2</p></li>+<li><p>asterisk 3</p></li>+</ul>++<hr />++<p>Pluses tight:</p>++<ul>+<li>Plus 1</li>+<li>Plus 2</li>+<li>Plus 3</li>+</ul>++<p>Pluses loose:</p>++<ul>+<li><p>Plus 1</p></li>+<li><p>Plus 2</p></li>+<li><p>Plus 3</p></li>+</ul>++<hr />++<p>Minuses tight:</p>++<ul>+<li>Minus 1</li>+<li>Minus 2</li>+<li>Minus 3</li>+</ul>++<p>Minuses loose:</p>++<ul>+<li><p>Minus 1</p></li>+<li><p>Minus 2</p></li>+<li><p>Minus 3</p></li>+</ul>++<h2>Ordered</h2>++<p>Tight:</p>++<ol>+<li>First</li>+<li>Second</li>+<li>Third</li>+</ol>++<p>and:</p>++<ol>+<li>One</li>+<li>Two</li>+<li>Three</li>+</ol>++<p>Loose using tabs:</p>++<ol>+<li><p>First</p></li>+<li><p>Second</p></li>+<li><p>Third</p></li>+</ol>++<p>and using spaces:</p>++<ol>+<li><p>One</p></li>+<li><p>Two</p></li>+<li><p>Three</p></li>+</ol>++<p>Multiple paragraphs:</p>++<ol>+<li><p>Item 1, graf one.</p>++<p>Item 2. graf two. The quick brown fox jumped over the lazy dog's+back.</p></li>+<li><p>Item 2.</p></li>+<li><p>Item 3.</p></li>+</ol>++<h2>Nested</h2>++<ul>+<li>Tab+<ul>+<li>Tab+<ul>+<li>Tab</li>+</ul></li>+</ul></li>+</ul>++<p>Here's another:</p>++<ol>+<li>First</li>+<li>Second:+<ul>+<li>Fee</li>+<li>Fie</li>+<li>Foe</li>+</ul></li>+<li>Third</li>+</ol>++<p>Same thing but with paragraphs:</p>++<ol>+<li><p>First</p></li>+<li><p>Second:</p>++<ul>+<li>Fee</li>+<li>Fie</li>+<li>Foe</li>+</ul></li>+<li><p>Third</p></li>+</ol>+++<p>This was an error in Markdown 1.0.1:</p>++<ul>+<li><p>this</p>++<ul><li>sub</li></ul>++<p>that</p></li>+</ul>
+ tests/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text view
@@ -0,0 +1,131 @@+## Unordered++Asterisks tight:++* asterisk 1+* asterisk 2+* asterisk 3+++Asterisks loose:++* asterisk 1++* asterisk 2++* asterisk 3++* * *++Pluses tight:+++ Plus 1++ Plus 2++ Plus 3+++Pluses loose:+++ Plus 1+++ Plus 2+++ Plus 3++* * *+++Minuses tight:++- Minus 1+- Minus 2+- Minus 3+++Minuses loose:++- Minus 1++- Minus 2++- Minus 3+++## Ordered++Tight:++1. First+2. Second+3. Third++and:++1. One+2. Two+3. Three+++Loose using tabs:++1. First++2. Second++3. Third++and using spaces:++1. One++2. Two++3. Three++Multiple paragraphs:++1. Item 1, graf one.++ Item 2. graf two. The quick brown fox jumped over the lazy dog's+ back.+ +2. Item 2.++3. Item 3.++++## Nested++* Tab+ * Tab+ * Tab++Here's another:++1. First+2. Second:+ * Fee+ * Fie+ * Foe+3. Third++Same thing but with paragraphs:++1. First++2. Second:+ * Fee+ * Fie+ * Foe++3. Third+++This was an error in Markdown 1.0.1:++* this++ * sub++ that
+ tests/MarkdownTest_1.0.3/Tests/Strong and em together.html view
@@ -0,0 +1,7 @@+<p><strong><em>This is strong and em.</em></strong></p>++<p>So is <strong><em>this</em></strong> word.</p>++<p><strong><em>This is strong and em.</em></strong></p>++<p>So is <strong><em>this</em></strong> word.</p>
+ tests/MarkdownTest_1.0.3/Tests/Strong and em together.text view
@@ -0,0 +1,7 @@+***This is strong and em.***++So is ***this*** word.++___This is strong and em.___++So is ___this___ word.
+ tests/MarkdownTest_1.0.3/Tests/Tabs.html view
@@ -0,0 +1,25 @@+<ul>+<li><p>this is a list item+indented with tabs</p></li>+<li><p>this is a list item+indented with spaces</p></li>+</ul>++<p>Code:</p>++<pre><code>this code block is indented by one tab+</code></pre>++<p>And:</p>++<pre><code> this code block is indented by two tabs+</code></pre>++<p>And:</p>++<pre><code>+ this is an example list item+ indented with tabs+++ this is an example list item+ indented with spaces+</code></pre>
+ tests/MarkdownTest_1.0.3/Tests/Tabs.text view
@@ -0,0 +1,21 @@++ this is a list item+ indented with tabs+++ this is a list item+ indented with spaces++Code:++ this code block is indented by one tab++And:++ this code block is indented by two tabs++And:++ + this is an example list item+ indented with tabs+ + + this is an example list item+ indented with spaces
+ tests/MarkdownTest_1.0.3/Tests/Tidyness.html view
@@ -0,0 +1,8 @@+<blockquote>+<p>A list within a blockquote:</p>+<ul>+<li>asterisk 1</li>+<li>asterisk 2</li>+<li>asterisk 3</li>+</ul>+</blockquote>
+ tests/MarkdownTest_1.0.3/Tests/Tidyness.text view
@@ -0,0 +1,5 @@+> A list within a blockquote:+> +> * asterisk 1+> * asterisk 2+> * asterisk 3
+ tests/bodybg.gif view
binary file changed (absent → 10119 bytes)
+ tests/generate.sh view
@@ -0,0 +1,12 @@+#!/bin/sh++../pandoc -r native -s -w native testsuite.native > writer.native+../pandoc -r native -s -w markdown testsuite.native > writer.markdown+../pandoc -r native -s -w rst testsuite.native > writer.rst +../pandoc -r native -s -w html testsuite.native > writer.html+../pandoc -r native -s -w latex testsuite.native > writer.latex+../pandoc -r native -s -w rtf testsuite.native > writer.rtf+../pandoc -r native -s -w man testsuite.native > writer.man+sed -e '/^, Header 1 \[Str "HTML",Space,Str "Blocks"\]/,/^, HorizontalRule/d' testsuite.native | ../pandoc -r native -w docbook -s > writer.docbook+sed -e '/^, Header 1 \[Str "LaTeX"\]/,/^, HorizontalRule/d' testsuite.native | ../pandoc -r native -w context -s > writer.context+
+ tests/html-reader.html view
@@ -0,0 +1,463 @@+<html>+<head>+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />+<meta name="generator" content="pandoc" />+<style type="text/css">+div.pandocNote { border-left: 1px solid grey; padding-left: 1em; }+span.pandocNoteRef { vertical-align: super; font-size: 80%; }+span.pandocNoteMarker { }+</style>+<title>Pandoc Test Suite</title>+</head>+<body>+<h1 class="title">Pandoc Test Suite</h1>+<p>This is a set of tests for pandoc. Most of them are adapted from John Gruber's markdown test suite.</p>+<hr />+<h1>Headers</h1>+<h2>Level 2 with an <a href="/url">embedded link</a></h2>+<h3>Level 3 with <em>emphasis</em></h3>+<h4>Level 4</h4>+<h5>Level 5</h5>+<h1>Level 1</h1>+<h2>Level 2 with <em>emphasis</em></h2>+<h3>Level 3</h3>+<p>with no blank line</p>+<h2>Level 2</h2>+<p>with no blank line</p>+<hr />+<h1>Paragraphs</h1>+<p>Here's a regular paragraph.</p>+<p>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.</p>+<p>Here's one with a bullet. * criminey.</p>+<p>There should be a hard line break<br />+ here.</p>+<hr />+<h1>Block Quotes</h1>+<p>E-mail style:</p>+<blockquote>+<p>This is a block quote. It is pretty short.</p>+</blockquote>+<blockquote>+<p>Code in a block quote:</p>+<pre><code>sub status {+ print "working";+}+</code></pre>+<p>A list:</p>+<ol>+<li>item one</li>+<li>item two</li>+</ol>+<p>Nested block quotes:</p>+<blockquote>+<p>nested</p>+</blockquote>+<blockquote>+<p>nested</p>+</blockquote>+</blockquote>+<p>This should not be a block quote: 2 > 1.</p>+<p>Box-style:</p>+<blockquote>+<p>Example:</p>+<pre><code>sub status {+ print "working";+}+</code></pre>+</blockquote>+<blockquote>+<ol>+<li>do laundry</li>+<li>take out the trash</li>+</ol>+</blockquote>+<p>Here's a nested one:</p>+<blockquote>+<p>Joe said:</p>+<blockquote>+<p>Don't quote me.</p>+</blockquote>+</blockquote>+<p>And a following paragraph.</p>+<hr />+<h1>Code Blocks</h1>+<p>Code:</p>+<pre><code>---- (should be four hyphens)++sub status {+ print "working";+}++this code block is indented by one tab+</code></pre>+<p>And:</p>+<pre><code> this code block is indented by two tabs++These should not be escaped: \$ \\ \> \[ \{+</code></pre>+<hr />+<h1>Lists</h1>+<h2>Unordered</h2>+<p>Asterisks tight:</p>+<ul>+<li>asterisk 1</li>+<li>asterisk 2</li>+<li>asterisk 3</li>+</ul>+<p>Asterisks loose:</p>+<ul>+<li><p>asterisk 1</p>+</li>+<li><p>asterisk 2</p>+</li>+<li><p>asterisk 3</p>+</li>+</ul>+<p>Pluses tight:</p>+<ul>+<li>Plus 1</li>+<li>Plus 2</li>+<li>Plus 3</li>+</ul>+<p>Pluses loose:</p>+<ul>+<li><p>Plus 1</p>+</li>+<li><p>Plus 2</p>+</li>+<li><p>Plus 3</p>+</li>+</ul>+<p>Minuses tight:</p>+<ul>+<li>Minus 1</li>+<li>Minus 2</li>+<li>Minus 3</li>+</ul>+<p>Minuses loose:</p>+<ul>+<li><p>Minus 1</p>+</li>+<li><p>Minus 2</p>+</li>+<li><p>Minus 3</p>+</li>+</ul>+<h2>Ordered</h2>+<p>Tight:</p>+<ol>+<li>First</li>+<li>Second</li>+<li>Third</li>+</ol>+<p>and:</p>+<ol>+<li>One</li>+<li>Two</li>+<li>Three</li>+</ol>+<p>Loose using tabs:</p>+<ol>+<li><p>First</p>+</li>+<li><p>Second</p>+</li>+<li><p>Third</p>+</li>+</ol>+<p>and using spaces:</p>+<ol>+<li><p>One</p>+</li>+<li><p>Two</p>+</li>+<li><p>Three</p>+</li>+</ol>+<p>Multiple paragraphs:</p>+<ol>+<li><p>Item 1, graf one.</p>+<p>Item 1. graf two. The quick brown fox jumped over the lazy dog's back.</p>+</li>+<li><p>Item 2.</p>+</li>+<li><p>Item 3.</p>+</li>+</ol>+<h2>Nested</h2>+<ul>+<li>Tab<ul>+<li>Tab<ul>+<li>Tab</li>+</ul>+</li>+</ul>+</li>+</ul>+<p>Here's another:</p>+<ol>+<li>First</li>+<li>Second:<ul>+<li>Fee</li>+<li>Fie</li>+<li>Foe</li>+</ul>+</li>+<li>Third</li>+</ol>+<p>Same thing but with paragraphs:</p>+<ol>+<li><p>First</p>+</li>+<li><p>Second:</p>+<ul>+<li>Fee</li>+<li>Fie</li>+<li>Foe</li>+</ul>+</li>+<li><p>Third</p>+</li>+</ol>+<h2>Tabs and spaces</h2>+<ul>+<li><p>this is a list item indented with tabs</p>+</li>+<li><p>this is a list item indented with spaces</p>+<ul>+<li><p>this is an example list item indented with tabs</p>+</li>+<li><p>this is an example list item indented with spaces</p>+</li>+</ul>+</li>+</ul>+<h2 id="fancy-list-markers"+ >Fancy list markers</h2+ ><ol start="2" class="decimal"+ ><li+ >begins with 2</li+ ><li+ ><p+ >and now 3</p+ ><p+ >with a continuation</p+ ><ol start="4" class="lower-roman"+ ><li+ >sublist with roman numerals, starting with 4</li+ ><li+ >more items<ol class="upper-alpha"+ ><li+ >a subsublist</li+ ><li+ >a subsublist</li+ ></ol+ ></li+ ></ol+ ></li+ ></ol+ ><p+ >Nesting:</p+ ><ol class="upper-alpha"+ ><li+ >Upper Alpha<ol class="upper-roman"+ ><li+ >Upper Roman.<ol start="6" class="decimal"+ ><li+ >Decimal start with 6<ol start="3" class="lower-alpha"+ ><li+ >Lower alpha with paren</li+ ></ol+ ></li+ ></ol+ ></li+ ></ol+ ></li+ ></ol+ ><p+ >Autonumbering:</p+ ><ol+ ><li+ >Autonumber.</li+ ><li+ >More.<ol+ ><li+ >Nested.</li+ ></ol+ ></li+ ></ol+ ><hr+ />+<h2>Definition</h2>+<dl>+ <dt>Violin</dt>+ <dd>Stringed musical instrument.</dd>+ <dd>Torture device.</dd>+ <dt>Cello</dt>+ <dt>Violoncello</dt>+ <dd>Low-voiced stringed instrument.</dd>+</dl>+<hr />+<h1>HTML Blocks</h1>+<p>Simple block on one line:</p>+foo<p>And nested without indentation:</p>+foobar<p>Interpreted markdown in a table:</p>+This is <em>emphasized</em>. And this is <strong>strong</strong><p>Here's a simple block:</p>+foo<p>This should be a code block, though:</p>+<pre><code><div>+ foo+</div>+</code></pre>+<p>As should this:</p>+<pre><code><div>foo</div>+</code></pre>+<p>Now, nested:</p>+foo<p>This should just be an HTML comment:</p>+<p>Multiline:</p>+<p>Code block:</p>+<pre><code><!-- Comment -->+</code></pre>+<p>Just plain comment, with trailing spaces on the line:</p>+<p>Code:</p>+<pre><code><hr />+</code></pre>+<p>Hr's:</p>+<hr />+<hr />+<hr />+<hr />+<hr />+<hr />+<hr />+<hr />+<hr />+<hr />+<h1>Inline Markup</h1>+<p>This is <em>emphasized</em>, and so <em>is this</em>.</p>+<p>This is <strong>strong</strong>, and so <strong>is this</strong>.</p>+<p>An <em><a href="/url">emphasized link</a></em>.</p>+<p><strong><em>This is strong and em.</em></strong></p>+<p>So is <strong><em>this</em></strong> word.</p>+<p><strong><em>This is strong and em.</em></strong></p>+<p>So is <strong><em>this</em></strong> word.</p>+<p>This is code: <code>></code>, <code>$</code>, <code>\</code>, <code>\$</code>, <code><html></code>.</p>+<hr />+<h1>Smart quotes, ellipses, dashes</h1>+<p>"Hello," said the spider. "'Shelob' is my name."</p>+<p>'A', 'B', and 'C' are letters.</p>+<p>'Oak,' 'elm,' and 'beech' are names of trees. So is 'pine.'</p>+<p>'He said, "I want to go."' Were you alive in the 70's?</p>+<p>Here is some quoted '<code>code</code>' and a "<a href="http://example.com/?foo=1&bar=2">quoted link</a>".</p>+<p>Some dashes: one---two --- three--four -- five.</p>+<p>Dashes between numbers: 5-7, 255-66, 1987-1999.</p>+<p>Ellipses...and. . .and . . . .</p>+<hr />+<h1>LaTeX</h1>+<ul>+<li>\cite[22-23]{smith.1899}</li>+<li>\doublespacing</li>+<li>$2+2=4$</li>+<li>$x \in y$</li>+<li>$\alpha \wedge \omega$</li>+<li>$223$</li>+<li>$p$-Tree</li>+<li>$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</li>+<li>Here's one that has a line break in it: $\alpha + \omega \times x^2$.</li>+</ul>+<p>These shouldn't be math:</p>+<ul>+<li>To get the famous equation, write <code>$e = mc^2$</code>.</li>+<li>$22,000 is a <em>lot</em> of money. So is $34,000. (It worked if "lot" is emphasized.)</li>+<li>Escaped <code>$</code>: $73 <em>this should be emphasized</em> 23$.</li>+</ul>+<p>Here's a LaTeX table:</p>+<p>\begin{tabular}{|l|l|}\hline Animal & Number \\ \hline Dog & 2 \\ Cat & 1 \\ \hline \end{tabular}</p>+<hr />+<h1>Special Characters</h1>+<p>Here is some unicode:</p>+<ul>+<li>I hat: Î</li>+<li>o umlaut: ö</li>+<li>section: §</li>+<li>set membership: ∈</li>+<li>copyright: ©</li>+</ul>+<p>AT&T has an ampersand in their name.</p>+<p>AT&T is another way to write it.</p>+<p>This & that.</p>+<p>4 < 5.</p>+<p>6 > 5.</p>+<p>Backslash: \</p>+<p>Backtick: `</p>+<p>Asterisk: *</p>+<p>Underscore: _</p>+<p>Left brace: {</p>+<p>Right brace: }</p>+<p>Left bracket: [</p>+<p>Right bracket: ]</p>+<p>Left paren: (</p>+<p>Right paren: )</p>+<p>Greater-than: ></p>+<p>Hash: #</p>+<p>Period: .</p>+<p>Bang: !</p>+<p>Plus: +</p>+<p>Minus: -</p>+<hr />+<h1>Links</h1>+<h2>Explicit</h2>+<p>Just a <a href="/url/">URL</a>.</p>+<p><a href="/url/" title="title">URL and title</a>.</p>+<p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p>+<p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p>+<p><a href="/url/" title="title with "quotes" in it">URL and title</a></p>+<p><a href="/url/" title="title with single quotes">URL and title</a></p>+Email link (nobody [at] nowhere.net)<p><a href="">Empty</a>.</p>+<h2>Reference</h2>+<p>Foo <a href="/url/">bar</a>.</p>+<p>Foo <a href="/url/">bar</a>.</p>+<p>Foo <a href="/url/">bar</a>.</p>+<p>With <a href="/url/">embedded [brackets]</a>.</p>+<p><a href="/url/">b</a> by itself should be a link.</p>+<p>Indented <a href="/url">once</a>.</p>+<p>Indented <a href="/url">twice</a>.</p>+<p>Indented <a href="/url">thrice</a>.</p>+<p>This should [not] be a link.</p>+<pre><code>[not]: /url+</code></pre>+<p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p>+<p>Foo <a href="/url/" title="Title with "quote" inside">biz</a>.</p>+<h2>With ampersands</h2>+<p>Here's a <a href="http://example.com/?foo=1&bar=2">link with an ampersand in the URL</a>.</p>+<p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&T">AT&T</a>.</p>+<p>Here's an <a href="/script?foo=1&bar=2">inline link</a>.</p>+<p>Here's an <a href="/script?foo=1&bar=2">inline link in pointy braces</a>.</p>+<h2>Autolinks</h2>+<p>With an ampersand: <a href="http://example.com/?foo=1&bar=2">http://example.com/?foo=1&bar=2</a></p>+<ul>+<li>In a list?</li>+<li><a href="http://example.com/">http://example.com/</a></li>+<li>It should.</li>+</ul>+An e-mail address: nobody [at] nowhere.net<blockquote>+<p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p>+</blockquote>+<p>Auto-links should not occur here: <code><http://example.com/></code></p>+<pre><code>or here: <http://example.com/>+</code></pre>+<hr />+<h1>Images</h1>+<p>From "Voyage dans la Lune" by Georges Melies (1902):</p>+<p><img src="lalune.jpg" title="Voyage dans la Lune" alt="lalune"></p>+<p>Here is a movie <img src="movie.jpg" alt="movie"> icon.</p>+<hr />+<h1>Footnotes</h1>+<p>Here is a footnote reference<a href="#note_1">(1)</a>, and another<a href="#note_longnote">(longnote)</a>. This should <em>not</em> be a footnote reference, because it contains a space^(my note).</p>+<p><a href="#ref_1">(1)</a> Here is the footnote. It can go anywhere in the document, not just at the end.</p>+<p><a href="#ref_longnote">(longnote)</a> Here's the other note. This one contains multiple blocks.</p>+<p>Caret characters are used to indicate that the blocks all belong to a single footnote (as with block quotes).</p>+<pre><code> { <code> }+</code></pre>+<p>If you want, you can use a caret at the beginning of every line, as with blockquotes, but all that you need is a caret at the beginning of the first line of the block and any preceding blank lines.</p>+</body>+</html>
+ tests/html-reader.native view
@@ -0,0 +1,346 @@+Pandoc (Meta [Str "Pandoc",Space,Str "Test",Space,Str "Suite"] [] "")+[ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc.",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber's",Space,Str "markdown",Space,Str "test",Space,Str "suite."]+, HorizontalRule+, Header 1 [Str "Headers"]+, Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embedded",Space,Str "link"] ("/url","")]+, Header 3 [Str "Level",Space,Str "3",Space,Str "with",Space,Emph [Str "emphasis"]]+, Header 4 [Str "Level",Space,Str "4"]+, Header 5 [Str "Level",Space,Str "5"]+, Header 1 [Str "Level",Space,Str "1"]+, Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Emph [Str "emphasis"]]+, Header 3 [Str "Level",Space,Str "3"]+, Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]+, Header 2 [Str "Level",Space,Str "2"]+, Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]+, HorizontalRule+, Header 1 [Str "Paragraphs"]+, Para [Str "Here's",Space,Str "a",Space,Str "regular",Space,Str "paragraph."]+, Para [Str "In",Space,Str "Markdown",Space,Str "1.0.0",Space,Str "and",Space,Str "earlier.",Space,Str "Version",Space,Str "8.",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item.",Space,Str "Because",Space,Str "a",Space,Str "hard-wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item."]+, Para [Str "Here's",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet.",Space,Str "*",Space,Str "criminey."]+, Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break",LineBreak,Space,Str "here."]+, HorizontalRule+, Header 1 [Str "Block",Space,Str "Quotes"]+, Para [Str "E-mail",Space,Str "style:"]+, BlockQuote+ [ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote.",Space,Str "It",Space,Str "is",Space,Str "pretty",Space,Str "short."] ]++, BlockQuote+ [ Para [Str "Code",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote:"]+ , CodeBlock "sub status {\n print \"working\";\n}"+ , Para [Str "A",Space,Str "list:"]+ , OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "item",Space,Str "one"] ]+ , [ Plain [Str "item",Space,Str "two"] ] ]+ , Para [Str "Nested",Space,Str "block",Space,Str "quotes:"]+ , BlockQuote+ [ Para [Str "nested"] ]+ + , BlockQuote+ [ Para [Str "nested"] ]+ ]+, Para [Str "This",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "block",Space,Str "quote:",Space,Str "2",Space,Str ">",Space,Str "1."]+, Para [Str "Box-style:"]+, BlockQuote+ [ Para [Str "Example:"]+ , CodeBlock "sub status {\n print \"working\";\n}" ]+, BlockQuote+ [ OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "do",Space,Str "laundry"] ]+ , [ Plain [Str "take",Space,Str "out",Space,Str "the",Space,Str "trash"] ] ] ]+, Para [Str "Here's",Space,Str "a",Space,Str "nested",Space,Str "one:"]+, BlockQuote+ [ Para [Str "Joe",Space,Str "said:"]+ , BlockQuote+ [ Para [Str "Don't",Space,Str "quote",Space,Str "me."] ]+ ]+, Para [Str "And",Space,Str "a",Space,Str "following",Space,Str "paragraph."]+, HorizontalRule+, Header 1 [Str "Code",Space,Str "Blocks"]+, Para [Str "Code:"]+, CodeBlock "---- (should be four hyphens)\n\nsub status {\n print \"working\";\n}\n\nthis code block is indented by one tab"+, Para [Str "And:"]+, CodeBlock " this code block is indented by two tabs\n\nThese should not be escaped: \\$ \\\\ \\> \\[ \\{"+, HorizontalRule+, Header 1 [Str "Lists"]+, Header 2 [Str "Unordered"]+, Para [Str "Asterisks",Space,Str "tight:"]+, BulletList+ [ [ Plain [Str "asterisk",Space,Str "1"] ]+ , [ Plain [Str "asterisk",Space,Str "2"] ]+ , [ Plain [Str "asterisk",Space,Str "3"] ] ]+, Para [Str "Asterisks",Space,Str "loose:"]+, BulletList+ [ [ Para [Str "asterisk",Space,Str "1"] ]+ , [ Para [Str "asterisk",Space,Str "2"] ]+ , [ Para [Str "asterisk",Space,Str "3"] ] ]+, Para [Str "Pluses",Space,Str "tight:"]+, BulletList+ [ [ Plain [Str "Plus",Space,Str "1"] ]+ , [ Plain [Str "Plus",Space,Str "2"] ]+ , [ Plain [Str "Plus",Space,Str "3"] ] ]+, Para [Str "Pluses",Space,Str "loose:"]+, BulletList+ [ [ Para [Str "Plus",Space,Str "1"] ]+ , [ Para [Str "Plus",Space,Str "2"] ]+ , [ Para [Str "Plus",Space,Str "3"] ] ]+, Para [Str "Minuses",Space,Str "tight:"]+, BulletList+ [ [ Plain [Str "Minus",Space,Str "1"] ]+ , [ Plain [Str "Minus",Space,Str "2"] ]+ , [ Plain [Str "Minus",Space,Str "3"] ] ]+, Para [Str "Minuses",Space,Str "loose:"]+, BulletList+ [ [ Para [Str "Minus",Space,Str "1"] ]+ , [ Para [Str "Minus",Space,Str "2"] ]+ , [ Para [Str "Minus",Space,Str "3"] ] ]+, Header 2 [Str "Ordered"]+, Para [Str "Tight:"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "First"] ]+ , [ Plain [Str "Second"] ]+ , [ Plain [Str "Third"] ] ]+, Para [Str "and:"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "One"] ]+ , [ Plain [Str "Two"] ]+ , [ Plain [Str "Three"] ] ]+, Para [Str "Loose",Space,Str "using",Space,Str "tabs:"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Para [Str "First"] ]+ , [ Para [Str "Second"] ]+ , [ Para [Str "Third"] ] ]+, Para [Str "and",Space,Str "using",Space,Str "spaces:"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Para [Str "One"] ]+ , [ Para [Str "Two"] ]+ , [ Para [Str "Three"] ] ]+, Para [Str "Multiple",Space,Str "paragraphs:"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Para [Str "Item",Space,Str "1,",Space,Str "graf",Space,Str "one."]+ , Para [Str "Item",Space,Str "1.",Space,Str "graf",Space,Str "two.",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog's",Space,Str "back."] ], [ Para [Str "Item",Space,Str "2."] ]+ , [ Para [Str "Item",Space,Str "3."] ] ]+, Header 2 [Str "Nested"]+, BulletList+ [ [ Plain [Str "Tab"]+ , BulletList+ [ [ Plain [Str "Tab"]+ , BulletList+ [ [ Plain [Str "Tab"] ]+ ] ] ] ] ]+, Para [Str "Here's",Space,Str "another:"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "First"] ]+ , [ Plain [Str "Second:"]+ , BulletList+ [ [ Plain [Str "Fee"] ]+ , [ Plain [Str "Fie"] ]+ , [ Plain [Str "Foe"] ] ] ], [ Plain [Str "Third"] ] ]+, Para [Str "Same",Space,Str "thing",Space,Str "but",Space,Str "with",Space,Str "paragraphs:"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Para [Str "First"] ]+ , [ Para [Str "Second:"]+ , BulletList+ [ [ Plain [Str "Fee"] ]+ , [ Plain [Str "Fie"] ]+ , [ Plain [Str "Foe"] ] ] ], [ Para [Str "Third"] ] ]+, Header 2 [Str "Tabs",Space,Str "and",Space,Str "spaces"]+, BulletList+ [ [ Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"] ]+ , [ Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"]+ , BulletList+ [ [ Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"] ]+ , [ Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"] ] ] ] ]+, Header 2 [Str "Fancy",Space,Str "list",Space,Str "markers"]+, OrderedList (2,Decimal,DefaultDelim)+ [ [ Plain [Str "begins",Space,Str "with",Space,Str "2"] ]+ , [ Para [Str "and",Space,Str "now",Space,Str "3"]+ , Para [Str "with",Space,Str "a",Space,Str "continuation"]+ , OrderedList (4,LowerRoman,DefaultDelim)+ [ [ Plain [Str "sublist",Space,Str "with",Space,Str "roman",Space,Str "numerals,",Space,Str "starting",Space,Str "with",Space,Str "4"] ]+ , [ Plain [Str "more",Space,Str "items"]+ , OrderedList (1,UpperAlpha,DefaultDelim)+ [ [ Plain [Str "a",Space,Str "subsublist"] ]+ , [ Plain [Str "a",Space,Str "subsublist"] ] ] ] ] ] ]+, Para [Str "Nesting:"]+, OrderedList (1,UpperAlpha,DefaultDelim)+ [ [ Plain [Str "Upper",Space,Str "Alpha"]+ , OrderedList (1,UpperRoman,DefaultDelim)+ [ [ Plain [Str "Upper",Space,Str "Roman."]+ , OrderedList (6,Decimal,DefaultDelim)+ [ [ Plain [Str "Decimal",Space,Str "start",Space,Str "with",Space,Str "6"]+ , OrderedList (3,LowerAlpha,DefaultDelim)+ [ [ Plain [Str "Lower",Space,Str "alpha",Space,Str "with",Space,Str "paren"] ]+ ] ] ] ] ] ] ]+, Para [Str "Autonumbering:"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "Autonumber."] ]+ , [ Plain [Str "More."]+ , OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "Nested."] ]+ ] ] ]+, HorizontalRule+, Header 2 [Str "Definition"]+, DefinitionList+ [ ([Str "Violin"],+ [ Plain [Str "Stringed",Space,Str "musical",Space,Str "instrument."]+ , Plain [Str "Torture",Space,Str "device."] ] ),+ ([Str "Cello",LineBreak,Str "Violoncello"],+ [ Plain [Str "Low-voiced",Space,Str "stringed",Space,Str "instrument."] ]+ ) ]+, HorizontalRule+, Header 1 [Str "HTML",Space,Str "Blocks"]+, Para [Str "Simple",Space,Str "block",Space,Str "on",Space,Str "one",Space,Str "line:"]+, Plain [Str "foo"]+, Para [Str "And",Space,Str "nested",Space,Str "without",Space,Str "indentation:"]+, Plain [Str "foobar"]+, Para [Str "Interpreted",Space,Str "markdown",Space,Str "in",Space,Str "a",Space,Str "table:"]+, Plain [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ".",Space,Str "And",Space,Str "this",Space,Str "is",Space,Strong [Str "strong"]]+, Para [Str "Here's",Space,Str "a",Space,Str "simple",Space,Str "block:"]+, Plain [Str "foo"]+, Para [Str "This",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "code",Space,Str "block,",Space,Str "though:"]+, CodeBlock "<div>\n foo\n</div>"+, Para [Str "As",Space,Str "should",Space,Str "this:"]+, CodeBlock "<div>foo</div>"+, Para [Str "Now,",Space,Str "nested:"]+, Plain [Str "foo"]+, Para [Str "This",Space,Str "should",Space,Str "just",Space,Str "be",Space,Str "an",Space,Str "HTML",Space,Str "comment:"]+, Para [Str "Multiline:"]+, Para [Str "Code",Space,Str "block:"]+, CodeBlock "<!-- Comment -->"+, Para [Str "Just",Space,Str "plain",Space,Str "comment,",Space,Str "with",Space,Str "trailing",Space,Str "spaces",Space,Str "on",Space,Str "the",Space,Str "line:"]+, Para [Str "Code:"]+, CodeBlock "<hr />"+, Para [Str "Hr's:"]+, HorizontalRule+, HorizontalRule+, HorizontalRule+, HorizontalRule+, HorizontalRule+, HorizontalRule+, HorizontalRule+, HorizontalRule+, HorizontalRule+, HorizontalRule+, Header 1 [Str "Inline",Space,Str "Markup"]+, Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ",",Space,Str "and",Space,Str "so",Space,Emph [Str "is",Space,Str "this"],Str "."]+, Para [Str "This",Space,Str "is",Space,Strong [Str "strong"],Str ",",Space,Str "and",Space,Str "so",Space,Strong [Str "is",Space,Str "this"],Str "."]+, Para [Str "An",Space,Emph [Link [Str "emphasized",Space,Str "link"] ("/url","")],Str "."]+, Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]+, Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word."]+, Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]+, Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word."]+, Para [Str "This",Space,Str "is",Space,Str "code:",Space,Code ">",Str ",",Space,Code "$",Str ",",Space,Code "\\",Str ",",Space,Code "\\$",Str ",",Space,Code "<html>",Str "."]+, HorizontalRule+, Header 1 [Str "Smart",Space,Str "quotes,",Space,Str "ellipses,",Space,Str "dashes"]+, Para [Str "\"Hello,\"",Space,Str "said",Space,Str "the",Space,Str "spider.",Space,Str "\"'Shelob'",Space,Str "is",Space,Str "my",Space,Str "name.\""]+, Para [Str "'A',",Space,Str "'B',",Space,Str "and",Space,Str "'C'",Space,Str "are",Space,Str "letters."]+, Para [Str "'Oak,'",Space,Str "'elm,'",Space,Str "and",Space,Str "'beech'",Space,Str "are",Space,Str "names",Space,Str "of",Space,Str "trees.",Space,Str "So",Space,Str "is",Space,Str "'pine.'"]+, Para [Str "'He",Space,Str "said,",Space,Str "\"I",Space,Str "want",Space,Str "to",Space,Str "go.\"'",Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70's?"]+, Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "quoted",Space,Str "'",Code "code",Str "'",Space,Str "and",Space,Str "a",Space,Str "\"",Link [Str "quoted",Space,Str "link"] ("http://example.com/?foo=1&bar=2",""),Str "\"."]+, Para [Str "Some",Space,Str "dashes:",Space,Str "one---two",Space,Str "---",Space,Str "three--four",Space,Str "--",Space,Str "five."]+, Para [Str "Dashes",Space,Str "between",Space,Str "numbers:",Space,Str "5-7,",Space,Str "255-66,",Space,Str "1987-1999."]+, Para [Str "Ellipses...and.",Space,Str ".",Space,Str ".and",Space,Str ".",Space,Str ".",Space,Str ".",Space,Str "."]+, HorizontalRule+, Header 1 [Str "LaTeX"]+, BulletList+ [ [ Plain [Str "\\cite[22-23]{smith.1899}"] ]+ , [ Plain [Str "\\doublespacing"] ]+ , [ Plain [Str "$2+2=4$"] ]+ , [ Plain [Str "$x",Space,Str "\\in",Space,Str "y$"] ]+ , [ Plain [Str "$\\alpha",Space,Str "\\wedge",Space,Str "\\omega$"] ]+ , [ Plain [Str "$223$"] ]+ , [ Plain [Str "$p$-Tree"] ]+ , [ Plain [Str "$\\frac{d}{dx}f(x)=\\lim_{h\\to",Space,Str "0}\\frac{f(x+h)-f(x)}{h}$"] ]+ , [ Plain [Str "Here's",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it:",Space,Str "$\\alpha",Space,Str "+",Space,Str "\\omega",Space,Str "\\times",Space,Str "x^2$."] ] ]+, Para [Str "These",Space,Str "shouldn't",Space,Str "be",Space,Str "math:"]+, BulletList+ [ [ Plain [Str "To",Space,Str "get",Space,Str "the",Space,Str "famous",Space,Str "equation,",Space,Str "write",Space,Code "$e = mc^2$",Str "."] ]+ , [ Plain [Str "$22,000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money.",Space,Str "So",Space,Str "is",Space,Str "$34,000.",Space,Str "(It",Space,Str "worked",Space,Str "if",Space,Str "\"lot\"",Space,Str "is",Space,Str "emphasized.)"] ]+ , [ Plain [Str "Escaped",Space,Code "$",Str ":",Space,Str "$73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23$."] ] ]+, Para [Str "Here's",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]+, Para [Str "\\begin{tabular}{|l|l|}\\hline",Space,Str "Animal",Space,Str "&",Space,Str "Number",Space,Str "\\\\",Space,Str "\\hline",Space,Str "Dog",Space,Str "&",Space,Str "2",Space,Str "\\\\",Space,Str "Cat",Space,Str "&",Space,Str "1",Space,Str "\\\\",Space,Str "\\hline",Space,Str "\\end{tabular}"]+, HorizontalRule+, Header 1 [Str "Special",Space,Str "Characters"]+, Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode:"]+, BulletList+ [ [ Plain [Str "I",Space,Str "hat:",Space,Str "\206"] ]+ , [ Plain [Str "o",Space,Str "umlaut:",Space,Str "\246"] ]+ , [ Plain [Str "section:",Space,Str "\167"] ]+ , [ Plain [Str "set",Space,Str "membership:",Space,Str "\8712"] ]+ , [ Plain [Str "copyright:",Space,Str "\169"] ] ]+, Para [Str "AT",Str "&",Str "T",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "their",Space,Str "name."]+, Para [Str "AT",Str "&",Str "T",Space,Str "is",Space,Str "another",Space,Str "way",Space,Str "to",Space,Str "write",Space,Str "it."]+, Para [Str "This",Space,Str "&",Space,Str "that."]+, Para [Str "4",Space,Str "<",Space,Str "5."]+, Para [Str "6",Space,Str ">",Space,Str "5."]+, Para [Str "Backslash:",Space,Str "\\"]+, Para [Str "Backtick:",Space,Str "`"]+, Para [Str "Asterisk:",Space,Str "*"]+, Para [Str "Underscore:",Space,Str "_"]+, Para [Str "Left",Space,Str "brace:",Space,Str "{"]+, Para [Str "Right",Space,Str "brace:",Space,Str "}"]+, Para [Str "Left",Space,Str "bracket:",Space,Str "["]+, Para [Str "Right",Space,Str "bracket:",Space,Str "]"]+, Para [Str "Left",Space,Str "paren:",Space,Str "("]+, Para [Str "Right",Space,Str "paren:",Space,Str ")"]+, Para [Str "Greater-than:",Space,Str ">"]+, Para [Str "Hash:",Space,Str "#"]+, Para [Str "Period:",Space,Str "."]+, Para [Str "Bang:",Space,Str "!"]+, Para [Str "Plus:",Space,Str "+"]+, Para [Str "Minus:",Space,Str "-"]+, HorizontalRule+, Header 1 [Str "Links"]+, Header 2 [Str "Explicit"]+, Para [Str "Just",Space,Str "a",Space,Link [Str "URL"] ("/url/",""),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title"),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title preceded by two spaces"),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title preceded by a tab"),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title with \"quotes\" in it")]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title with single quotes")]+, Plain [Str "Email",Space,Str "link",Space,Str "(nobody",Space,Str "[at]",Space,Str "nowhere.net)"]+, Para [Link [Str "Empty"] ("",""),Str "."]+, Header 2 [Str "Reference"]+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+, Para [Str "With",Space,Link [Str "embedded",Space,Str "[brackets]"] ("/url/",""),Str "."]+, Para [Link [Str "b"] ("/url/",""),Space,Str "by",Space,Str "itself",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "link."]+, Para [Str "Indented",Space,Link [Str "once"] ("/url",""),Str "."]+, Para [Str "Indented",Space,Link [Str "twice"] ("/url",""),Str "."]+, Para [Str "Indented",Space,Link [Str "thrice"] ("/url",""),Str "."]+, Para [Str "This",Space,Str "should",Space,Str "[not]",Space,Str "be",Space,Str "a",Space,Str "link."]+, CodeBlock "[not]: /url"+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/","Title with \"quotes\" inside"),Str "."]+, Para [Str "Foo",Space,Link [Str "biz"] ("/url/","Title with \"quote\" inside"),Str "."]+, Header 2 [Str "With",Space,Str "ampersands"]+, Para [Str "Here's",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]+, Para [Str "Here's",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text:",Space,Link [Str "AT",Str "&",Str "T"] ("http://att.com/","AT&T"),Str "."]+, Para [Str "Here's",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]+, Para [Str "Here's",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]+, Header 2 [Str "Autolinks"]+, Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link [Str "http://example.com/?foo=1",Str "&",Str "bar=2"] ("http://example.com/?foo=1&bar=2","")]+, BulletList+ [ [ Plain [Str "In",Space,Str "a",Space,Str "list?"] ]+ , [ Plain [Link [Str "http://example.com/"] ("http://example.com/","")] ]+ , [ Plain [Str "It",Space,Str "should."] ] ]+, Plain [Str "An",Space,Str "e-mail",Space,Str "address:",Space,Str "nobody",Space,Str "[at]",Space,Str "nowhere.net"]+, BlockQuote+ [ Para [Str "Blockquoted:",Space,Link [Str "http://example.com/"] ("http://example.com/","")] ]++, Para [Str "Auto-links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",Space,Code "<http://example.com/>"]+, CodeBlock "or here: <http://example.com/>"+, HorizontalRule+, Header 1 [Str "Images"]+, Para [Str "From",Space,Str "\"Voyage",Space,Str "dans",Space,Str "la",Space,Str "Lune\"",Space,Str "by",Space,Str "Georges",Space,Str "Melies",Space,Str "(1902):"]+, Para [Image [Str "lalune"] ("lalune.jpg","Voyage dans la Lune")]+, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image [Str "movie"] ("movie.jpg",""),Space,Str "icon."]+, HorizontalRule+, Header 1 [Str "Footnotes"]+, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference",Link [Str "(1)"] ("#note_1",""),Str ",",Space,Str "and",Space,Str "another",Link [Str "(longnote)"] ("#note_longnote",""),Str ".",Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space^(my",Space,Str "note)."]+, Para [Link [Str "(1)"] ("#ref_1",""),Space,Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote.",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "in",Space,Str "the",Space,Str "document,",Space,Str "not",Space,Str "just",Space,Str "at",Space,Str "the",Space,Str "end."]+, Para [Link [Str "(longnote)"] ("#ref_longnote",""),Space,Str "Here's",Space,Str "the",Space,Str "other",Space,Str "note.",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks."]+, Para [Str "Caret",Space,Str "characters",Space,Str "are",Space,Str "used",Space,Str "to",Space,Str "indicate",Space,Str "that",Space,Str "the",Space,Str "blocks",Space,Str "all",Space,Str "belong",Space,Str "to",Space,Str "a",Space,Str "single",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "block",Space,Str "quotes)."]+, CodeBlock " { <code> }"+, Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "use",Space,Str "a",Space,Str "caret",Space,Str "at",Space,Str "the",Space,Str "beginning",Space,Str "of",Space,Str "every",Space,Str "line,",Space,Str "as",Space,Str "with",Space,Str "blockquotes,",Space,Str "but",Space,Str "all",Space,Str "that",Space,Str "you",Space,Str "need",Space,Str "is",Space,Str "a",Space,Str "caret",Space,Str "at",Space,Str "the",Space,Str "beginning",Space,Str "of",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "the",Space,Str "block",Space,Str "and",Space,Str "any",Space,Str "preceding",Space,Str "blank",Space,Str "lines."] ]+
+ tests/insert view
@@ -0,0 +1,1 @@+STUFF INSERTED
+ tests/lalune.jpg view
binary file changed (absent → 16270 bytes)
+ tests/movie.jpg view
binary file changed (absent → 1046 bytes)
+ tests/rst-reader.native view
@@ -0,0 +1,211 @@+Pandoc (Meta [Str "Pandoc",Space,Str "Test",Space,Str "Suite",Str ":",Space,Str "Subtitle"] ["John MacFarlane","Anonymous"] "July 17, 2006")+[ BlockQuote+ [ Para [Strong [Str "Revision"],Str ":",Space,Str "3"] ]++, Header 1 [Str "Level",Space,Str "one",Space,Str "header"]+, Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc.",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber's",Space,Str "markdown",Space,Str "test",Space,Str "suite."]+, Header 2 [Str "Level",Space,Str "two",Space,Str "header"]+, Header 3 [Str "Level",Space,Str "three"]+, Header 4 [Str "Level",Space,Str "four",Space,Str "with",Space,Emph [Str "emphasis"]]+, Header 5 [Str "Level",Space,Str "five"]+, Header 1 [Str "Paragraphs"]+, Para [Str "Here's",Space,Str "a",Space,Str "regular",Space,Str "paragraph."]+, Para [Str "In",Space,Str "Markdown",Space,Str "1.0.0",Space,Str "and",Space,Str "earlier.",Space,Str "Version",Space,Str "8.",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item.",Space,Str "Because",Space,Str "a",Space,Str "hard",Str "-",Str "wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item."]+, Para [Str "Here's",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet.",Space,Str "*",Space,Str "criminey."]+, Para [Str "Horizontal",Space,Str "rule",Str ":"]+, HorizontalRule+, Para [Str "Another",Str ":"]+, HorizontalRule+, Header 1 [Str "Block",Space,Str "Quotes"]+, Para [Str "Here's",Space,Str "a",Space,Str "block",Space,Str "quote",Str ":"]+, BlockQuote+ [ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote.",Space,Str "It",Space,Str "is",Space,Str "pretty",Space,Str "short."] ]++, Para [Str "Here's",Space,Str "another,",Space,Str "differently",Space,Str "indented",Str ":"]+, BlockQuote+ [ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote.",Space,Str "It's",Space,Str "indented",Space,Str "with",Space,Str "a",Space,Str "tab."]+ , Para [Str "Code",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote",Str ":"]+ , CodeBlock "sub status {\n print \"working\";\n}"+ , Para [Str "List",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote",Str ":"]+ , OrderedList (1,Decimal,Period)+ [ [ Plain [Str "item",Space,Str "one"] ]+ , [ Plain [Str "item",Space,Str "two"] ] ]+ , Para [Str "Nested",Space,Str "block",Space,Str "quotes",Str ":"]+ , BlockQuote+ [ Para [Str "nested"]+ , BlockQuote+ [ Para [Str "nested"] ]+ ] ]+, Header 1 [Str "Code",Space,Str "Blocks"]+, Para [Str "Code",Str ":"]+, CodeBlock "---- (should be four hyphens)\n\nsub status {\n print \"working\";\n}"+, CodeBlock "this code block is indented by one tab"+, Para [Str "And",Str ":"]+, CodeBlock " this block is indented by two tabs\n\n These should not be escaped: \\$ \\\\ \\> \\[ \\{"+, Header 1 [Str "Lists"]+, Header 2 [Str "Unordered"]+, Para [Str "Asterisks",Space,Str "tight",Str ":"]+, BulletList+ [ [ Plain [Str "asterisk",Space,Str "1"] ]+ , [ Plain [Str "asterisk",Space,Str "2"] ]+ , [ Plain [Str "asterisk",Space,Str "3"] ] ]+, Para [Str "Asterisks",Space,Str "loose",Str ":"]+, BulletList+ [ [ Para [Str "asterisk",Space,Str "1"] ]+ , [ Para [Str "asterisk",Space,Str "2"] ]+ , [ Para [Str "asterisk",Space,Str "3"] ] ]+, Para [Str "Pluses",Space,Str "tight",Str ":"]+, BulletList+ [ [ Plain [Str "Plus",Space,Str "1"] ]+ , [ Plain [Str "Plus",Space,Str "2"] ]+ , [ Plain [Str "Plus",Space,Str "3"] ] ]+, Para [Str "Pluses",Space,Str "loose",Str ":"]+, BulletList+ [ [ Para [Str "Plus",Space,Str "1"] ]+ , [ Para [Str "Plus",Space,Str "2"] ]+ , [ Para [Str "Plus",Space,Str "3"] ] ]+, Para [Str "Minuses",Space,Str "tight",Str ":"]+, BulletList+ [ [ Plain [Str "Minus",Space,Str "1"] ]+ , [ Plain [Str "Minus",Space,Str "2"] ]+ , [ Plain [Str "Minus",Space,Str "3"] ] ]+, Para [Str "Minuses",Space,Str "loose",Str ":"]+, BulletList+ [ [ Para [Str "Minus",Space,Str "1"] ]+ , [ Para [Str "Minus",Space,Str "2"] ]+ , [ Para [Str "Minus",Space,Str "3"] ] ]+, Header 2 [Str "Ordered"]+, Para [Str "Tight",Str ":"]+, OrderedList (1,Decimal,Period)+ [ [ Plain [Str "First"] ]+ , [ Plain [Str "Second"] ]+ , [ Plain [Str "Third"] ] ]+, Para [Str "and",Str ":"]+, OrderedList (1,Decimal,Period)+ [ [ Plain [Str "One"] ]+ , [ Plain [Str "Two"] ]+ , [ Plain [Str "Three"] ] ]+, Para [Str "Loose",Space,Str "using",Space,Str "tabs",Str ":"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "First"] ]+ , [ Para [Str "Second"] ]+ , [ Para [Str "Third"] ] ]+, Para [Str "and",Space,Str "using",Space,Str "spaces",Str ":"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "One"] ]+ , [ Para [Str "Two"] ]+ , [ Para [Str "Three"] ] ]+, Para [Str "Multiple",Space,Str "paragraphs",Str ":"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "Item",Space,Str "1,",Space,Str "graf",Space,Str "one."]+ , Para [Str "Item",Space,Str "1.",Space,Str "graf",Space,Str "two.",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog's",Space,Str "back."] ], [ Para [Str "Item",Space,Str "2."] ]+ , [ Para [Str "Item",Space,Str "3."] ] ]+, Para [Str "Nested",Str ":"]+, BulletList+ [ [ Para [Str "Tab"]+ , BulletList+ [ [ Para [Str "Tab"]+ , BulletList+ [ [ Plain [Str "Tab"] ]+ ] ] ] ] ]+, Para [Str "Here's",Space,Str "another",Str ":"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "First"] ]+ , [ Para [Str "Second",Str ":"]+ , BlockQuote+ [ BulletList+ [ [ Plain [Str "Fee"] ]+ , [ Plain [Str "Fie"] ]+ , [ Plain [Str "Foe"] ] ] ] ], [ Para [Str "Third"] ] ]+, Header 2 [Str "Fancy",Space,Str "list",Space,Str "markers"]+, OrderedList (2,Decimal,TwoParens)+ [ [ Plain [Str "begins",Space,Str "with",Space,Str "2"] ]+ , [ Para [Str "and",Space,Str "now",Space,Str "3"]+ , Para [Str "with",Space,Str "a",Space,Str "continuation"]+ , OrderedList (4,LowerRoman,Period)+ [ [ Plain [Str "sublist",Space,Str "with",Space,Str "roman",Space,Str "numerals,",Space,Str "starting",Space,Str "with",Space,Str "4"] ]+ , [ Para [Str "more",Space,Str "items"]+ , OrderedList (1,UpperAlpha,TwoParens)+ [ [ Plain [Str "a",Space,Str "subsublist"] ]+ , [ Plain [Str "a",Space,Str "subsublist"] ] ] ] ] ] ]+, Para [Str "Nesting",Str ":"]+, OrderedList (1,UpperAlpha,Period)+ [ [ Para [Str "Upper",Space,Str "Alpha"]+ , OrderedList (1,UpperRoman,Period)+ [ [ Para [Str "Upper",Space,Str "Roman."]+ , OrderedList (6,Decimal,TwoParens)+ [ [ Para [Str "Decimal",Space,Str "start",Space,Str "with",Space,Str "6"]+ , OrderedList (3,LowerAlpha,OneParen)+ [ [ Plain [Str "Lower",Space,Str "alpha",Space,Str "with",Space,Str "paren"] ]+ ] ] ] ] ] ] ]+, Para [Str "Autonumbering",Str ":"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "Autonumber."] ]+ , [ Para [Str "More."]+ , OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "Nested."] ]+ ] ] ]+, Header 2 [Str "Definition"]+, DefinitionList+ [ ([Str "term",Space,Str "1"],+ [ Para [Str "Definition",Space,Str "1."] ]+ ),+ ([Str "term",Space,Str "2"],+ [ Para [Str "Definition",Space,Str "2,",Space,Str "paragraph",Space,Str "1."]+ , Para [Str "Definition",Space,Str "2,",Space,Str "paragraph",Space,Str "2."] ] ),+ ([Str "term",Space,Str "with",Space,Emph [Str "emphasis"]],+ [ Para [Str "Definition",Space,Str "3."] ]+ ) ]+, Header 1 [Str "HTML",Space,Str "Blocks"]+, Para [Str "Simple",Space,Str "block",Space,Str "on",Space,Str "one",Space,Str "line",Str ":"]+, RawHtml "<div>foo</div>\n"+, Para [Str "Now,",Space,Str "nested",Str ":"]+, RawHtml "<div>\n <div>\n <div>\n foo\n </div>\n </div>\n</div>\n"+, Header 1 [Str "LaTeX",Space,Str "Block"]+, Para [TeX "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}\n"]+, Header 1 [Str "Inline",Space,Str "Markup"]+, Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ".",Space,Str "This",Space,Str "is",Space,Strong [Str "strong"],Str "."]+, Para [Str "This",Space,Str "is",Space,Str "code",Str ":",Space,Code ">",Str ",",Space,Code "$",Str ",",Space,Code "\\",Str ",",Space,Code "\\$",Str ",",Space,Code "<html>",Str "."]+, Para [Str "This",Space,Str "is",Subscript [Str "subscripted"],Space,Str "and",Space,Str "this",Space,Str "is",Space,Superscript [Str "superscripted"],Str "."]+, Header 1 [Str "Special",Space,Str "Characters"]+, Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode",Str ":"]+, BulletList+ [ [ Plain [Str "I",Space,Str "hat",Str ":",Space,Str "\206"] ]+ , [ Plain [Str "o",Space,Str "umlaut",Str ":",Space,Str "\246"] ]+ , [ Plain [Str "section",Str ":",Space,Str "\167"] ]+ , [ Plain [Str "set",Space,Str "membership",Str ":",Space,Str "\8712"] ]+ , [ Plain [Str "copyright",Str ":",Space,Str "\169"] ] ]+, Para [Str "AT&T",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "their",Space,Str "name."]+, Para [Str "This",Space,Str "&",Space,Str "that."]+, Para [Str "4",Space,Str "<",Space,Str "5."]+, Para [Str "6",Space,Str ">",Space,Str "5."]+, Para [Str "Backslash",Str ":",Space,Str "\\"]+, Para [Str "Backtick",Str ":",Space,Str "`"]+, Para [Str "Asterisk",Str ":",Space,Str "*"]+, Para [Str "Underscore",Str ":",Space,Str "_"]+, Para [Str "Left",Space,Str "brace",Str ":",Space,Str "{"]+, Para [Str "Right",Space,Str "brace",Str ":",Space,Str "}"]+, Para [Str "Left",Space,Str "bracket",Str ":",Space,Str "["]+, Para [Str "Right",Space,Str "bracket",Str ":",Space,Str "]"]+, Para [Str "Left",Space,Str "paren",Str ":",Space,Str "("]+, Para [Str "Right",Space,Str "paren",Str ":",Space,Str ")"]+, Para [Str "Greater",Str "-",Str "than",Str ":",Space,Str ">"]+, Para [Str "Hash",Str ":",Space,Str "#"]+, Para [Str "Period",Str ":",Space,Str "."]+, Para [Str "Bang",Str ":",Space,Str "!"]+, Para [Str "Plus",Str ":",Space,Str "+"]+, Para [Str "Minus",Str ":",Space,Str "-"]+, Header 1 [Str "Links"]+, Para [Str "Explicit",Str ":",Space,Str "a",Space,Link [Str "URL"] ("/url/",""),Str "."]+, Para [Str "Two",Space,Str "anonymous",Space,Str "links",Str ":",Space,Link [Str "the",Space,Str "first"] ("/url1/",""),Space,Str "and",Space,Link [Str "the",Space,Str "second"] ("/url2/","")]+, Para [Str "Reference",Space,Str "links",Str ":",Space,Link [Str "link1"] ("/url1/",""),Space,Str "and",Space,Link [Str "link2"] ("/url2/",""),Space,Str "and",Space,Link [Str "link1"] ("/url1/",""),Space,Str "again."]+, Para [Str "Here's",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]+, Para [Str "Here's",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text",Str ":",Space,Link [Str "AT&T"] ("/url/",""),Str "."]+, Para [Str "Autolinks",Str ":",Space,Link [Str "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2",""),Space,Str "and",Space,Link [Str "nobody@nowhere.net"] ("mailto:nobody@nowhere.net",""),Str "."]+, Para [Str "But",Space,Str "not",Space,Str "here",Str ":"]+, CodeBlock "http://example.com/"+, Header 1 [Str "Images"]+, Para [Str "From",Space,Str "\"Voyage",Space,Str "dans",Space,Str "la",Space,Str "Lune\"",Space,Str "by",Space,Str "Georges",Space,Str "Melies",Space,Str "(1902)",Str ":"]+, Plain [Image [Str "image"] ("lalune.jpg","")]+, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image [Str "movie"] ("movie.jpg",""),Space,Str "icon."] ]+
+ tests/rst-reader.rst view
@@ -0,0 +1,387 @@+Pandoc Test Suite+#################+Subtitle+^^^^^^^^++:Author: John MacFarlane+:Author: Anonymous+:Date: July 17, 2006+:Revision: 3++Level one header+================++This is a set of tests for pandoc. Most of them are adapted from+John Gruber's markdown test suite.++Level two header+----------------++Level three++++++++++++++Level four with *emphasis*+~~~~~~~~~~~~~~~~~~~~~~~~~~++Level five+''''''''''++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.++Here's one with a bullet.+* criminey.++Horizontal rule:++-----++Another:++****++Block Quotes+============++Here's a block quote:++ This is a block quote.+ It is pretty short.++Here's another, differently indented:++ This is a block quote.+ It's indented with a tab.++ Code in a block quote:: ++ sub status {+ print "working";+ }++ List in a block quote:++ 1. item one+ 2. item two++ Nested block quotes:++ nested++ nested++Code Blocks+===========++Code:++::++ ---- (should be four hyphens)++ sub status {+ print "working";+ }++::++ this code block is indented by one tab++And::++ this block is indented by two tabs++ These should not be escaped: \$ \\ \> \[ \{++Lists+=====++Unordered+---------++Asterisks tight:++* asterisk 1+* asterisk 2+* asterisk 3++Asterisks loose:++* asterisk 1++* asterisk 2++* asterisk 3++Pluses tight:+++ Plus 1++ Plus 2++ Plus 3++Pluses loose:+++ Plus 1+++ Plus 2+++ Plus 3++Minuses tight:++- Minus 1+- Minus 2+- Minus 3++Minuses loose:++- Minus 1++- Minus 2++- Minus 3++Ordered+-------++Tight:++1. First+2. Second+3. Third++and:++1. One+2. Two+3. Three++Loose using tabs:++1. First++2. Second++3. Third++and using spaces:++1. One++2. Two++3. Three++Multiple paragraphs:++1. Item 1, graf one.++ Item 1. graf two. The quick brown fox jumped over the lazy dog's+ back.+ +2. Item 2.++3. Item 3.++Nested:++* Tab++ * Tab++ * Tab++Here's another:++1. First++2. Second:++ * Fee+ * Fie+ * Foe++3. Third ++Fancy list markers+------------------++(2) begins with 2+(3) and now 3++ with a continuation++ iv. sublist with roman numerals, starting with 4+ v. more items+ + (A) a subsublist+ (B) a subsublist++Nesting:++A. Upper Alpha+ + I. Upper Roman.+ + (6) Decimal start with 6+ + c) Lower alpha with paren++Autonumbering:++#. Autonumber.+#. More.+ + #. Nested.++Definition+----------++term 1+ Definition 1.++term 2+ Definition 2, paragraph 1.++ Definition 2, paragraph 2.++term with *emphasis* + Definition 3.++HTML Blocks+===========++Simple block on one line:++.. raw:: html++ <div>foo</div>++Now, nested:++.. raw:: html++ <div>+ <div>+ <div>+ foo+ </div>+ </div>+ </div>++LaTeX Block+===========++.. raw:: latex++ \begin{tabular}{|l|l|}\hline+ Animal & Number \\ \hline+ Dog & 2 \\+ Cat & 1 \\ \hline+ \end{tabular}++Inline Markup+=============++This is *emphasized*. This is **strong**.++This is code: ``>``, ``$``, ``\``, ``\$``, ``<html>``.++This is\ :sub:`subscripted` and this is :sup:`superscripted`\ .++Special Characters+==================++Here is some unicode:++- I hat: Î+- o umlaut: ö+- section: § +- set membership: ∈+- copyright: ©++AT&T has an ampersand in their name.++This & that.++4 < 5.++6 > 5.++Backslash: \\++Backtick: \`++Asterisk: \*++Underscore: \_++Left brace: \{++Right brace: \}++Left bracket: \[++Right bracket: \]++Left paren: \(++Right paren: \)++Greater-than: \>++Hash: \#++Period: \.++Bang: \!++Plus: \+++Minus: \-++Links+=====++Explicit: a `URL </url/>`_.++Two anonymous links: `the first`__ and `the second`__++__ /url1/+__ /url2/++Reference links: `link1`_ and `link2`_ and link1_ again.++.. _link1: /url1/+.. _`link2`: /url2/++Here's a `link with an ampersand in the URL`_.++Here's a link with an amersand in the link text: `AT&T </url/>`_.++.. _link with an ampersand in the URL: http://example.com/?foo=1&bar=2++Autolinks: http://example.com/?foo=1&bar=2 and nobody@nowhere.net.++But not here::++ http://example.com/++Images+======++From "Voyage dans la Lune" by Georges Melies (1902):++.. image:: lalune.jpg++Here is a movie |movie| icon.++.. |movie| image:: movie.jpg
+ tests/runtests.pl view
@@ -0,0 +1,114 @@+#!/bin/perl -w++$verbose = 1;+my $diffexists = `which diff`;+if ($diffexists eq "") { die "diff not found in path.\n"; }++my $script = "COLUMNS=78 ./pandoc";++use Getopt::Long;+GetOptions("script=s" => \$script);++unless (-f $script) { die "$script does not exist.\n"; }+unless (-x $script) { die "$script is not executable.\n"; }++print "Writer tests:\n";++my @writeformats = ("html", "latex", "rst", "rtf", "markdown", "man", "native"); # docbook, context, and s5 handled separately+my @readformats = ("latex", "native"); # handle html,markdown & rst separately+my $source = "testsuite.native";++sub test_results +{+ my $testname = $_[0];+ my $output = $_[1];+ my $norm = $_[2];+ my $diffoutput = `diff --strip-trailing-cr $output $norm`;+ if ($diffoutput eq "") + {+ print "passed\n";+ }+ else+ {+ print "FAILED\n";+ if ($verbose) { print $diffoutput; } + } +}++foreach my $format (@writeformats)+{+ $options = "";++ my $extension = $format;+ print "Testing $format writer...";++ `$script -r native -w $extension $options -s $source > tmp.$extension`;++ test_results("$format writer", "tmp.$extension", "writer.$format");++ print " $format tables...";++ `$script -r native -w $extension tables.native > tmp.$extension`;++ test_results("$format writer", "tmp.$extension", "tables.$format");+}++print "Testing docbook writer...";+# remove HTML block tests, as this produces invalid docbook...+`sed -e '/^, Header 1 \\[Str "HTML",Space,Str "Blocks"\\]/,/^, HorizontalRule/d' testsuite.native | $script -r native -w docbook -s > tmp.docbook`;+test_results("docbook writer", "tmp.docbook", "writer.docbook");+`$script -r native -w docbook tables.native > tmp.docbook`;+print " docbook tables...";+test_results("docbook tables", "tmp.docbook", "tables.docbook");++print "Testing context writer...";+# remove LaTeX tests, as this produces invalid docbook...+`sed -e '/^, Header 1 \\[Str "LaTeX"\\]/,/^, HorizontalRule/d' testsuite.native | $script -r native -w context -s > tmp.context`;+test_results("context writer", "tmp.context", "writer.context");+`$script -r native -w context tables.native > tmp.context`;+print " context tables...";+test_results("context tables", "tmp.context", "tables.context");++print "Testing s5 writer (basic)...";+`$script -r native -w s5 -s s5.native > tmp.html`;+test_results("s5 writer (basic)", "tmp.html", "s5.basic.html");++print "Testing s5 writer (fancy)...";+`$script -r native -w s5 -s -m -i s5.native > tmp.html`;+test_results("s5 writer (fancy)", "tmp.html", "s5.fancy.html");++print "Testing html fragment...";+`$script -r native -w html s5.native > tmp.html`;+test_results("html fragment", "tmp.html", "s5.fragment.html");++print "Testing -H -B -A -c options...";+`$script -r native -s -w html -H insert -B insert -A insert -c main.css s5.native > tmp.html`;+test_results("-B, -A, -H, -c options", "tmp.html", "s5.inserts.html");++print "\nReader tests:\n";++print "Testing markdown reader...";+`$script -r markdown -w native -s -S testsuite.txt > tmp.native`;+test_results("markdown reader", "tmp.native", "testsuite.native");++print "Testing rst reader...";+`$script -r rst -w native -s rst-reader.rst > tmp.native`;+test_results("rst reader", "tmp.native", "rst-reader.native");++print "Testing html reader...";+`$script -r html -w native -s html-reader.html > tmp.native`;+test_results("html reader", "tmp.native", "html-reader.native");++print "\nReader tests (roundtrip: X -> native -> X -> native):\n";++foreach my $format (@readformats)+{+ print "Testing $format reader...";+ `$script -r $format -w native -s -R writer.$format > tmp1.native`;+ `$script -r native -w $format -s -R tmp1.native | $script -r $format -w native -s -R - > tmp2.native`;+ test_results("$format reader", "tmp1.native", "tmp2.native");+}++`rm tmp?.*`;+`rm tmp.*`;+
+ tests/s5.basic.html view
@@ -0,0 +1,790 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html+><head+ ><title+ >My S5 Document</title+ ><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"+ /><meta name="generator" content="pandoc"+ /><meta name="author" content="Sam Smith"+ /><meta name="author" content="Jen Jones"+ /><meta name="date" content="July 15, 2006"+ /><!-- configuration parameters -->+<meta name="defaultView" content="slideshow" />+<meta name="controlVis" content="hidden" />+<style type="text/css" media="projection" id="slideProj">+/* Do not edit or override these styles! The system will likely break if you do. */++div#header, div#footer, div#controls, .slide {position: absolute;}+html>body div#header, html>body div#footer, + html>body div#controls, html>body .slide {position: fixed;}+.handout {display: none;}+.layout {display: block;}+.slide, .hideme, .incremental {visibility: hidden;}+#slide0 {visibility: visible;}++/* The following styles size, place, and layer the slide components.+ Edit these if you want to change the overall slide layout.+ The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */++/* target = 1024x768 */++div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}+div#header {top: 0; height: 3em; z-index: 1;}+div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}+.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2; list-style: none;}+div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;+ margin: 0;}+#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z-index: 10;}+html>body #currentSlide {position: fixed;}++/*+div#header {background: #FCC;}+div#footer {background: #CCF;}+div#controls {background: #BBD;}+div#currentSlide {background: #FFC;}+*/++/* Following are the presentation styles -- edit away! */++body {background: #FFF url(bodybg.gif) -16px 0 no-repeat; color: #000; font-size: 2em;}+:link, :visited {text-decoration: none; color: #00C;}+#controls :active {color: #88A !important;}+#controls :focus {outline: 1px dotted #227;}+h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}+ul, pre {margin: 0; line-height: 1em;}+html, body {margin: 0; padding: 0;}++blockquote, q {font-style: italic;}+blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: center; font-size: 1em;}+blockquote p {margin: 0;}+blockquote i {font-style: normal;}+blockquote b {display: block; margin-top: 0.5em; font-weight: normal; font-size: smaller; font-style: normal;}+blockquote b i {font-style: italic;}++kbd {font-weight: bold; font-size: 1em;}+sup {font-size: smaller; line-height: 1px;}++.slide code {padding: 2px 0.25em; font-weight: bold; color: #533;}+.slide code.bad, code del {color: red;}+.slide code.old {color: silver;}+.slide pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 90%;}+.slide pre code {display: block;}+.slide ul {margin-left: 5%; margin-right: 7%; list-style: disc;}+.slide li {margin-top: 0.75em; margin-right: 0;}+.slide ul ul {line-height: 1;}+.slide ul ul li {margin: .2em; font-size: 85%; list-style: square;}+.slide img.leader {display: block; margin: 0 auto;}++div#header, div#footer {background: #005; color: #AAB;+ font-family: Verdana, Helvetica, sans-serif;}+div#header {background: #005 url(bodybg.gif) -16px 0 no-repeat;+ line-height: 1px;}+div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;}+#footer h1, #footer h2 {display: block; padding: 0 1em;}+#footer h2 {font-style: italic;}++div.long {font-size: 0.75em;}+.slide h1 {position: absolute; top: 0.7em; left: 87px; z-index: 1;+ margin: 0; padding: 0.3em 0 0 50px; white-space: nowrap;+ font: bold 150%/1em Helvetica, sans-serif; text-transform: capitalize;+ color: #DDE; background: #005;}+.slide h3 {font-size: 130%;}+h1 abbr {font-variant: small-caps;}++div#controls {position: absolute; left: 50%; bottom: 0;+ width: 50%;+ text-align: right; font: bold 0.9em Verdana, Helvetica, sans-serif;}+html>body div#controls {position: fixed; padding: 0 0 1em 0;+ top: auto;}+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;+ margin: 0; padding: 0;}+#controls #navLinks a {padding: 0; margin: 0 0.5em; + background: #005; border: none; color: #779; + cursor: pointer;}+#controls #navList {height: 1em;}+#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; background: #DDD; color: #227;}++#currentSlide {text-align: center; font-size: 0.5em; color: #449;}++#slide0 {padding-top: 3.5em; font-size: 90%;}+#slide0 h1 {position: static; margin: 1em 0 0; padding: 0;+ font: bold 2em Helvetica, sans-serif; white-space: normal;+ color: #000; background: transparent;}+#slide0 h2 {font: bold italic 1em Helvetica, sans-serif; margin: 0.25em;}+#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}+#slide0 h4 {margin-top: 0; font-size: 1em;}++ul.urls {list-style: none; display: inline; margin: 0;}+.urls li {display: inline; margin: 0;}+.note {display: none;}+.external {border-bottom: 1px dotted gray;}+html>body .external {border-bottom: none;}+.external:after {content: " \274F"; font-size: smaller; color: #77B;}++.incremental, .incremental *, .incremental *:after {color: #DDE; visibility: visible;}+img.incremental {visibility: hidden;}+.slide .current {color: #B02;}+++/* diagnostics++li:after {content: " [" attr(class) "]"; color: #F88;}+ */+</style>+<style type="text/css" media="projection" id="operaFix">+/* DO NOT CHANGE THESE unless you really want to break Opera Show */+.slide {+ visibility: visible !important;+ position: static !important;+ page-break-before: always;+}+#slide0 {page-break-before: avoid;}++</style>+<style type="text/css" media="screen" id="outlineStyle">+/* don't change this unless you want the layout stuff to show up in the outline view! */++.layout div, #footer *, #controlForm * {display: none;}+#footer, #controls, #controlForm, #navLinks, #toggle {+ display: block; visibility: visible; margin: 0; padding: 0;}+#toggle {float: right; padding: 0.5em;}+html>body #toggle {position: fixed; top: 0; right: 0;}++/* making the outline look pretty-ish */++#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;}+#slide0 h1 {padding-top: 1.5em;}+.slide h1 {margin: 1.5em 0 0; padding-top: 0.25em;+ border-top: 1px solid #888; border-bottom: 1px solid #AAA;}+#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;}++</style>+<style type="text/css" media="print" id="slidePrint">+/* The following rule is necessary to have all slides appear in print! DO NOT REMOVE IT! */+.slide, ul {page-break-inside: avoid; visibility: visible !important;}+h1 {page-break-after: avoid;}++body {font-size: 12pt; background: white;}+* {color: black;}++#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;}+#slide0 h3 {margin: 0; padding: 0;}+#slide0 h4 {margin: 0 0 0.5em; padding: 0;}+#slide0 {margin-bottom: 3em;}++h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;}+.extra {background: transparent !important;}+div.extra, pre.extra, .example {font-size: 10pt; color: #333;}+ul.extra a {font-weight: bold;}+p.example {display: none;}++#header {display: none;}+#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style: italic;}+#footer h2, #controls {display: none;}++/* The following rule keeps the layout stuff out of print. Remove at your own risk! */+.layout, .layout * {display: none !important;}++</style>+<script type="text/javascript">+// S5 v1.1 slides.js -- released into the Public Domain+//+// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information +// about all the wonderful and talented contributors to this code!++var undef;+var slideCSS = '';+var snum = 0;+var smax = 1;+var incpos = 0;+var number = undef;+var s5mode = true;+var defaultView = 'slideshow';+var controlVis = 'visible';++var isIE = navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.indexOf('Opera') < 1 ? 1 : 0;+var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;+var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0;++function hasClass(object, className) {+ if (!object.className) return false;+ return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1);+}++function hasValue(object, value) {+ if (!object) return false;+ return (object.search('(^|\\s)' + value + '(\\s|$)') != -1);+}++function removeClass(object,className) {+ if (!object) return;+ object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2);+}++function addClass(object,className) {+ if (!object || hasClass(object, className)) return;+ if (object.className) {+ object.className += ' '+className;+ } else {+ object.className = className;+ }+}++function GetElementsWithClassName(elementName,className) {+ var allElements = document.getElementsByTagName(elementName);+ var elemColl = new Array();+ for (var i = 0; i< allElements.length; i++) {+ if (hasClass(allElements[i], className)) {+ elemColl[elemColl.length] = allElements[i];+ }+ }+ return elemColl;+}++function isParentOrSelf(element, id) {+ if (element == null || element.nodeName=='BODY') return false;+ else if (element.id == id) return true;+ else return isParentOrSelf(element.parentNode, id);+}++function nodeValue(node) {+ var result = "";+ if (node.nodeType == 1) {+ var children = node.childNodes;+ for (var i = 0; i < children.length; ++i) {+ result += nodeValue(children[i]);+ } + }+ else if (node.nodeType == 3) {+ result = node.nodeValue;+ }+ return(result);+}++function slideLabel() {+ var slideColl = GetElementsWithClassName('*','slide');+ var list = document.getElementById('jumplist');+ smax = slideColl.length;+ for (var n = 0; n < smax; n++) {+ var obj = slideColl[n];++ var did = 'slide' + n.toString();+ obj.setAttribute('id',did);+ if (isOp) continue;++ var otext = '';+ var menu = obj.firstChild;+ if (!menu) continue; // to cope with empty slides+ while (menu && menu.nodeType == 3) {+ menu = menu.nextSibling;+ }+ if (!menu) continue; // to cope with slides with only text nodes++ var menunodes = menu.childNodes;+ for (var o = 0; o < menunodes.length; o++) {+ otext += nodeValue(menunodes[o]);+ }+ list.options[list.length] = new Option(n + ' : ' + otext, n);+ }+}++function currentSlide() {+ var cs;+ if (document.getElementById) {+ cs = document.getElementById('currentSlide');+ } else {+ cs = document.currentSlide;+ }+ cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' + + '<span id="csSep">\/<\/span> ' + + '<span id="csTotal">' + (smax-1) + '<\/span>';+ if (snum == 0) {+ cs.style.visibility = 'hidden';+ } else {+ cs.style.visibility = 'visible';+ }+}++function go(step) {+ if (document.getElementById('slideProj').disabled || step == 0) return;+ var jl = document.getElementById('jumplist');+ var cid = 'slide' + snum;+ var ce = document.getElementById(cid);+ if (incrementals[snum].length > 0) {+ for (var i = 0; i < incrementals[snum].length; i++) {+ removeClass(incrementals[snum][i], 'current');+ removeClass(incrementals[snum][i], 'incremental');+ }+ }+ if (step != 'j') {+ snum += step;+ lmax = smax - 1;+ if (snum > lmax) snum = lmax;+ if (snum < 0) snum = 0;+ } else+ snum = parseInt(jl.value);+ var nid = 'slide' + snum;+ var ne = document.getElementById(nid);+ if (!ne) {+ ne = document.getElementById('slide0');+ snum = 0;+ }+ if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;}+ if (incrementals[snum].length > 0 && incpos == 0) {+ for (var i = 0; i < incrementals[snum].length; i++) {+ if (hasClass(incrementals[snum][i], 'current'))+ incpos = i + 1;+ else+ addClass(incrementals[snum][i], 'incremental');+ }+ }+ if (incrementals[snum].length > 0 && incpos > 0)+ addClass(incrementals[snum][incpos - 1], 'current');+ ce.style.visibility = 'hidden';+ ne.style.visibility = 'visible';+ jl.selectedIndex = snum;+ currentSlide();+ number = 0;+}++function goTo(target) {+ if (target >= smax || target == snum) return;+ go(target - snum);+}++function subgo(step) {+ if (step > 0) {+ removeClass(incrementals[snum][incpos - 1],'current');+ removeClass(incrementals[snum][incpos], 'incremental');+ addClass(incrementals[snum][incpos],'current');+ incpos++;+ } else {+ incpos--;+ removeClass(incrementals[snum][incpos],'current');+ addClass(incrementals[snum][incpos], 'incremental');+ addClass(incrementals[snum][incpos - 1],'current');+ }+}++function toggle() {+ var slideColl = GetElementsWithClassName('*','slide');+ var slides = document.getElementById('slideProj');+ var outline = document.getElementById('outlineStyle');+ if (!slides.disabled) {+ slides.disabled = true;+ outline.disabled = false;+ s5mode = false;+ fontSize('1em');+ for (var n = 0; n < smax; n++) {+ var slide = slideColl[n];+ slide.style.visibility = 'visible';+ }+ } else {+ slides.disabled = false;+ outline.disabled = true;+ s5mode = true;+ fontScale();+ for (var n = 0; n < smax; n++) {+ var slide = slideColl[n];+ slide.style.visibility = 'hidden';+ }+ slideColl[snum].style.visibility = 'visible';+ }+}++function showHide(action) {+ var obj = GetElementsWithClassName('*','hideme')[0];+ switch (action) {+ case 's': obj.style.visibility = 'visible'; break;+ case 'h': obj.style.visibility = 'hidden'; break;+ case 'k':+ if (obj.style.visibility != 'visible') {+ obj.style.visibility = 'visible';+ } else {+ obj.style.visibility = 'hidden';+ }+ break;+ }+}++// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)+function keys(key) {+ if (!key) {+ key = event;+ key.which = key.keyCode;+ }+ if (key.which == 84) {+ toggle();+ return;+ }+ if (s5mode) {+ switch (key.which) {+ case 10: // return+ case 13: // enter+ if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;+ if (key.target && isParentOrSelf(key.target, 'controls')) return;+ if(number != undef) {+ goTo(number);+ break;+ }+ case 32: // spacebar+ case 34: // page down+ case 39: // rightkey+ case 40: // downkey+ if(number != undef) {+ go(number);+ } else if (!incrementals[snum] || incpos >= incrementals[snum].length) {+ go(1);+ } else {+ subgo(1);+ }+ break;+ case 33: // page up+ case 37: // leftkey+ case 38: // upkey+ if(number != undef) {+ go(-1 * number);+ } else if (!incrementals[snum] || incpos <= 0) {+ go(-1);+ } else {+ subgo(-1);+ }+ break;+ case 36: // home+ goTo(0);+ break;+ case 35: // end+ goTo(smax-1);+ break;+ case 67: // c+ showHide('k');+ break;+ }+ if (key.which < 48 || key.which > 57) {+ number = undef;+ } else {+ if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;+ if (key.target && isParentOrSelf(key.target, 'controls')) return;+ number = (((number != undef) ? number : 0) * 10) + (key.which - 48);+ }+ }+ return false;+}++function clicker(e) {+ number = undef;+ var target;+ if (window.event) {+ target = window.event.srcElement;+ e = window.event;+ } else target = e.target;+ if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true;+ if (!e.which || e.which == 1) {+ if (!incrementals[snum] || incpos >= incrementals[snum].length) {+ go(1);+ } else {+ subgo(1);+ }+ }+}++function findSlide(hash) {+ var target = null;+ var slides = GetElementsWithClassName('*','slide');+ for (var i = 0; i < slides.length; i++) {+ var targetSlide = slides[i];+ if ( (targetSlide.name && targetSlide.name == hash)+ || (targetSlide.id && targetSlide.id == hash) ) {+ target = targetSlide;+ break;+ }+ }+ while(target != null && target.nodeName != 'BODY') {+ if (hasClass(target, 'slide')) {+ return parseInt(target.id.slice(5));+ }+ target = target.parentNode;+ }+ return null;+}++function slideJump() {+ if (window.location.hash == null) return;+ var sregex = /^#slide(\d+)$/;+ var matches = sregex.exec(window.location.hash);+ var dest = null;+ if (matches != null) {+ dest = parseInt(matches[1]);+ } else {+ dest = findSlide(window.location.hash.slice(1));+ }+ if (dest != null)+ go(dest - snum);+}++function fixLinks() {+ var thisUri = window.location.href;+ thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length);+ var aelements = document.getElementsByTagName('A');+ for (var i = 0; i < aelements.length; i++) {+ var a = aelements[i].href;+ var slideID = a.match('\#slide[0-9]{1,2}');+ if ((slideID) && (slideID[0].slice(0,1) == '#')) {+ var dest = findSlide(slideID[0].slice(1));+ if (dest != null) {+ if (aelements[i].addEventListener) {+ aelements[i].addEventListener("click", new Function("e",+ "if (document.getElementById('slideProj').disabled) return;" ++ "go("+dest+" - snum); " ++ "if (e.preventDefault) e.preventDefault();"), true);+ } else if (aelements[i].attachEvent) {+ aelements[i].attachEvent("onclick", new Function("",+ "if (document.getElementById('slideProj').disabled) return;" ++ "go("+dest+" - snum); " ++ "event.returnValue = false;"));+ }+ }+ }+ }+}++function externalLinks() {+ if (!document.getElementsByTagName) return;+ var anchors = document.getElementsByTagName('a');+ for (var i=0; i<anchors.length; i++) {+ var anchor = anchors[i];+ if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) {+ anchor.target = '_blank';+ addClass(anchor,'external');+ }+ }+}++function createControls() {+ var controlsDiv = document.getElementById("controls");+ if (!controlsDiv) return;+ var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"';+ var hideDiv, hideList = '';+ if (controlVis == 'hidden') {+ hideDiv = hider;+ } else {+ hideList = hider;+ }+ controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' ++ '<div id="navLinks">' ++ '<a accesskey="t" id="toggle" href="javascript:toggle();">Ø<\/a>' ++ '<a accesskey="z" id="prev" href="javascript:go(-1);">«<\/a>' ++ '<a accesskey="x" id="next" href="javascript:go(1);">»<\/a>' ++ '<div id="navList"' + hideList + '><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' ++ '<\/div><\/form>';+ if (controlVis == 'hidden') {+ var hidden = document.getElementById('navLinks');+ } else {+ var hidden = document.getElementById('jumplist');+ }+ addClass(hidden,'hideme');+}++function fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers+ if (!s5mode) return false;+ var vScale = 22; // both yield 32 (after rounding) at 1024x768+ var hScale = 32; // perhaps should auto-calculate based on theme's declared value?+ if (window.innerHeight) {+ var vSize = window.innerHeight;+ var hSize = window.innerWidth;+ } else if (document.documentElement.clientHeight) {+ var vSize = document.documentElement.clientHeight;+ var hSize = document.documentElement.clientWidth;+ } else if (document.body.clientHeight) {+ var vSize = document.body.clientHeight;+ var hSize = document.body.clientWidth;+ } else {+ var vSize = 700; // assuming 1024x768, minus chrome and such+ var hSize = 1024; // these do not account for kiosk mode or Opera Show+ }+ var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale));+ fontSize(newSize + 'px');+ if (isGe) { // hack to counter incremental reflow bugs+ var obj = document.getElementsByTagName('body')[0];+ obj.style.display = 'none';+ obj.style.display = 'block';+ }+}++function fontSize(value) {+ if (!(s5ss = document.getElementById('s5ss'))) {+ if (!isIE) {+ document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style'));+ s5ss.setAttribute('media','screen, projection');+ s5ss.setAttribute('id','s5ss');+ } else {+ document.createStyleSheet();+ document.s5ss = document.styleSheets[document.styleSheets.length - 1];+ }+ }+ if (!isIE) {+ while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild);+ s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}'));+ } else {+ document.s5ss.addRule('body','font-size: ' + value + ' !important;');+ }+}++function notOperaFix() {+ slideCSS = document.getElementById('slideProj').href;+ var slides = document.getElementById('slideProj');+ var outline = document.getElementById('outlineStyle');+ slides.setAttribute('media','screen');+ outline.disabled = true;+ if (isGe) {+ slides.setAttribute('href','null'); // Gecko fix+ slides.setAttribute('href',slideCSS); // Gecko fix+ }+ if (isIE && document.styleSheets && document.styleSheets[0]) {+ document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)');+ document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)');+ document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)');+ }+}++function getIncrementals(obj) {+ var incrementals = new Array();+ if (!obj) + return incrementals;+ var children = obj.childNodes;+ for (var i = 0; i < children.length; i++) {+ var child = children[i];+ if (hasClass(child, 'incremental')) {+ if (child.nodeName == 'OL' || child.nodeName == 'UL') {+ removeClass(child, 'incremental');+ for (var j = 0; j < child.childNodes.length; j++) {+ if (child.childNodes[j].nodeType == 1) {+ addClass(child.childNodes[j], 'incremental');+ }+ }+ } else {+ incrementals[incrementals.length] = child;+ removeClass(child,'incremental');+ }+ }+ if (hasClass(child, 'show-first')) {+ if (child.nodeName == 'OL' || child.nodeName == 'UL') {+ removeClass(child, 'show-first');+ if (child.childNodes[isGe].nodeType == 1) {+ removeClass(child.childNodes[isGe], 'incremental');+ }+ } else {+ incrementals[incrementals.length] = child;+ }+ }+ incrementals = incrementals.concat(getIncrementals(child));+ }+ return incrementals;+}++function createIncrementals() {+ var incrementals = new Array();+ for (var i = 0; i < smax; i++) {+ incrementals[i] = getIncrementals(document.getElementById('slide'+i));+ }+ return incrementals;+}++function defaultCheck() {+ var allMetas = document.getElementsByTagName('meta');+ for (var i = 0; i< allMetas.length; i++) {+ if (allMetas[i].name == 'defaultView') {+ defaultView = allMetas[i].content;+ }+ if (allMetas[i].name == 'controlVis') {+ controlVis = allMetas[i].content;+ }+ }+}++// Key trap fix, new function body for trap()+function trap(e) {+ if (!e) {+ e = event;+ e.which = e.keyCode;+ }+ try {+ modifierKey = e.ctrlKey || e.altKey || e.metaKey;+ }+ catch(e) {+ modifierKey = false;+ }+ return modifierKey || e.which == 0;+}++function startup() {+ defaultCheck();+ if (!isOp) + createControls();+ slideLabel();+ fixLinks();+ externalLinks();+ fontScale();+ if (!isOp) {+ notOperaFix();+ incrementals = createIncrementals();+ slideJump();+ if (defaultView == 'outline') {+ toggle();+ }+ document.onkeyup = keys;+ document.onkeypress = trap;+ document.onclick = clicker;+ }+}++window.onload = startup;+window.onresize = function(){setTimeout('fontScale()', 50);}</script>+</head+ ><body+ ><div class="layout">+<div id="controls"></div>+<div id="currentSlide"></div>+<div id="header"></div>+<div id="footer">+<h1 id="july-15-2006"+ >July 15, 2006</h1+ ><h2 id="my-s5-document"+ >My S5 Document</h2+ ></div>+</div>+<div class="presentation">++<div class="slide">+<h1 id="my-s5-document-1"+ >My S5 Document</h1+ ><h3 id="sam-smith-jen-jones"+ >Sam Smith, Jen Jones</h3+ ><h4 id="july-15-2006-1"+ >July 15, 2006</h4+ ></div>+<div class="slide">+<h1 id="first-slide"+ >First slide</h1+ ><ul+ ><li+ >first bullet</li+ ><li+ >second bullet</li+ ></ul+ ></div>+<div class="slide">+<h1 id="math"+ >Math</h1+ ><ul+ ><li+ >$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</li+ ></ul+ ></div>+</div>+</body+ ></html+>+
+ tests/s5.fancy.html view
@@ -0,0 +1,1702 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html+><head+ ><title+ >My S5 Document</title+ ><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"+ /><meta name="generator" content="pandoc"+ /><meta name="author" content="Sam Smith"+ /><meta name="author" content="Jen Jones"+ /><meta name="date" content="July 15, 2006"+ /><script type="text/javascript">+/* ASCIIMathML.js - copyright Peter Jipsen, released under the GPL+See http://www1.chapman.edu/~jipsen/mathml/asciimath.html/ */++var checkForMathML = true; // check if browser can display MathML+var notifyIfNoMathML = true; // display note if no MathML capability+var alertIfNoMathML = false; // show alert box if no MathML capability+var mathcolor = ""; // change it to "" (to inherit) or any other color+var mathfontfamily = "serif"; // change to "" to inherit (works in IE) + // or another family (e.g. "arial")+var displaystyle = true; // puts limits above and below large operators+var showasciiformulaonhover = true; // helps students learn ASCIIMath+var decimalsign = "."; // change to "," if you like, beware of `(1,2)`!+var AMdelimiter1 = "`", AMescape1 = "\\\\`"; // can use other characters+var AMdelimiter2 = "$", AMescape2 = "\\\\\\$", AMdelimiter2regexp = "\\$";+var doubleblankmathdelimiter = false; // if true, x+1 is equal to `x+1`+ // for IE this works only in <!-- -->+//var separatetokens;// has been removed (email me if this is a problem)+var isIE = document.createElementNS==null;++if (document.getElementById==null) + alert("This webpage requires a recent browser such as\+\nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer")++// all further global variables start with "AM"++function AMcreateElementXHTML(t) {+ if (isIE) return document.createElement(t);+ else return document.createElementNS("http://www.w3.org/1999/xhtml",t);+}++function AMnoMathMLNote() {+ var nd = AMcreateElementXHTML("h3");+ nd.setAttribute("align","center")+ nd.appendChild(AMcreateElementXHTML("p"));+ nd.appendChild(document.createTextNode("To view the "));+ var an = AMcreateElementXHTML("a");+ an.appendChild(document.createTextNode("ASCIIMathML"));+ an.setAttribute("href","http://www.chapman.edu/~jipsen/asciimath.html");+ nd.appendChild(an);+ nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+")); + an = AMcreateElementXHTML("a");+ an.appendChild(document.createTextNode("MathPlayer"));+ an.setAttribute("href","http://www.dessci.com/en/products/mathplayer/download.htm");+ nd.appendChild(an);+ nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox"));+ nd.appendChild(AMcreateElementXHTML("p"));+ return nd;+}++function AMisMathMLavailable() {+ var regex = /KHTML/; /* ASCIIMathML.js - copyright Peter Jipsen, released under the GPL+See http://www1.chapman.edu/~jipsen/mathml/asciimath.html/ */+ if (navigator.appName.slice(0,8)=="Netscape")+ if (navigator.appVersion.slice(0,1)>="5" && !regex.test(navigator.userAgent)) return null;+ else return AMnoMathMLNote();+ else if (navigator.appName.slice(0,9)=="Microsoft")+ try {+ var ActiveX = new ActiveXObject("MathPlayer.Factory.1");+ return null;+ } catch (e) {+ return AMnoMathMLNote();+ }+ else return AMnoMathMLNote();+}++// character lists for Mozilla/Netscape fonts+var AMcal = [0xEF35,0x212C,0xEF36,0xEF37,0x2130,0x2131,0xEF38,0x210B,0x2110,0xEF39,0xEF3A,0x2112,0x2133,0xEF3B,0xEF3C,0xEF3D,0xEF3E,0x211B,0xEF3F,0xEF40,0xEF41,0xEF42,0xEF43,0xEF44,0xEF45,0xEF46];+var AMfrk = [0xEF5D,0xEF5E,0x212D,0xEF5F,0xEF60,0xEF61,0xEF62,0x210C,0x2111,0xEF63,0xEF64,0xEF65,0xEF66,0xEF67,0xEF68,0xEF69,0xEF6A,0x211C,0xEF6B,0xEF6C,0xEF6D,0xEF6E,0xEF6F,0xEF70,0xEF71,0x2128];+var AMbbb = [0xEF8C,0xEF8D,0x2102,0xEF8E,0xEF8F,0xEF90,0xEF91,0x210D,0xEF92,0xEF93,0xEF94,0xEF95,0xEF96,0x2115,0xEF97,0x2119,0x211A,0x211D,0xEF98,0xEF99,0xEF9A,0xEF9B,0xEF9C,0xEF9D,0xEF9E,0x2124];++var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4, + RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8,+ LEFTRIGHT = 9, TEXT = 10; // token types++var AMsqrt = {input:"sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY},+ AMroot = {input:"root", tag:"mroot", output:"root", tex:null, ttype:BINARY},+ AMfrac = {input:"frac", tag:"mfrac", output:"/", tex:null, ttype:BINARY},+ AMdiv = {input:"/", tag:"mfrac", output:"/", tex:null, ttype:INFIX},+ AMover = {input:"stackrel", tag:"mover", output:"stackrel", tex:null, ttype:BINARY},+ AMsub = {input:"_", tag:"msub", output:"_", tex:null, ttype:INFIX},+ AMsup = {input:"^", tag:"msup", output:"^", tex:null, ttype:INFIX},+ AMtext = {input:"text", tag:"mtext", output:"text", tex:null, ttype:TEXT},+ AMmbox = {input:"mbox", tag:"mtext", output:"mbox", tex:null, ttype:TEXT},+ AMquote = {input:"\"", tag:"mtext", output:"mbox", tex:null, ttype:TEXT};++var AMsymbols = [+//some greek symbols+{input:"alpha", tag:"mi", output:"\u03B1", tex:null, ttype:CONST},+{input:"beta", tag:"mi", output:"\u03B2", tex:null, ttype:CONST},+{input:"chi", tag:"mi", output:"\u03C7", tex:null, ttype:CONST},+{input:"delta", tag:"mi", output:"\u03B4", tex:null, ttype:CONST},+{input:"Delta", tag:"mo", output:"\u0394", tex:null, ttype:CONST},+{input:"epsi", tag:"mi", output:"\u03B5", tex:"epsilon", ttype:CONST},+{input:"varepsilon", tag:"mi", output:"\u025B", tex:null, ttype:CONST},+{input:"eta", tag:"mi", output:"\u03B7", tex:null, ttype:CONST},+{input:"gamma", tag:"mi", output:"\u03B3", tex:null, ttype:CONST},+{input:"Gamma", tag:"mo", output:"\u0393", tex:null, ttype:CONST},+{input:"iota", tag:"mi", output:"\u03B9", tex:null, ttype:CONST},+{input:"kappa", tag:"mi", output:"\u03BA", tex:null, ttype:CONST},+{input:"lambda", tag:"mi", output:"\u03BB", tex:null, ttype:CONST},+{input:"Lambda", tag:"mo", output:"\u039B", tex:null, ttype:CONST},+{input:"mu", tag:"mi", output:"\u03BC", tex:null, ttype:CONST},+{input:"nu", tag:"mi", output:"\u03BD", tex:null, ttype:CONST},+{input:"omega", tag:"mi", output:"\u03C9", tex:null, ttype:CONST},+{input:"Omega", tag:"mo", output:"\u03A9", tex:null, ttype:CONST},+{input:"phi", tag:"mi", output:"\u03C6", tex:null, ttype:CONST},+{input:"varphi", tag:"mi", output:"\u03D5", tex:null, ttype:CONST},+{input:"Phi", tag:"mo", output:"\u03A6", tex:null, ttype:CONST},+{input:"pi", tag:"mi", output:"\u03C0", tex:null, ttype:CONST},+{input:"Pi", tag:"mo", output:"\u03A0", tex:null, ttype:CONST},+{input:"psi", tag:"mi", output:"\u03C8", tex:null, ttype:CONST},+{input:"Psi", tag:"mi", output:"\u03A8", tex:null, ttype:CONST},+{input:"rho", tag:"mi", output:"\u03C1", tex:null, ttype:CONST},+{input:"sigma", tag:"mi", output:"\u03C3", tex:null, ttype:CONST},+{input:"Sigma", tag:"mo", output:"\u03A3", tex:null, ttype:CONST},+{input:"tau", tag:"mi", output:"\u03C4", tex:null, ttype:CONST},+{input:"theta", tag:"mi", output:"\u03B8", tex:null, ttype:CONST},+{input:"vartheta", tag:"mi", output:"\u03D1", tex:null, ttype:CONST},+{input:"Theta", tag:"mo", output:"\u0398", tex:null, ttype:CONST},+{input:"upsilon", tag:"mi", output:"\u03C5", tex:null, ttype:CONST},+{input:"xi", tag:"mi", output:"\u03BE", tex:null, ttype:CONST},+{input:"Xi", tag:"mo", output:"\u039E", tex:null, ttype:CONST},+{input:"zeta", tag:"mi", output:"\u03B6", tex:null, ttype:CONST},++//binary operation symbols+{input:"*", tag:"mo", output:"\u22C5", tex:"cdot", ttype:CONST},+{input:"**", tag:"mo", output:"\u22C6", tex:"star", ttype:CONST},+{input:"//", tag:"mo", output:"/", tex:null, ttype:CONST},+{input:"\\\\", tag:"mo", output:"\\", tex:"backslash", ttype:CONST},+{input:"setminus", tag:"mo", output:"\\", tex:null, ttype:CONST},+{input:"xx", tag:"mo", output:"\u00D7", tex:"times", ttype:CONST},+{input:"-:", tag:"mo", output:"\u00F7", tex:"divide", ttype:CONST},+{input:"@", tag:"mo", output:"\u2218", tex:"circ", ttype:CONST},+{input:"o+", tag:"mo", output:"\u2295", tex:"oplus", ttype:CONST},+{input:"ox", tag:"mo", output:"\u2297", tex:"otimes", ttype:CONST},+{input:"o.", tag:"mo", output:"\u2299", tex:"odot", ttype:CONST},+{input:"sum", tag:"mo", output:"\u2211", tex:null, ttype:UNDEROVER},+{input:"prod", tag:"mo", output:"\u220F", tex:null, ttype:UNDEROVER},+{input:"^^", tag:"mo", output:"\u2227", tex:"wedge", ttype:CONST},+{input:"^^^", tag:"mo", output:"\u22C0", tex:"bigwedge", ttype:UNDEROVER},+{input:"vv", tag:"mo", output:"\u2228", tex:"vee", ttype:CONST},+{input:"vvv", tag:"mo", output:"\u22C1", tex:"bigvee", ttype:UNDEROVER},+{input:"nn", tag:"mo", output:"\u2229", tex:"cap", ttype:CONST},+{input:"nnn", tag:"mo", output:"\u22C2", tex:"bigcap", ttype:UNDEROVER},+{input:"uu", tag:"mo", output:"\u222A", tex:"cup", ttype:CONST},+{input:"uuu", tag:"mo", output:"\u22C3", tex:"bigcup", ttype:UNDEROVER},++//binary relation symbols+{input:"!=", tag:"mo", output:"\u2260", tex:"ne", ttype:CONST},+{input:":=", tag:"mo", output:":=", tex:null, ttype:CONST},+{input:"lt", tag:"mo", output:"<", tex:null, ttype:CONST},+{input:"<=", tag:"mo", output:"\u2264", tex:"le", ttype:CONST},+{input:"lt=", tag:"mo", output:"\u2264", tex:"leq", ttype:CONST},+{input:">=", tag:"mo", output:"\u2265", tex:"ge", ttype:CONST},+{input:"geq", tag:"mo", output:"\u2265", tex:null, ttype:CONST},+{input:"-<", tag:"mo", output:"\u227A", tex:"prec", ttype:CONST},+{input:"-lt", tag:"mo", output:"\u227A", tex:null, ttype:CONST},+{input:">-", tag:"mo", output:"\u227B", tex:"succ", ttype:CONST},+{input:"-<=", tag:"mo", output:"\u2AAF", tex:"preceq", ttype:CONST},+{input:">-=", tag:"mo", output:"\u2AB0", tex:"succeq", ttype:CONST},+{input:"in", tag:"mo", output:"\u2208", tex:null, ttype:CONST},+{input:"!in", tag:"mo", output:"\u2209", tex:"notin", ttype:CONST},+{input:"sub", tag:"mo", output:"\u2282", tex:"subset", ttype:CONST},+{input:"sup", tag:"mo", output:"\u2283", tex:"supset", ttype:CONST},+{input:"sube", tag:"mo", output:"\u2286", tex:"subseteq", ttype:CONST},+{input:"supe", tag:"mo", output:"\u2287", tex:"supseteq", ttype:CONST},+{input:"-=", tag:"mo", output:"\u2261", tex:"equiv", ttype:CONST},+{input:"~=", tag:"mo", output:"\u2245", tex:"cong", ttype:CONST},+{input:"~~", tag:"mo", output:"\u2248", tex:"approx", ttype:CONST},+{input:"prop", tag:"mo", output:"\u221D", tex:"propto", ttype:CONST},++//logical symbols+{input:"and", tag:"mtext", output:"and", tex:null, ttype:SPACE},+{input:"or", tag:"mtext", output:"or", tex:null, ttype:SPACE},+{input:"not", tag:"mo", output:"\u00AC", tex:"neg", ttype:CONST},+{input:"=>", tag:"mo", output:"\u21D2", tex:"implies", ttype:CONST},+{input:"if", tag:"mo", output:"if", tex:null, ttype:SPACE},+{input:"<=>", tag:"mo", output:"\u21D4", tex:"iff", ttype:CONST},+{input:"AA", tag:"mo", output:"\u2200", tex:"forall", ttype:CONST},+{input:"EE", tag:"mo", output:"\u2203", tex:"exists", ttype:CONST},+{input:"_|_", tag:"mo", output:"\u22A5", tex:"bot", ttype:CONST},+{input:"TT", tag:"mo", output:"\u22A4", tex:"top", ttype:CONST},+{input:"|--", tag:"mo", output:"\u22A2", tex:"vdash", ttype:CONST},+{input:"|==", tag:"mo", output:"\u22A8", tex:"models", ttype:CONST},++//grouping brackets+{input:"(", tag:"mo", output:"(", tex:null, ttype:LEFTBRACKET},+{input:")", tag:"mo", output:")", tex:null, ttype:RIGHTBRACKET},+{input:"[", tag:"mo", output:"[", tex:null, ttype:LEFTBRACKET},+{input:"]", tag:"mo", output:"]", tex:null, ttype:RIGHTBRACKET},+{input:"{", tag:"mo", output:"{", tex:null, ttype:LEFTBRACKET},+{input:"}", tag:"mo", output:"}", tex:null, ttype:RIGHTBRACKET},+{input:"|", tag:"mo", output:"|", tex:null, ttype:LEFTRIGHT},+//{input:"||", tag:"mo", output:"||", tex:null, ttype:LEFTRIGHT},+{input:"(:", tag:"mo", output:"\u2329", tex:"langle", ttype:LEFTBRACKET},+{input:":)", tag:"mo", output:"\u232A", tex:"rangle", ttype:RIGHTBRACKET},+{input:"<<", tag:"mo", output:"\u2329", tex:null, ttype:LEFTBRACKET},+{input:">>", tag:"mo", output:"\u232A", tex:null, ttype:RIGHTBRACKET},+{input:"{:", tag:"mo", output:"{:", tex:null, ttype:LEFTBRACKET, invisible:true},+{input:":}", tag:"mo", output:":}", tex:null, ttype:RIGHTBRACKET, invisible:true},++//miscellaneous symbols+{input:"int", tag:"mo", output:"\u222B", tex:null, ttype:CONST},+{input:"dx", tag:"mi", output:"{:d x:}", tex:null, ttype:DEFINITION},+{input:"dy", tag:"mi", output:"{:d y:}", tex:null, ttype:DEFINITION},+{input:"dz", tag:"mi", output:"{:d z:}", tex:null, ttype:DEFINITION},+{input:"dt", tag:"mi", output:"{:d t:}", tex:null, ttype:DEFINITION},+{input:"oint", tag:"mo", output:"\u222E", tex:null, ttype:CONST},+{input:"del", tag:"mo", output:"\u2202", tex:"partial", ttype:CONST},+{input:"grad", tag:"mo", output:"\u2207", tex:"nabla", ttype:CONST},+{input:"+-", tag:"mo", output:"\u00B1", tex:"pm", ttype:CONST},+{input:"O/", tag:"mo", output:"\u2205", tex:"emptyset", ttype:CONST},+{input:"oo", tag:"mo", output:"\u221E", tex:"infty", ttype:CONST},+{input:"aleph", tag:"mo", output:"\u2135", tex:null, ttype:CONST},+{input:"...", tag:"mo", output:"...", tex:"ldots", ttype:CONST},+{input:":.", tag:"mo", output:"\u2234", tex:"therefore", ttype:CONST},+{input:"/_", tag:"mo", output:"\u2220", tex:"angle", ttype:CONST},+{input:"\\ ", tag:"mo", output:"\u00A0", tex:null, ttype:CONST},+{input:"quad", tag:"mo", output:"\u00A0\u00A0", tex:null, ttype:CONST},+{input:"qquad", tag:"mo", output:"\u00A0\u00A0\u00A0\u00A0", tex:null, ttype:CONST},+{input:"cdots", tag:"mo", output:"\u22EF", tex:null, ttype:CONST},+{input:"vdots", tag:"mo", output:"\u22EE", tex:null, ttype:CONST},+{input:"ddots", tag:"mo", output:"\u22F1", tex:null, ttype:CONST},+{input:"diamond", tag:"mo", output:"\u22C4", tex:null, ttype:CONST},+{input:"square", tag:"mo", output:"\u25A1", tex:null, ttype:CONST},+{input:"|__", tag:"mo", output:"\u230A", tex:"lfloor", ttype:CONST},+{input:"__|", tag:"mo", output:"\u230B", tex:"rfloor", ttype:CONST},+{input:"|~", tag:"mo", output:"\u2308", tex:"lceiling", ttype:CONST},+{input:"~|", tag:"mo", output:"\u2309", tex:"rceiling", ttype:CONST},+{input:"CC", tag:"mo", output:"\u2102", tex:null, ttype:CONST},+{input:"NN", tag:"mo", output:"\u2115", tex:null, ttype:CONST},+{input:"QQ", tag:"mo", output:"\u211A", tex:null, ttype:CONST},+{input:"RR", tag:"mo", output:"\u211D", tex:null, ttype:CONST},+{input:"ZZ", tag:"mo", output:"\u2124", tex:null, ttype:CONST},+{input:"f", tag:"mi", output:"f", tex:null, ttype:UNARY, func:true},+{input:"g", tag:"mi", output:"g", tex:null, ttype:UNARY, func:true},++//standard functions+{input:"lim", tag:"mo", output:"lim", tex:null, ttype:UNDEROVER},+{input:"Lim", tag:"mo", output:"Lim", tex:null, ttype:UNDEROVER},+{input:"sin", tag:"mo", output:"sin", tex:null, ttype:UNARY, func:true},+{input:"cos", tag:"mo", output:"cos", tex:null, ttype:UNARY, func:true},+{input:"tan", tag:"mo", output:"tan", tex:null, ttype:UNARY, func:true},+{input:"sinh", tag:"mo", output:"sinh", tex:null, ttype:UNARY, func:true},+{input:"cosh", tag:"mo", output:"cosh", tex:null, ttype:UNARY, func:true},+{input:"tanh", tag:"mo", output:"tanh", tex:null, ttype:UNARY, func:true},+{input:"cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true},+{input:"sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true},+{input:"csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true},+{input:"log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true},+{input:"ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true},+{input:"det", tag:"mo", output:"det", tex:null, ttype:UNARY, func:true},+{input:"dim", tag:"mo", output:"dim", tex:null, ttype:CONST},+{input:"mod", tag:"mo", output:"mod", tex:null, ttype:CONST},+{input:"gcd", tag:"mo", output:"gcd", tex:null, ttype:UNARY, func:true},+{input:"lcm", tag:"mo", output:"lcm", tex:null, ttype:UNARY, func:true},+{input:"lub", tag:"mo", output:"lub", tex:null, ttype:CONST},+{input:"glb", tag:"mo", output:"glb", tex:null, ttype:CONST},+{input:"min", tag:"mo", output:"min", tex:null, ttype:UNDEROVER},+{input:"max", tag:"mo", output:"max", tex:null, ttype:UNDEROVER},++//arrows+{input:"uarr", tag:"mo", output:"\u2191", tex:"uparrow", ttype:CONST},+{input:"darr", tag:"mo", output:"\u2193", tex:"downarrow", ttype:CONST},+{input:"rarr", tag:"mo", output:"\u2192", tex:"rightarrow", ttype:CONST},+{input:"->", tag:"mo", output:"\u2192", tex:"to", ttype:CONST},+{input:"|->", tag:"mo", output:"\u21A6", tex:"mapsto", ttype:CONST},+{input:"larr", tag:"mo", output:"\u2190", tex:"leftarrow", ttype:CONST},+{input:"harr", tag:"mo", output:"\u2194", tex:"leftrightarrow", ttype:CONST},+{input:"rArr", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST},+{input:"lArr", tag:"mo", output:"\u21D0", tex:"Leftarrow", ttype:CONST},+{input:"hArr", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST},++//commands with argument+AMsqrt, AMroot, AMfrac, AMdiv, AMover, AMsub, AMsup,+{input:"hat", tag:"mover", output:"\u005E", tex:null, ttype:UNARY, acc:true},+{input:"bar", tag:"mover", output:"\u00AF", tex:"overline", ttype:UNARY, acc:true},+{input:"vec", tag:"mover", output:"\u2192", tex:null, ttype:UNARY, acc:true},+{input:"dot", tag:"mover", output:".", tex:null, ttype:UNARY, acc:true},+{input:"ddot", tag:"mover", output:"..", tex:null, ttype:UNARY, acc:true},+{input:"ul", tag:"munder", output:"\u0332", tex:"underline", ttype:UNARY, acc:true},+AMtext, AMmbox, AMquote,+{input:"bb", tag:"mstyle", atname:"fontweight", atval:"bold", output:"bb", tex:null, ttype:UNARY},+{input:"mathbf", tag:"mstyle", atname:"fontweight", atval:"bold", output:"mathbf", tex:null, ttype:UNARY},+{input:"sf", tag:"mstyle", atname:"fontfamily", atval:"sans-serif", output:"sf", tex:null, ttype:UNARY},+{input:"mathsf", tag:"mstyle", atname:"fontfamily", atval:"sans-serif", output:"mathsf", tex:null, ttype:UNARY},+{input:"bbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"bbb", tex:null, ttype:UNARY, codes:AMbbb},+{input:"mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"mathbb", tex:null, ttype:UNARY, codes:AMbbb},+{input:"cc", tag:"mstyle", atname:"mathvariant", atval:"script", output:"cc", tex:null, ttype:UNARY, codes:AMcal},+{input:"mathcal", tag:"mstyle", atname:"mathvariant", atval:"script", output:"mathcal", tex:null, ttype:UNARY, codes:AMcal},+{input:"tt", tag:"mstyle", atname:"fontfamily", atval:"monospace", output:"tt", tex:null, ttype:UNARY},+{input:"mathtt", tag:"mstyle", atname:"fontfamily", atval:"monospace", output:"mathtt", tex:null, ttype:UNARY},+{input:"fr", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"fr", tex:null, ttype:UNARY, codes:AMfrk},+{input:"mathfrak", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"mathfrak", tex:null, ttype:UNARY, codes:AMfrk}+];++function compareNames(s1,s2) {+ if (s1.input > s2.input) return 1+ else return -1;+}++var AMnames = []; //list of input symbols++function AMinitSymbols() {+ var texsymbols = [], i;+ for (i=0; i<AMsymbols.length; i++)+ if (AMsymbols[i].tex) + texsymbols[texsymbols.length] = {input:AMsymbols[i].tex, + tag:AMsymbols[i].tag, output:AMsymbols[i].output, ttype:AMsymbols[i].ttype};+ AMsymbols = AMsymbols.concat(texsymbols);+ AMsymbols.sort(compareNames);+ for (i=0; i<AMsymbols.length; i++) AMnames[i] = AMsymbols[i].input;+}++var AMmathml = "http://www.w3.org/1998/Math/MathML";++function AMcreateElementMathML(t) {+ if (isIE) return document.createElement("m:"+t);+ else return document.createElementNS(AMmathml,t);+}++function AMcreateMmlNode(t,frag) {+// var node = AMcreateElementMathML(name);+ if (isIE) var node = document.createElement("m:"+t);+ else var node = document.createElementNS(AMmathml,t);+ node.appendChild(frag);+ return node;+}++function newcommand(oldstr,newstr) {+ AMsymbols = AMsymbols.concat([{input:oldstr, tag:"mo", output:newstr, + tex:null, ttype:DEFINITION}]);+}++function AMremoveCharsAndBlanks(str,n) {+//remove n characters and any following blanks+ var st;+ if (str.charAt(n)=="\\" && str.charAt(n+1)!="\\" && str.charAt(n+1)!=" ") + st = str.slice(n+1);+ else st = str.slice(n);+ for (var i=0; i<st.length && st.charCodeAt(i)<=32; i=i+1);+ return st.slice(i);+}++function AMposition(arr, str, n) { +// return position >=n where str appears or would be inserted+// assumes arr is sorted+ if (n==0) {+ var h,m;+ n = -1;+ h = arr.length;+ while (n+1<h) {+ m = (n+h) >> 1;+ if (arr[m]<str) n = m; else h = m;+ }+ return h;+ } else+ for (var i=n; i<arr.length && arr[i]<str; i++);+ return i; // i=arr.length || arr[i]>=str+}++function AMgetSymbol(str) {+//return maximal initial substring of str that appears in names+//return null if there is none+ var k = 0; //new pos+ var j = 0; //old pos+ var mk; //match pos+ var st;+ var tagst;+ var match = "";+ var more = true;+ for (var i=1; i<=str.length && more; i++) {+ st = str.slice(0,i); //initial substring of length i+ j = k;+ k = AMposition(AMnames, st, j);+ if (k<AMnames.length && str.slice(0,AMnames[k].length)==AMnames[k]){+ match = AMnames[k];+ mk = k;+ i = match.length;+ }+ more = k<AMnames.length && str.slice(0,AMnames[k].length)>=AMnames[k];+ }+ AMpreviousSymbol=AMcurrentSymbol;+ if (match!=""){+ AMcurrentSymbol=AMsymbols[mk].ttype;+ return AMsymbols[mk]; + }+// if str[0] is a digit or - return maxsubstring of digits.digits+ AMcurrentSymbol=CONST;+ k = 1;+ st = str.slice(0,1);+ var integ = true;+ while ("0"<=st && st<="9" && k<=str.length) {+ st = str.slice(k,k+1);+ k++;+ }+ if (st == decimalsign) {+ st = str.slice(k,k+1);+ if ("0"<=st && st<="9") {+ integ = false;+ k++;+ while ("0"<=st && st<="9" && k<=str.length) {+ st = str.slice(k,k+1);+ k++;+ }+ }+ }+ if ((integ && k>1) || k>2) {+ st = str.slice(0,k-1);+ tagst = "mn";+ } else {+ k = 2;+ st = str.slice(0,1); //take 1 character+ tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi");+ }+ if (st=="-" && AMpreviousSymbol==INFIX) {+ AMcurrentSymbol = INFIX; //trick "/" into recognizing "-" on second parse+ return {input:st, tag:tagst, output:st, ttype:UNARY, func:true};+ }+ return {input:st, tag:tagst, output:st, ttype:CONST};+}++function AMremoveBrackets(node) {+ var st;+ if (node.nodeName=="mrow") {+ st = node.firstChild.firstChild.nodeValue;+ if (st=="(" || st=="[" || st=="{") node.removeChild(node.firstChild);+ }+ if (node.nodeName=="mrow") {+ st = node.lastChild.firstChild.nodeValue;+ if (st==")" || st=="]" || st=="}") node.removeChild(node.lastChild);+ }+}++/* ASCIIMathML.js - copyright Peter Jipsen, released under the GPL+See http://www1.chapman.edu/~jipsen/mathml/asciimath.html/ */++var AMnestingDepth,AMpreviousSymbol,AMcurrentSymbol;++function AMparseSexpr(str) { //parses str and returns [node,tailstr]+ var symbol, node, result, i, st,// rightvert = false,+ newFrag = document.createDocumentFragment();+ str = AMremoveCharsAndBlanks(str,0);+ symbol = AMgetSymbol(str); //either a token or a bracket or empty+ if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) {+ return [null,str];+ }+ if (symbol.ttype == DEFINITION) {+ str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length); + symbol = AMgetSymbol(str);+ }+ switch (symbol.ttype) {+ case UNDEROVER:+ case CONST:+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [AMcreateMmlNode(symbol.tag, //its a constant+ document.createTextNode(symbol.output)),str];+ case LEFTBRACKET: //read (expr+)+ AMnestingDepth++;+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseExpr(str,true);+ AMnestingDepth--;+ if (typeof symbol.invisible == "boolean" && symbol.invisible) + node = AMcreateMmlNode("mrow",result[0]);+ else {+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));+ node = AMcreateMmlNode("mrow",node);+ node.appendChild(result[0]);+ }+ return [node,result[1]];+ case TEXT:+ if (symbol!=AMquote) str = AMremoveCharsAndBlanks(str,symbol.input.length);+ if (str.charAt(0)=="{") i=str.indexOf("}");+ else if (str.charAt(0)=="(") i=str.indexOf(")");+ else if (str.charAt(0)=="[") i=str.indexOf("]");+ else if (symbol==AMquote) i=str.slice(1).indexOf("\"")+1;+ else i = 0;+ if (i==-1) i = str.length;+ st = str.slice(1,i);+ if (st.charAt(0) == " ") {+ node = AMcreateElementMathML("mspace");+ node.setAttribute("width","1ex");+ newFrag.appendChild(node);+ }+ newFrag.appendChild(+ AMcreateMmlNode(symbol.tag,document.createTextNode(st)));+ if (st.charAt(st.length-1) == " ") {+ node = AMcreateElementMathML("mspace");+ node.setAttribute("width","1ex");+ newFrag.appendChild(node);+ }+ str = AMremoveCharsAndBlanks(str,i+1);+ return [AMcreateMmlNode("mrow",newFrag),str];+ case UNARY:+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseSexpr(str);+ if (result[0]==null) return [AMcreateMmlNode(symbol.tag,+ document.createTextNode(symbol.output)),str];+ if (typeof symbol.func == "boolean" && symbol.func) { // functions hack+ st = str.charAt(0);+ if (st=="^" || st=="_" || st=="/" || st=="|" || st==",") {+ return [AMcreateMmlNode(symbol.tag,+ document.createTextNode(symbol.output)),str];+ } else {+ node = AMcreateMmlNode("mrow",+ AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));+ node.appendChild(result[0]);+ return [node,result[1]];+ }+ }+ AMremoveBrackets(result[0]);+ if (symbol.input == "sqrt") { // sqrt+ return [AMcreateMmlNode(symbol.tag,result[0]),result[1]];+ } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent+ node = AMcreateMmlNode(symbol.tag,result[0]);+ node.appendChild(AMcreateMmlNode("mo",document.createTextNode(symbol.output)));+ return [node,result[1]];+ } else { // font change command+ if (!isIE && typeof symbol.codes != "undefined") {+ for (i=0; i<result[0].childNodes.length; i++)+ if (result[0].childNodes[i].nodeName=="mi" || result[0].nodeName=="mi") {+ st = (result[0].nodeName=="mi"?result[0].firstChild.nodeValue:+ result[0].childNodes[i].firstChild.nodeValue);+ var newst = [];+ for (var j=0; j<st.length; j++)+ if (st.charCodeAt(j)>64 && st.charCodeAt(j)<91) newst = newst ++ String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]);+ else newst = newst + st.charAt(j);+ if (result[0].nodeName=="mi")+ result[0]=AMcreateElementMathML("mo").+ appendChild(document.createTextNode(newst));+ else result[0].replaceChild(AMcreateElementMathML("mo").+ appendChild(document.createTextNode(newst)),result[0].childNodes[i]);+ }+ }+ node = AMcreateMmlNode(symbol.tag,result[0]);+ node.setAttribute(symbol.atname,symbol.atval);+ return [node,result[1]];+ }+ case BINARY:+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseSexpr(str);+ if (result[0]==null) return [AMcreateMmlNode("mo",+ document.createTextNode(symbol.input)),str];+ AMremoveBrackets(result[0]);+ var result2 = AMparseSexpr(result[1]);+ if (result2[0]==null) return [AMcreateMmlNode("mo",+ document.createTextNode(symbol.input)),str];+ AMremoveBrackets(result2[0]);+ if (symbol.input=="root" || symbol.input=="stackrel") + newFrag.appendChild(result2[0]);+ newFrag.appendChild(result[0]);+ if (symbol.input=="frac") newFrag.appendChild(result2[0]);+ return [AMcreateMmlNode(symbol.tag,newFrag),result2[1]];+ case INFIX:+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [AMcreateMmlNode("mo",document.createTextNode(symbol.output)),str];+ case SPACE:+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + node = AMcreateElementMathML("mspace");+ node.setAttribute("width","1ex");+ newFrag.appendChild(node);+ newFrag.appendChild(+ AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));+ node = AMcreateElementMathML("mspace");+ node.setAttribute("width","1ex");+ newFrag.appendChild(node);+ return [AMcreateMmlNode("mrow",newFrag),str];+ case LEFTRIGHT:+// if (rightvert) return [null,str]; else rightvert = true;+ AMnestingDepth++;+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + result = AMparseExpr(str,false);+ AMnestingDepth--;+ var st = "";+ if (result[0].lastChild!=null)+ st = result[0].lastChild.firstChild.nodeValue;+ if (st == "|") { // its an absolute value subterm+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));+ node = AMcreateMmlNode("mrow",node);+ node.appendChild(result[0]);+ return [node,result[1]];+ } else { // the "|" is a \mid+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));+ node = AMcreateMmlNode("mrow",node);+ return [node,str];+ }+ default:+//alert("default");+ str = AMremoveCharsAndBlanks(str,symbol.input.length); + return [AMcreateMmlNode(symbol.tag, //its a constant+ document.createTextNode(symbol.output)),str];+ }+}++function AMparseIexpr(str) {+ var symbol, sym1, sym2, node, result, underover;+ str = AMremoveCharsAndBlanks(str,0);+ sym1 = AMgetSymbol(str);+ result = AMparseSexpr(str);+ node = result[0];+ str = result[1];+ symbol = AMgetSymbol(str);+ if (symbol.ttype == INFIX && symbol.input != "/") {+ str = AMremoveCharsAndBlanks(str,symbol.input.length);+// if (symbol.input == "/") result = AMparseIexpr(str); else ...+ result = AMparseSexpr(str);+ if (result[0] == null) // show box in place of missing argument+ result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1"));+ else AMremoveBrackets(result[0]);+ str = result[1];+// if (symbol.input == "/") AMremoveBrackets(node);+ if (symbol.input == "_") {+ sym2 = AMgetSymbol(str);+ underover = (sym1.ttype == UNDEROVER);+ if (sym2.input == "^") {+ str = AMremoveCharsAndBlanks(str,sym2.input.length);+ var res2 = AMparseSexpr(str);+ AMremoveBrackets(res2[0]);+ str = res2[1];+ node = AMcreateMmlNode((underover?"munderover":"msubsup"),node);+ node.appendChild(result[0]);+ node.appendChild(res2[0]);+ node = AMcreateMmlNode("mrow",node); // so sum does not stretch+ } else {+ node = AMcreateMmlNode((underover?"munder":"msub"),node);+ node.appendChild(result[0]);+ }+ } else {+ node = AMcreateMmlNode(symbol.tag,node);+ node.appendChild(result[0]);+ }+ }+ return [node,str];+}++function AMparseExpr(str,rightbracket) {+ var symbol, node, result, i, nodeList = [],+ newFrag = document.createDocumentFragment();+ do {+ str = AMremoveCharsAndBlanks(str,0);+ result = AMparseIexpr(str);+ node = result[0];+ str = result[1];+ symbol = AMgetSymbol(str);+ if (symbol.ttype == INFIX && symbol.input == "/") {+ str = AMremoveCharsAndBlanks(str,symbol.input.length);+ result = AMparseIexpr(str);+ if (result[0] == null) // show box in place of missing argument+ result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1"));+ else AMremoveBrackets(result[0]);+ str = result[1];+ AMremoveBrackets(node);+ node = AMcreateMmlNode(symbol.tag,node);+ node.appendChild(result[0]);+ newFrag.appendChild(node);+ symbol = AMgetSymbol(str);+ } + else if (node!=undefined) newFrag.appendChild(node);+ } while ((symbol.ttype != RIGHTBRACKET && + (symbol.ttype != LEFTRIGHT || rightbracket)+ || AMnestingDepth == 0) && symbol!=null && symbol.output!="");+ if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) {+// if (AMnestingDepth > 0) AMnestingDepth--;+ var len = newFrag.childNodes.length;+ if (len>0 && newFrag.childNodes[len-1].nodeName == "mrow" && len>1 &&+ newFrag.childNodes[len-2].nodeName == "mo" &&+ newFrag.childNodes[len-2].firstChild.nodeValue == ",") { //matrix+ var right = newFrag.childNodes[len-1].lastChild.firstChild.nodeValue;+ if (right==")" || right=="]") {+ var left = newFrag.childNodes[len-1].firstChild.firstChild.nodeValue;+ if (left=="(" && right==")" && symbol.output != "}" || + left=="[" && right=="]") {+ var pos = []; // positions of commas+ var matrix = true;+ var m = newFrag.childNodes.length;+ for (i=0; matrix && i<m; i=i+2) {+ pos[i] = [];+ node = newFrag.childNodes[i];+ if (matrix) matrix = node.nodeName=="mrow" && + (i==m-1 || node.nextSibling.nodeName=="mo" && + node.nextSibling.firstChild.nodeValue==",")&&+ node.firstChild.firstChild.nodeValue==left &&+ node.lastChild.firstChild.nodeValue==right;+ if (matrix) + for (var j=0; j<node.childNodes.length; j++)+ if (node.childNodes[j].firstChild.nodeValue==",")+ pos[i][pos[i].length]=j;+ if (matrix && i>1) matrix = pos[i].length == pos[i-2].length;+ }+ if (matrix) {+ var row, frag, n, k, table = document.createDocumentFragment();+ for (i=0; i<m; i=i+2) {+ row = document.createDocumentFragment();+ frag = document.createDocumentFragment();+ node = newFrag.firstChild; // <mrow>(-,-,...,-,-)</mrow>+ n = node.childNodes.length;+ k = 0;+ node.removeChild(node.firstChild); //remove (+ for (j=1; j<n-1; j++) {+ if (typeof pos[i][k] != "undefined" && j==pos[i][k]){+ node.removeChild(node.firstChild); //remove ,+ row.appendChild(AMcreateMmlNode("mtd",frag));+ k++;+ } else frag.appendChild(node.firstChild);+ }+ row.appendChild(AMcreateMmlNode("mtd",frag));+ if (newFrag.childNodes.length>2) {+ newFrag.removeChild(newFrag.firstChild); //remove <mrow>)</mrow>+ newFrag.removeChild(newFrag.firstChild); //remove <mo>,</mo>+ }+ table.appendChild(AMcreateMmlNode("mtr",row));+ }+ node = AMcreateMmlNode("mtable",table);+ if (typeof symbol.invisible == "boolean" && symbol.invisible) node.setAttribute("columnalign","left");+ newFrag.replaceChild(node,newFrag.firstChild);+ }+ }+ }+ }+ str = AMremoveCharsAndBlanks(str,symbol.input.length);+ if (typeof symbol.invisible != "boolean" || !symbol.invisible) {+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));+ newFrag.appendChild(node);+ }+ }+ return [newFrag,str];+}++function AMparseMath(str) {+ var result, node = AMcreateElementMathML("mstyle");+ if (mathcolor != "") node.setAttribute("mathcolor",mathcolor);+ if (displaystyle) node.setAttribute("displaystyle","true");+ if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily);+ AMnestingDepth = 0;+ node.appendChild(AMparseExpr(str.replace(/^\s+/g,""),false)[0]);+ node = AMcreateMmlNode("math",node);+ if (showasciiformulaonhover) //fixed by djhsu so newline+ node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko+ if (mathfontfamily != "" && (isIE || mathfontfamily != "serif")) {+ var fnode = AMcreateElementXHTML("font");+ fnode.setAttribute("face",mathfontfamily);+ fnode.appendChild(node);+ return fnode;+ }+ return node;+}++function AMstrarr2docFrag(arr, linebreaks) {+ var newFrag=document.createDocumentFragment();+ var expr = false;+ for (var i=0; i<arr.length; i++) {+ if (expr) newFrag.appendChild(AMparseMath(arr[i]));+ else {+ var arri = (linebreaks ? arr[i].split("\n\n") : [arr[i]]);+ newFrag.appendChild(AMcreateElementXHTML("span").+ appendChild(document.createTextNode(arri[0])));+ for (var j=1; j<arri.length; j++) {+ newFrag.appendChild(AMcreateElementXHTML("p"));+ newFrag.appendChild(AMcreateElementXHTML("span").+ appendChild(document.createTextNode(arri[j])));+ }+ }+ expr = !expr;+ }+ return newFrag;+}++function AMprocessNodeR(n, linebreaks) {+ var mtch, str, arr, frg, i;+ if (n.childNodes.length == 0) {+ if ((n.nodeType!=8 || linebreaks) &&+ n.parentNode.nodeName!="form" && n.parentNode.nodeName!="FORM" &&+ n.parentNode.nodeName!="textarea" && n.parentNode.nodeName!="TEXTAREA" &&+ n.parentNode.nodeName!="code" && n.parentNode.nodeName!="CODE" && /* ASCIIMathML.js - copyright Peter Jipsen, released under the GPL+See http://www1.chapman.edu/~jipsen/mathml/asciimath.html/ */+ n.parentNode.nodeName!="pre" && n.parentNode.nodeName!="PRE") {+ str = n.nodeValue;+ if (!(str == null)) {+ str = str.replace(/\r\n\r\n/g,"\n\n");+ if (doubleblankmathdelimiter) {+ str = str.replace(/\x20\x20\./g," "+AMdelimiter1+".");+ str = str.replace(/\x20\x20,/g," "+AMdelimiter1+",");+ str = str.replace(/\x20\x20/g," "+AMdelimiter1+" ");+ }+ str = str.replace(/\x20+/g," ");+ str = str.replace(/\s*\r\n/g," ");+ mtch = false;+ str = str.replace(new RegExp(AMescape2, "g"),+ function(st){mtch=true;return "AMescape2"});+ str = str.replace(new RegExp(AMescape1, "g"),+ function(st){mtch=true;return "AMescape1"});+ str = str.replace(new RegExp(AMdelimiter2regexp, "g"),AMdelimiter1);+ arr = str.split(AMdelimiter1);+ for (i=0; i<arr.length; i++)+ arr[i]=arr[i].replace(/AMescape2/g,AMdelimiter2).+ replace(/AMescape1/g,AMdelimiter1);+ if (arr.length>1 || mtch) {+ if (checkForMathML) {+ checkForMathML = false;+ var nd = AMisMathMLavailable();+ AMnoMathML = nd != null;+ if (AMnoMathML && notifyIfNoMathML) + if (alertIfNoMathML)+ alert("To view the ASCIIMathML notation use Internet Explorer 6 +\nMathPlayer (free from www.dessci.com)\n\+ or Firefox/Mozilla/Netscape");+ else AMbody.insertBefore(nd,AMbody.childNodes[0]);+ }+ if (!AMnoMathML) {+ frg = AMstrarr2docFrag(arr,n.nodeType==8);+ var len = frg.childNodes.length;+ n.parentNode.replaceChild(frg,n);+ return len-1;+ } else return 0;+ }+ }+ } else return 0;+ } else if (n.nodeName!="math") {+ for (i=0; i<n.childNodes.length; i++)+ i += AMprocessNodeR(n.childNodes[i], linebreaks);+ }+ return 0;+}++function AMprocessNode(n, linebreaks, spanclassAM) {+ var frag,st;+ if (spanclassAM!=null) {+ frag = document.getElementsByTagName("span")+ for (var i=0;i<frag.length;i++)+ if (frag[i].className == "AM")+ AMprocessNodeR(frag[i],linebreaks);+ } else {+ try {+ st = n.innerHTML;+ } catch(err) {}+ if (st==null || + st.indexOf(AMdelimiter1)!=-1 || st.indexOf(AMdelimiter2)!=-1) + AMprocessNodeR(n,linebreaks);+ }+ if (isIE) { //needed to match size and font of formula to surrounding text+ frag = document.getElementsByTagName('math');+ for (var i=0;i<frag.length;i++) frag[i].update()+ }+}++var AMbody;+var AMnoMathML = false, AMtranslated = false;++function translate(spanclassAM) {+ if (!AMtranslated) { // run this only once+ AMtranslated = true;+ AMinitSymbols();+ AMbody = document.getElementsByTagName("body")[0];+ AMprocessNode(AMbody, false, spanclassAM);+ }+}++if (isIE) { // avoid adding MathPlayer info explicitly to each webpage+ document.write("<object id=\"mathplayer\"\+ classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>");+ document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>");+}++// GO1.1 Generic onload by Brothercake +// http://www.brothercake.com/+//onload function (replaces the onload="translate()" in the <body> tag)+function generic()+{+ translate();+};+//setup onload function+if(typeof window.addEventListener != 'undefined')+{+ //.. gecko, safari, konqueror and standard+ window.addEventListener('load', generic, false);+}+else if(typeof document.addEventListener != 'undefined')+{+ //.. opera 7+ document.addEventListener('load', generic, false);+}+else if(typeof window.attachEvent != 'undefined')+{+ //.. win/ie+ window.attachEvent('onload', generic);+}+//** remove this condition to degrade older browsers+else+{+ //.. mac/ie5 and anything else that gets this far+ //if there's an existing onload function+ if(typeof window.onload == 'function')+ {+ //store it+ var existing = onload;+ //add new onload handler+ window.onload = function()+ {+ //call existing onload function+ existing();+ //call generic onload function+ generic();+ };+ }+ else+ {+ //setup onload function+ window.onload = generic;+ }+}+</script>+<!-- configuration parameters -->+<meta name="defaultView" content="slideshow" />+<meta name="controlVis" content="hidden" />+<style type="text/css" media="projection" id="slideProj">+/* Do not edit or override these styles! The system will likely break if you do. */++div#header, div#footer, div#controls, .slide {position: absolute;}+html>body div#header, html>body div#footer, + html>body div#controls, html>body .slide {position: fixed;}+.handout {display: none;}+.layout {display: block;}+.slide, .hideme, .incremental {visibility: hidden;}+#slide0 {visibility: visible;}++/* The following styles size, place, and layer the slide components.+ Edit these if you want to change the overall slide layout.+ The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */++/* target = 1024x768 */++div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}+div#header {top: 0; height: 3em; z-index: 1;}+div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}+.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2; list-style: none;}+div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;+ margin: 0;}+#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z-index: 10;}+html>body #currentSlide {position: fixed;}++/*+div#header {background: #FCC;}+div#footer {background: #CCF;}+div#controls {background: #BBD;}+div#currentSlide {background: #FFC;}+*/++/* Following are the presentation styles -- edit away! */++body {background: #FFF url(bodybg.gif) -16px 0 no-repeat; color: #000; font-size: 2em;}+:link, :visited {text-decoration: none; color: #00C;}+#controls :active {color: #88A !important;}+#controls :focus {outline: 1px dotted #227;}+h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}+ul, pre {margin: 0; line-height: 1em;}+html, body {margin: 0; padding: 0;}++blockquote, q {font-style: italic;}+blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: center; font-size: 1em;}+blockquote p {margin: 0;}+blockquote i {font-style: normal;}+blockquote b {display: block; margin-top: 0.5em; font-weight: normal; font-size: smaller; font-style: normal;}+blockquote b i {font-style: italic;}++kbd {font-weight: bold; font-size: 1em;}+sup {font-size: smaller; line-height: 1px;}++.slide code {padding: 2px 0.25em; font-weight: bold; color: #533;}+.slide code.bad, code del {color: red;}+.slide code.old {color: silver;}+.slide pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 90%;}+.slide pre code {display: block;}+.slide ul {margin-left: 5%; margin-right: 7%; list-style: disc;}+.slide li {margin-top: 0.75em; margin-right: 0;}+.slide ul ul {line-height: 1;}+.slide ul ul li {margin: .2em; font-size: 85%; list-style: square;}+.slide img.leader {display: block; margin: 0 auto;}++div#header, div#footer {background: #005; color: #AAB;+ font-family: Verdana, Helvetica, sans-serif;}+div#header {background: #005 url(bodybg.gif) -16px 0 no-repeat;+ line-height: 1px;}+div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;}+#footer h1, #footer h2 {display: block; padding: 0 1em;}+#footer h2 {font-style: italic;}++div.long {font-size: 0.75em;}+.slide h1 {position: absolute; top: 0.7em; left: 87px; z-index: 1;+ margin: 0; padding: 0.3em 0 0 50px; white-space: nowrap;+ font: bold 150%/1em Helvetica, sans-serif; text-transform: capitalize;+ color: #DDE; background: #005;}+.slide h3 {font-size: 130%;}+h1 abbr {font-variant: small-caps;}++div#controls {position: absolute; left: 50%; bottom: 0;+ width: 50%;+ text-align: right; font: bold 0.9em Verdana, Helvetica, sans-serif;}+html>body div#controls {position: fixed; padding: 0 0 1em 0;+ top: auto;}+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;+ margin: 0; padding: 0;}+#controls #navLinks a {padding: 0; margin: 0 0.5em; + background: #005; border: none; color: #779; + cursor: pointer;}+#controls #navList {height: 1em;}+#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; background: #DDD; color: #227;}++#currentSlide {text-align: center; font-size: 0.5em; color: #449;}++#slide0 {padding-top: 3.5em; font-size: 90%;}+#slide0 h1 {position: static; margin: 1em 0 0; padding: 0;+ font: bold 2em Helvetica, sans-serif; white-space: normal;+ color: #000; background: transparent;}+#slide0 h2 {font: bold italic 1em Helvetica, sans-serif; margin: 0.25em;}+#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}+#slide0 h4 {margin-top: 0; font-size: 1em;}++ul.urls {list-style: none; display: inline; margin: 0;}+.urls li {display: inline; margin: 0;}+.note {display: none;}+.external {border-bottom: 1px dotted gray;}+html>body .external {border-bottom: none;}+.external:after {content: " \274F"; font-size: smaller; color: #77B;}++.incremental, .incremental *, .incremental *:after {color: #DDE; visibility: visible;}+img.incremental {visibility: hidden;}+.slide .current {color: #B02;}+++/* diagnostics++li:after {content: " [" attr(class) "]"; color: #F88;}+ */+</style>+<style type="text/css" media="projection" id="operaFix">+/* DO NOT CHANGE THESE unless you really want to break Opera Show */+.slide {+ visibility: visible !important;+ position: static !important;+ page-break-before: always;+}+#slide0 {page-break-before: avoid;}++</style>+<style type="text/css" media="screen" id="outlineStyle">+/* don't change this unless you want the layout stuff to show up in the outline view! */++.layout div, #footer *, #controlForm * {display: none;}+#footer, #controls, #controlForm, #navLinks, #toggle {+ display: block; visibility: visible; margin: 0; padding: 0;}+#toggle {float: right; padding: 0.5em;}+html>body #toggle {position: fixed; top: 0; right: 0;}++/* making the outline look pretty-ish */++#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;}+#slide0 h1 {padding-top: 1.5em;}+.slide h1 {margin: 1.5em 0 0; padding-top: 0.25em;+ border-top: 1px solid #888; border-bottom: 1px solid #AAA;}+#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;}++</style>+<style type="text/css" media="print" id="slidePrint">+/* The following rule is necessary to have all slides appear in print! DO NOT REMOVE IT! */+.slide, ul {page-break-inside: avoid; visibility: visible !important;}+h1 {page-break-after: avoid;}++body {font-size: 12pt; background: white;}+* {color: black;}++#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;}+#slide0 h3 {margin: 0; padding: 0;}+#slide0 h4 {margin: 0 0 0.5em; padding: 0;}+#slide0 {margin-bottom: 3em;}++h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;}+.extra {background: transparent !important;}+div.extra, pre.extra, .example {font-size: 10pt; color: #333;}+ul.extra a {font-weight: bold;}+p.example {display: none;}++#header {display: none;}+#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style: italic;}+#footer h2, #controls {display: none;}++/* The following rule keeps the layout stuff out of print. Remove at your own risk! */+.layout, .layout * {display: none !important;}++</style>+<script type="text/javascript">+// S5 v1.1 slides.js -- released into the Public Domain+//+// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information +// about all the wonderful and talented contributors to this code!++var undef;+var slideCSS = '';+var snum = 0;+var smax = 1;+var incpos = 0;+var number = undef;+var s5mode = true;+var defaultView = 'slideshow';+var controlVis = 'visible';++var isIE = navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.indexOf('Opera') < 1 ? 1 : 0;+var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;+var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0;++function hasClass(object, className) {+ if (!object.className) return false;+ return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1);+}++function hasValue(object, value) {+ if (!object) return false;+ return (object.search('(^|\\s)' + value + '(\\s|$)') != -1);+}++function removeClass(object,className) {+ if (!object) return;+ object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2);+}++function addClass(object,className) {+ if (!object || hasClass(object, className)) return;+ if (object.className) {+ object.className += ' '+className;+ } else {+ object.className = className;+ }+}++function GetElementsWithClassName(elementName,className) {+ var allElements = document.getElementsByTagName(elementName);+ var elemColl = new Array();+ for (var i = 0; i< allElements.length; i++) {+ if (hasClass(allElements[i], className)) {+ elemColl[elemColl.length] = allElements[i];+ }+ }+ return elemColl;+}++function isParentOrSelf(element, id) {+ if (element == null || element.nodeName=='BODY') return false;+ else if (element.id == id) return true;+ else return isParentOrSelf(element.parentNode, id);+}++function nodeValue(node) {+ var result = "";+ if (node.nodeType == 1) {+ var children = node.childNodes;+ for (var i = 0; i < children.length; ++i) {+ result += nodeValue(children[i]);+ } + }+ else if (node.nodeType == 3) {+ result = node.nodeValue;+ }+ return(result);+}++function slideLabel() {+ var slideColl = GetElementsWithClassName('*','slide');+ var list = document.getElementById('jumplist');+ smax = slideColl.length;+ for (var n = 0; n < smax; n++) {+ var obj = slideColl[n];++ var did = 'slide' + n.toString();+ obj.setAttribute('id',did);+ if (isOp) continue;++ var otext = '';+ var menu = obj.firstChild;+ if (!menu) continue; // to cope with empty slides+ while (menu && menu.nodeType == 3) {+ menu = menu.nextSibling;+ }+ if (!menu) continue; // to cope with slides with only text nodes++ var menunodes = menu.childNodes;+ for (var o = 0; o < menunodes.length; o++) {+ otext += nodeValue(menunodes[o]);+ }+ list.options[list.length] = new Option(n + ' : ' + otext, n);+ }+}++function currentSlide() {+ var cs;+ if (document.getElementById) {+ cs = document.getElementById('currentSlide');+ } else {+ cs = document.currentSlide;+ }+ cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' + + '<span id="csSep">\/<\/span> ' + + '<span id="csTotal">' + (smax-1) + '<\/span>';+ if (snum == 0) {+ cs.style.visibility = 'hidden';+ } else {+ cs.style.visibility = 'visible';+ }+}++function go(step) {+ if (document.getElementById('slideProj').disabled || step == 0) return;+ var jl = document.getElementById('jumplist');+ var cid = 'slide' + snum;+ var ce = document.getElementById(cid);+ if (incrementals[snum].length > 0) {+ for (var i = 0; i < incrementals[snum].length; i++) {+ removeClass(incrementals[snum][i], 'current');+ removeClass(incrementals[snum][i], 'incremental');+ }+ }+ if (step != 'j') {+ snum += step;+ lmax = smax - 1;+ if (snum > lmax) snum = lmax;+ if (snum < 0) snum = 0;+ } else+ snum = parseInt(jl.value);+ var nid = 'slide' + snum;+ var ne = document.getElementById(nid);+ if (!ne) {+ ne = document.getElementById('slide0');+ snum = 0;+ }+ if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;}+ if (incrementals[snum].length > 0 && incpos == 0) {+ for (var i = 0; i < incrementals[snum].length; i++) {+ if (hasClass(incrementals[snum][i], 'current'))+ incpos = i + 1;+ else+ addClass(incrementals[snum][i], 'incremental');+ }+ }+ if (incrementals[snum].length > 0 && incpos > 0)+ addClass(incrementals[snum][incpos - 1], 'current');+ ce.style.visibility = 'hidden';+ ne.style.visibility = 'visible';+ jl.selectedIndex = snum;+ currentSlide();+ number = 0;+}++function goTo(target) {+ if (target >= smax || target == snum) return;+ go(target - snum);+}++function subgo(step) {+ if (step > 0) {+ removeClass(incrementals[snum][incpos - 1],'current');+ removeClass(incrementals[snum][incpos], 'incremental');+ addClass(incrementals[snum][incpos],'current');+ incpos++;+ } else {+ incpos--;+ removeClass(incrementals[snum][incpos],'current');+ addClass(incrementals[snum][incpos], 'incremental');+ addClass(incrementals[snum][incpos - 1],'current');+ }+}++function toggle() {+ var slideColl = GetElementsWithClassName('*','slide');+ var slides = document.getElementById('slideProj');+ var outline = document.getElementById('outlineStyle');+ if (!slides.disabled) {+ slides.disabled = true;+ outline.disabled = false;+ s5mode = false;+ fontSize('1em');+ for (var n = 0; n < smax; n++) {+ var slide = slideColl[n];+ slide.style.visibility = 'visible';+ }+ } else {+ slides.disabled = false;+ outline.disabled = true;+ s5mode = true;+ fontScale();+ for (var n = 0; n < smax; n++) {+ var slide = slideColl[n];+ slide.style.visibility = 'hidden';+ }+ slideColl[snum].style.visibility = 'visible';+ }+}++function showHide(action) {+ var obj = GetElementsWithClassName('*','hideme')[0];+ switch (action) {+ case 's': obj.style.visibility = 'visible'; break;+ case 'h': obj.style.visibility = 'hidden'; break;+ case 'k':+ if (obj.style.visibility != 'visible') {+ obj.style.visibility = 'visible';+ } else {+ obj.style.visibility = 'hidden';+ }+ break;+ }+}++// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)+function keys(key) {+ if (!key) {+ key = event;+ key.which = key.keyCode;+ }+ if (key.which == 84) {+ toggle();+ return;+ }+ if (s5mode) {+ switch (key.which) {+ case 10: // return+ case 13: // enter+ if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;+ if (key.target && isParentOrSelf(key.target, 'controls')) return;+ if(number != undef) {+ goTo(number);+ break;+ }+ case 32: // spacebar+ case 34: // page down+ case 39: // rightkey+ case 40: // downkey+ if(number != undef) {+ go(number);+ } else if (!incrementals[snum] || incpos >= incrementals[snum].length) {+ go(1);+ } else {+ subgo(1);+ }+ break;+ case 33: // page up+ case 37: // leftkey+ case 38: // upkey+ if(number != undef) {+ go(-1 * number);+ } else if (!incrementals[snum] || incpos <= 0) {+ go(-1);+ } else {+ subgo(-1);+ }+ break;+ case 36: // home+ goTo(0);+ break;+ case 35: // end+ goTo(smax-1);+ break;+ case 67: // c+ showHide('k');+ break;+ }+ if (key.which < 48 || key.which > 57) {+ number = undef;+ } else {+ if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;+ if (key.target && isParentOrSelf(key.target, 'controls')) return;+ number = (((number != undef) ? number : 0) * 10) + (key.which - 48);+ }+ }+ return false;+}++function clicker(e) {+ number = undef;+ var target;+ if (window.event) {+ target = window.event.srcElement;+ e = window.event;+ } else target = e.target;+ if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true;+ if (!e.which || e.which == 1) {+ if (!incrementals[snum] || incpos >= incrementals[snum].length) {+ go(1);+ } else {+ subgo(1);+ }+ }+}++function findSlide(hash) {+ var target = null;+ var slides = GetElementsWithClassName('*','slide');+ for (var i = 0; i < slides.length; i++) {+ var targetSlide = slides[i];+ if ( (targetSlide.name && targetSlide.name == hash)+ || (targetSlide.id && targetSlide.id == hash) ) {+ target = targetSlide;+ break;+ }+ }+ while(target != null && target.nodeName != 'BODY') {+ if (hasClass(target, 'slide')) {+ return parseInt(target.id.slice(5));+ }+ target = target.parentNode;+ }+ return null;+}++function slideJump() {+ if (window.location.hash == null) return;+ var sregex = /^#slide(\d+)$/;+ var matches = sregex.exec(window.location.hash);+ var dest = null;+ if (matches != null) {+ dest = parseInt(matches[1]);+ } else {+ dest = findSlide(window.location.hash.slice(1));+ }+ if (dest != null)+ go(dest - snum);+}++function fixLinks() {+ var thisUri = window.location.href;+ thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length);+ var aelements = document.getElementsByTagName('A');+ for (var i = 0; i < aelements.length; i++) {+ var a = aelements[i].href;+ var slideID = a.match('\#slide[0-9]{1,2}');+ if ((slideID) && (slideID[0].slice(0,1) == '#')) {+ var dest = findSlide(slideID[0].slice(1));+ if (dest != null) {+ if (aelements[i].addEventListener) {+ aelements[i].addEventListener("click", new Function("e",+ "if (document.getElementById('slideProj').disabled) return;" ++ "go("+dest+" - snum); " ++ "if (e.preventDefault) e.preventDefault();"), true);+ } else if (aelements[i].attachEvent) {+ aelements[i].attachEvent("onclick", new Function("",+ "if (document.getElementById('slideProj').disabled) return;" ++ "go("+dest+" - snum); " ++ "event.returnValue = false;"));+ }+ }+ }+ }+}++function externalLinks() {+ if (!document.getElementsByTagName) return;+ var anchors = document.getElementsByTagName('a');+ for (var i=0; i<anchors.length; i++) {+ var anchor = anchors[i];+ if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) {+ anchor.target = '_blank';+ addClass(anchor,'external');+ }+ }+}++function createControls() {+ var controlsDiv = document.getElementById("controls");+ if (!controlsDiv) return;+ var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"';+ var hideDiv, hideList = '';+ if (controlVis == 'hidden') {+ hideDiv = hider;+ } else {+ hideList = hider;+ }+ controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' ++ '<div id="navLinks">' ++ '<a accesskey="t" id="toggle" href="javascript:toggle();">Ø<\/a>' ++ '<a accesskey="z" id="prev" href="javascript:go(-1);">«<\/a>' ++ '<a accesskey="x" id="next" href="javascript:go(1);">»<\/a>' ++ '<div id="navList"' + hideList + '><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' ++ '<\/div><\/form>';+ if (controlVis == 'hidden') {+ var hidden = document.getElementById('navLinks');+ } else {+ var hidden = document.getElementById('jumplist');+ }+ addClass(hidden,'hideme');+}++function fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers+ if (!s5mode) return false;+ var vScale = 22; // both yield 32 (after rounding) at 1024x768+ var hScale = 32; // perhaps should auto-calculate based on theme's declared value?+ if (window.innerHeight) {+ var vSize = window.innerHeight;+ var hSize = window.innerWidth;+ } else if (document.documentElement.clientHeight) {+ var vSize = document.documentElement.clientHeight;+ var hSize = document.documentElement.clientWidth;+ } else if (document.body.clientHeight) {+ var vSize = document.body.clientHeight;+ var hSize = document.body.clientWidth;+ } else {+ var vSize = 700; // assuming 1024x768, minus chrome and such+ var hSize = 1024; // these do not account for kiosk mode or Opera Show+ }+ var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale));+ fontSize(newSize + 'px');+ if (isGe) { // hack to counter incremental reflow bugs+ var obj = document.getElementsByTagName('body')[0];+ obj.style.display = 'none';+ obj.style.display = 'block';+ }+}++function fontSize(value) {+ if (!(s5ss = document.getElementById('s5ss'))) {+ if (!isIE) {+ document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style'));+ s5ss.setAttribute('media','screen, projection');+ s5ss.setAttribute('id','s5ss');+ } else {+ document.createStyleSheet();+ document.s5ss = document.styleSheets[document.styleSheets.length - 1];+ }+ }+ if (!isIE) {+ while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild);+ s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}'));+ } else {+ document.s5ss.addRule('body','font-size: ' + value + ' !important;');+ }+}++function notOperaFix() {+ slideCSS = document.getElementById('slideProj').href;+ var slides = document.getElementById('slideProj');+ var outline = document.getElementById('outlineStyle');+ slides.setAttribute('media','screen');+ outline.disabled = true;+ if (isGe) {+ slides.setAttribute('href','null'); // Gecko fix+ slides.setAttribute('href',slideCSS); // Gecko fix+ }+ if (isIE && document.styleSheets && document.styleSheets[0]) {+ document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)');+ document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)');+ document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)');+ }+}++function getIncrementals(obj) {+ var incrementals = new Array();+ if (!obj) + return incrementals;+ var children = obj.childNodes;+ for (var i = 0; i < children.length; i++) {+ var child = children[i];+ if (hasClass(child, 'incremental')) {+ if (child.nodeName == 'OL' || child.nodeName == 'UL') {+ removeClass(child, 'incremental');+ for (var j = 0; j < child.childNodes.length; j++) {+ if (child.childNodes[j].nodeType == 1) {+ addClass(child.childNodes[j], 'incremental');+ }+ }+ } else {+ incrementals[incrementals.length] = child;+ removeClass(child,'incremental');+ }+ }+ if (hasClass(child, 'show-first')) {+ if (child.nodeName == 'OL' || child.nodeName == 'UL') {+ removeClass(child, 'show-first');+ if (child.childNodes[isGe].nodeType == 1) {+ removeClass(child.childNodes[isGe], 'incremental');+ }+ } else {+ incrementals[incrementals.length] = child;+ }+ }+ incrementals = incrementals.concat(getIncrementals(child));+ }+ return incrementals;+}++function createIncrementals() {+ var incrementals = new Array();+ for (var i = 0; i < smax; i++) {+ incrementals[i] = getIncrementals(document.getElementById('slide'+i));+ }+ return incrementals;+}++function defaultCheck() {+ var allMetas = document.getElementsByTagName('meta');+ for (var i = 0; i< allMetas.length; i++) {+ if (allMetas[i].name == 'defaultView') {+ defaultView = allMetas[i].content;+ }+ if (allMetas[i].name == 'controlVis') {+ controlVis = allMetas[i].content;+ }+ }+}++// Key trap fix, new function body for trap()+function trap(e) {+ if (!e) {+ e = event;+ e.which = e.keyCode;+ }+ try {+ modifierKey = e.ctrlKey || e.altKey || e.metaKey;+ }+ catch(e) {+ modifierKey = false;+ }+ return modifierKey || e.which == 0;+}++function startup() {+ defaultCheck();+ if (!isOp) + createControls();+ slideLabel();+ fixLinks();+ externalLinks();+ fontScale();+ if (!isOp) {+ notOperaFix();+ incrementals = createIncrementals();+ slideJump();+ if (defaultView == 'outline') {+ toggle();+ }+ document.onkeyup = keys;+ document.onkeypress = trap;+ document.onclick = clicker;+ }+}++window.onload = startup;+window.onresize = function(){setTimeout('fontScale()', 50);}</script>+</head+ ><body+ ><div class="layout">+<div id="controls"></div>+<div id="currentSlide"></div>+<div id="header"></div>+<div id="footer">+<h1 id="july-15-2006"+ >July 15, 2006</h1+ ><h2 id="my-s5-document"+ >My S5 Document</h2+ ></div>+</div>+<div class="presentation">++<div class="slide">+<h1 id="my-s5-document-1"+ >My S5 Document</h1+ ><h3 id="sam-smith-jen-jones"+ >Sam Smith, Jen Jones</h3+ ><h4 id="july-15-2006-1"+ >July 15, 2006</h4+ ></div>+<div class="slide">+<h1 id="first-slide"+ >First slide</h1+ ><ul class="incremental"+ ><li+ >first bullet</li+ ><li+ >second bullet</li+ ></ul+ ></div>+<div class="slide">+<h1 id="math"+ >Math</h1+ ><ul class="incremental"+ ><li+ >$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</li+ ></ul+ ></div>+</div>+</body+ ></html+>+
+ tests/s5.fragment.html view
@@ -0,0 +1,15 @@+<h1 id="first-slide"+>First slide</h1+><ul+><li+ >first bullet</li+ ><li+ >second bullet</li+ ></ul+><h1 id="math"+>Math</h1+><ul+><li+ >$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</li+ ></ul+>
+ tests/s5.inserts.html view
@@ -0,0 +1,36 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html+><head+ ><title+ >My S5 Document</title+ ><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"+ /><meta name="generator" content="pandoc"+ /><meta name="author" content="Sam Smith"+ /><meta name="author" content="Jen Jones"+ /><meta name="date" content="July 15, 2006"+ /><link rel="stylesheet" href="main.css" type="text/css" media="all" />+STUFF INSERTED+</head+ ><body+ >STUFF INSERTED+<h1 class="title"+ >My S5 Document</h1+ ><h1 id="first-slide"+ >First slide</h1+ ><ul+ ><li+ >first bullet</li+ ><li+ >second bullet</li+ ></ul+ ><h1 id="math"+ >Math</h1+ ><ul+ ><li+ >$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</li+ ></ul+ >STUFF INSERTED+</body+ ></html+>+
+ tests/s5.native view
@@ -0,0 +1,9 @@+Pandoc (Meta [Str "My",Space,Str "S5",Space,Str "Document"] ["Sam Smith","Jen Jones"] "July 15, 2006")+[ Header 1 [Str "First",Space,Str "slide"]+, BulletList+ [ [ Plain [Str "first",Space,Str "bullet"] ]+ , [ Plain [Str "second",Space,Str "bullet"] ] ]+, Header 1 [Str "Math"]+, BulletList+ [ [ Plain [TeX "$\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}$"] ]+ ] ]
+ tests/tables.context view
@@ -0,0 +1,136 @@+Simple table with caption:++\placetable[here]{Demonstration of simple table syntax.}+\starttable[|rp(0.15\textwidth)|lp(0.09\textwidth)|cp(0.16\textwidth)|lp(0.13\textwidth)|]+\HL+\NC Right+\NC Left+\NC Center+\NC Default+\NC\AR+\HL+\NC 12+\NC 12+\NC 12+\NC 12+\NC\AR+\NC 123+\NC 123+\NC 123+\NC 123+\NC\AR+\NC 1+\NC 1+\NC 1+\NC 1+\NC\AR+\HL+\stoptable++Simple table without caption:++\placetable[here]{none}+\starttable[|rp(0.15\textwidth)|lp(0.09\textwidth)|cp(0.16\textwidth)|lp(0.13\textwidth)|]+\HL+\NC Right+\NC Left+\NC Center+\NC Default+\NC\AR+\HL+\NC 12+\NC 12+\NC 12+\NC 12+\NC\AR+\NC 123+\NC 123+\NC 123+\NC 123+\NC\AR+\NC 1+\NC 1+\NC 1+\NC 1+\NC\AR+\HL+\stoptable++Simple table indented two spaces:++\placetable[here]{Demonstration of simple table syntax.}+\starttable[|rp(0.15\textwidth)|lp(0.09\textwidth)|cp(0.16\textwidth)|lp(0.13\textwidth)|]+\HL+\NC Right+\NC Left+\NC Center+\NC Default+\NC\AR+\HL+\NC 12+\NC 12+\NC 12+\NC 12+\NC\AR+\NC 123+\NC 123+\NC 123+\NC 123+\NC\AR+\NC 1+\NC 1+\NC 1+\NC 1+\NC\AR+\HL+\stoptable++Multiline table with caption:++\placetable[here]{Here's the caption. It may span multiple lines.}+\starttable[|cp(0.15\textwidth)|lp(0.14\textwidth)|rp(0.16\textwidth)|lp(0.34\textwidth)|]+\HL+\NC Centered Header+\NC Left Aligned+\NC Right Aligned+\NC Default aligned+\NC\AR+\HL+\NC First+\NC row+\NC 12.0+\NC Example of a row that spans multiple lines.+\NC\AR+\NC Second+\NC row+\NC 5.0+\NC Here's another one. Note the blank line between rows.+\NC\AR+\HL+\stoptable++Multiline table without caption:++\placetable[here]{none}+\starttable[|cp(0.15\textwidth)|lp(0.14\textwidth)|rp(0.16\textwidth)|lp(0.34\textwidth)|]+\HL+\NC Centered Header+\NC Left Aligned+\NC Right Aligned+\NC Default aligned+\NC\AR+\HL+\NC First+\NC row+\NC 12.0+\NC Example of a row that spans multiple lines.+\NC\AR+\NC Second+\NC row+\NC 5.0+\NC Here's another one. Note the blank line between rows.+\NC\AR+\HL+\stoptable++
+ tests/tables.docbook view
@@ -0,0 +1,287 @@+<para>+ Simple table with caption:+</para>+<table>+ <caption>+ Demonstration of simple table syntax.+ </caption>+ <tr>+ <th align="right" style="{width: 15%;}">+ Right+ </th>+ <th align="left" style="{width: 8%;}">+ Left+ </th>+ <th align="center" style="{width: 16%;}">+ Center+ </th>+ <th align="left" style="{width: 12%;}">+ Default+ </th>+ </tr>+ <tr>+ <td align="right">+ 12+ </td>+ <td align="left">+ 12+ </td>+ <td align="center">+ 12+ </td>+ <td align="left">+ 12+ </td>+ </tr>+ <tr>+ <td align="right">+ 123+ </td>+ <td align="left">+ 123+ </td>+ <td align="center">+ 123+ </td>+ <td align="left">+ 123+ </td>+ </tr>+ <tr>+ <td align="right">+ 1+ </td>+ <td align="left">+ 1+ </td>+ <td align="center">+ 1+ </td>+ <td align="left">+ 1+ </td>+ </tr>+</table>+<para>+ Simple table without caption:+</para>+<informaltable>+ <tr>+ <th align="right" style="{width: 15%;}">+ Right+ </th>+ <th align="left" style="{width: 8%;}">+ Left+ </th>+ <th align="center" style="{width: 16%;}">+ Center+ </th>+ <th align="left" style="{width: 12%;}">+ Default+ </th>+ </tr>+ <tr>+ <td align="right">+ 12+ </td>+ <td align="left">+ 12+ </td>+ <td align="center">+ 12+ </td>+ <td align="left">+ 12+ </td>+ </tr>+ <tr>+ <td align="right">+ 123+ </td>+ <td align="left">+ 123+ </td>+ <td align="center">+ 123+ </td>+ <td align="left">+ 123+ </td>+ </tr>+ <tr>+ <td align="right">+ 1+ </td>+ <td align="left">+ 1+ </td>+ <td align="center">+ 1+ </td>+ <td align="left">+ 1+ </td>+ </tr>+</informaltable>+<para>+ Simple table indented two spaces:+</para>+<table>+ <caption>+ Demonstration of simple table syntax.+ </caption>+ <tr>+ <th align="right" style="{width: 15%;}">+ Right+ </th>+ <th align="left" style="{width: 8%;}">+ Left+ </th>+ <th align="center" style="{width: 16%;}">+ Center+ </th>+ <th align="left" style="{width: 12%;}">+ Default+ </th>+ </tr>+ <tr>+ <td align="right">+ 12+ </td>+ <td align="left">+ 12+ </td>+ <td align="center">+ 12+ </td>+ <td align="left">+ 12+ </td>+ </tr>+ <tr>+ <td align="right">+ 123+ </td>+ <td align="left">+ 123+ </td>+ <td align="center">+ 123+ </td>+ <td align="left">+ 123+ </td>+ </tr>+ <tr>+ <td align="right">+ 1+ </td>+ <td align="left">+ 1+ </td>+ <td align="center">+ 1+ </td>+ <td align="left">+ 1+ </td>+ </tr>+</table>+<para>+ Multiline table with caption:+</para>+<table>+ <caption>+ Here's the caption. It may span multiple lines.+ </caption>+ <tr>+ <th align="center" style="{width: 15%;}">+ Centered Header+ </th>+ <th align="left" style="{width: 13%;}">+ Left Aligned+ </th>+ <th align="right" style="{width: 16%;}">+ Right Aligned+ </th>+ <th align="left" style="{width: 33%;}">+ Default aligned+ </th>+ </tr>+ <tr>+ <td align="center">+ First+ </td>+ <td align="left">+ row+ </td>+ <td align="right">+ 12.0+ </td>+ <td align="left">+ Example of a row that spans multiple lines.+ </td>+ </tr>+ <tr>+ <td align="center">+ Second+ </td>+ <td align="left">+ row+ </td>+ <td align="right">+ 5.0+ </td>+ <td align="left">+ Here's another one. Note the blank line between rows.+ </td>+ </tr>+</table>+<para>+ Multiline table without caption:+</para>+<informaltable>+ <tr>+ <th align="center" style="{width: 15%;}">+ Centered Header+ </th>+ <th align="left" style="{width: 13%;}">+ Left Aligned+ </th>+ <th align="right" style="{width: 16%;}">+ Right Aligned+ </th>+ <th align="left" style="{width: 33%;}">+ Default aligned+ </th>+ </tr>+ <tr>+ <td align="center">+ First+ </td>+ <td align="left">+ row+ </td>+ <td align="right">+ 12.0+ </td>+ <td align="left">+ Example of a row that spans multiple lines.+ </td>+ </tr>+ <tr>+ <td align="center">+ Second+ </td>+ <td align="left">+ row+ </td>+ <td align="right">+ 5.0+ </td>+ <td align="left">+ Here's another one. Note the blank line between rows.+ </td>+ </tr>+</informaltable>+
+ tests/tables.html view
@@ -0,0 +1,207 @@+<p+>Simple table with caption:</p+><table+><caption+ >Demonstration of simple table syntax.</caption+ ><tr+ ><th align="right" style="{width: 15%;}"+ >Right</th+ ><th align="left" style="{width: 8%;}"+ >Left</th+ ><th align="center" style="{width: 16%;}"+ >Center</th+ ><th align="left" style="{width: 12%;}"+ >Default</th+ ></tr+ ><tr+ ><td align="right"+ >12</td+ ><td align="left"+ >12</td+ ><td align="center"+ >12</td+ ><td align="left"+ >12</td+ ></tr+ ><tr+ ><td align="right"+ >123</td+ ><td align="left"+ >123</td+ ><td align="center"+ >123</td+ ><td align="left"+ >123</td+ ></tr+ ><tr+ ><td align="right"+ >1</td+ ><td align="left"+ >1</td+ ><td align="center"+ >1</td+ ><td align="left"+ >1</td+ ></tr+ ></table+><p+>Simple table without caption:</p+><table+><tr+ ><th align="right" style="{width: 15%;}"+ >Right</th+ ><th align="left" style="{width: 8%;}"+ >Left</th+ ><th align="center" style="{width: 16%;}"+ >Center</th+ ><th align="left" style="{width: 12%;}"+ >Default</th+ ></tr+ ><tr+ ><td align="right"+ >12</td+ ><td align="left"+ >12</td+ ><td align="center"+ >12</td+ ><td align="left"+ >12</td+ ></tr+ ><tr+ ><td align="right"+ >123</td+ ><td align="left"+ >123</td+ ><td align="center"+ >123</td+ ><td align="left"+ >123</td+ ></tr+ ><tr+ ><td align="right"+ >1</td+ ><td align="left"+ >1</td+ ><td align="center"+ >1</td+ ><td align="left"+ >1</td+ ></tr+ ></table+><p+>Simple table indented two spaces:</p+><table+><caption+ >Demonstration of simple table syntax.</caption+ ><tr+ ><th align="right" style="{width: 15%;}"+ >Right</th+ ><th align="left" style="{width: 8%;}"+ >Left</th+ ><th align="center" style="{width: 16%;}"+ >Center</th+ ><th align="left" style="{width: 12%;}"+ >Default</th+ ></tr+ ><tr+ ><td align="right"+ >12</td+ ><td align="left"+ >12</td+ ><td align="center"+ >12</td+ ><td align="left"+ >12</td+ ></tr+ ><tr+ ><td align="right"+ >123</td+ ><td align="left"+ >123</td+ ><td align="center"+ >123</td+ ><td align="left"+ >123</td+ ></tr+ ><tr+ ><td align="right"+ >1</td+ ><td align="left"+ >1</td+ ><td align="center"+ >1</td+ ><td align="left"+ >1</td+ ></tr+ ></table+><p+>Multiline table with caption:</p+><table+><caption+ >Here's the caption. It may span multiple lines.</caption+ ><tr+ ><th align="center" style="{width: 15%;}"+ >Centered Header</th+ ><th align="left" style="{width: 13%;}"+ >Left Aligned</th+ ><th align="right" style="{width: 16%;}"+ >Right Aligned</th+ ><th align="left" style="{width: 33%;}"+ >Default aligned</th+ ></tr+ ><tr+ ><td align="center"+ >First</td+ ><td align="left"+ >row</td+ ><td align="right"+ >12.0</td+ ><td align="left"+ >Example of a row that spans multiple lines.</td+ ></tr+ ><tr+ ><td align="center"+ >Second</td+ ><td align="left"+ >row</td+ ><td align="right"+ >5.0</td+ ><td align="left"+ >Here's another one. Note the blank line between rows.</td+ ></tr+ ></table+><p+>Multiline table without caption:</p+><table+><tr+ ><th align="center" style="{width: 15%;}"+ >Centered Header</th+ ><th align="left" style="{width: 13%;}"+ >Left Aligned</th+ ><th align="right" style="{width: 16%;}"+ >Right Aligned</th+ ><th align="left" style="{width: 33%;}"+ >Default aligned</th+ ></tr+ ><tr+ ><td align="center"+ >First</td+ ><td align="left"+ >row</td+ ><td align="right"+ >12.0</td+ ><td align="left"+ >Example of a row that spans multiple lines.</td+ ></tr+ ><tr+ ><td align="center"+ >Second</td+ ><td align="left"+ >row</td+ ><td align="right"+ >5.0</td+ ><td align="left"+ >Here's another one. Note the blank line between rows.</td+ ></tr+ ></table+>
+ tests/tables.latex view
@@ -0,0 +1,140 @@+Simple table with caption:++\begin{table}[h]+\begin{center}+\begin{tabular}{>{\PBS\raggedleft\hspace{0pt}}p{0.15\columnwidth}>{\PBS\raggedright\hspace{0pt}}p{0.09\columnwidth}>{\PBS\centering\hspace{0pt}}p{0.16\columnwidth}>{\PBS\raggedright\hspace{0pt}}p{0.13\columnwidth}}+Right+ & Left+ & Center+ & Default+\\+\hline+12+ & 12+ & 12+ & 12+\\+123+ & 123+ & 123+ & 123+\\+1+ & 1+ & 1+ & 1+\\+\end{tabular}+\end{center}+\caption{Demonstration of simple table syntax.}+\end{table}++Simple table without caption:++\begin{center}+\begin{tabular}{>{\PBS\raggedleft\hspace{0pt}}p{0.15\columnwidth}>{\PBS\raggedright\hspace{0pt}}p{0.09\columnwidth}>{\PBS\centering\hspace{0pt}}p{0.16\columnwidth}>{\PBS\raggedright\hspace{0pt}}p{0.13\columnwidth}}+Right+ & Left+ & Center+ & Default+\\+\hline+12+ & 12+ & 12+ & 12+\\+123+ & 123+ & 123+ & 123+\\+1+ & 1+ & 1+ & 1+\\+\end{tabular}+\end{center}++Simple table indented two spaces:++\begin{table}[h]+\begin{center}+\begin{tabular}{>{\PBS\raggedleft\hspace{0pt}}p{0.15\columnwidth}>{\PBS\raggedright\hspace{0pt}}p{0.09\columnwidth}>{\PBS\centering\hspace{0pt}}p{0.16\columnwidth}>{\PBS\raggedright\hspace{0pt}}p{0.13\columnwidth}}+Right+ & Left+ & Center+ & Default+\\+\hline+12+ & 12+ & 12+ & 12+\\+123+ & 123+ & 123+ & 123+\\+1+ & 1+ & 1+ & 1+\\+\end{tabular}+\end{center}+\caption{Demonstration of simple table syntax.}+\end{table}++Multiline table with caption:++\begin{table}[h]+\begin{center}+\begin{tabular}{>{\PBS\centering\hspace{0pt}}p{0.15\columnwidth}>{\PBS\raggedright\hspace{0pt}}p{0.14\columnwidth}>{\PBS\raggedleft\hspace{0pt}}p{0.16\columnwidth}>{\PBS\raggedright\hspace{0pt}}p{0.34\columnwidth}}+Centered Header+ & Left Aligned+ & Right Aligned+ & Default aligned+\\+\hline+First+ & row+ & 12.0+ & Example of a row that spans multiple lines.+\\+Second+ & row+ & 5.0+ & Here's another one. Note the blank line between rows.+\\+\end{tabular}+\end{center}+\caption{Here's the caption. It may span multiple lines.}+\end{table}++Multiline table without caption:++\begin{center}+\begin{tabular}{>{\PBS\centering\hspace{0pt}}p{0.15\columnwidth}>{\PBS\raggedright\hspace{0pt}}p{0.14\columnwidth}>{\PBS\raggedleft\hspace{0pt}}p{0.16\columnwidth}>{\PBS\raggedright\hspace{0pt}}p{0.34\columnwidth}}+Centered Header+ & Left Aligned+ & Right Aligned+ & Default aligned+\\+\hline+First+ & row+ & 12.0+ & Example of a row that spans multiple lines.+\\+Second+ & row+ & 5.0+ & Here's another one. Note the blank line between rows.+\\+\end{tabular}+\end{center}++
+ tests/tables.man view
@@ -0,0 +1,205 @@+.PP+Simple table with caption:+.PP+Demonstration of simple table syntax\.+.TS+tab(@);+rw(10.50n) lw(6.13n) cw(11.38n) lw(8.75n).+T{+Right+T}@T{+Left+T}@T{+Center+T}@T{+Default+T}+_+T{+12+T}@T{+12+T}@T{+12+T}@T{+12+T}+T{+123+T}@T{+123+T}@T{+123+T}@T{+123+T}+T{+1+T}@T{+1+T}@T{+1+T}@T{+1+T}+.TE+.PP+Simple table without caption:+.PP+.TS+tab(@);+rw(10.50n) lw(6.13n) cw(11.38n) lw(8.75n).+T{+Right+T}@T{+Left+T}@T{+Center+T}@T{+Default+T}+_+T{+12+T}@T{+12+T}@T{+12+T}@T{+12+T}+T{+123+T}@T{+123+T}@T{+123+T}@T{+123+T}+T{+1+T}@T{+1+T}@T{+1+T}@T{+1+T}+.TE+.PP+Simple table indented two spaces:+.PP+Demonstration of simple table syntax\.+.TS+tab(@);+rw(10.50n) lw(6.13n) cw(11.38n) lw(8.75n).+T{+Right+T}@T{+Left+T}@T{+Center+T}@T{+Default+T}+_+T{+12+T}@T{+12+T}@T{+12+T}@T{+12+T}+T{+123+T}@T{+123+T}@T{+123+T}@T{+123+T}+T{+1+T}@T{+1+T}@T{+1+T}@T{+1+T}+.TE+.PP+Multiline table with caption:+.PP+Here\[aq]s the caption\. It may span multiple lines\.+.TS+tab(@);+cw(10.50n) lw(9.63n) rw(11.38n) lw(23.63n).+T{+Centered Header+T}@T{+Left Aligned+T}@T{+Right Aligned+T}@T{+Default aligned+T}+_+T{+First+T}@T{+row+T}@T{+12\.0+T}@T{+Example of a row that spans multiple lines\.+T}+T{+Second+T}@T{+row+T}@T{+5\.0+T}@T{+Here\[aq]s another one\. Note the blank line between rows\.+T}+.TE+.PP+Multiline table without caption:+.PP+.TS+tab(@);+cw(10.50n) lw(9.63n) rw(11.38n) lw(23.63n).+T{+Centered Header+T}@T{+Left Aligned+T}@T{+Right Aligned+T}@T{+Default aligned+T}+_+T{+First+T}@T{+row+T}@T{+12\.0+T}@T{+Example of a row that spans multiple lines\.+T}+T{+Second+T}@T{+row+T}@T{+5\.0+T}@T{+Here\[aq]s another one\. Note the blank line between rows\.+T}+.TE
+ tests/tables.markdown view
@@ -0,0 +1,60 @@+Simple table with caption:++ Right Left Center Default+ ----------- ------ ------------ ---------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1+ + Table: Demonstration of simple table syntax.++Simple table without caption:++ Right Left Center Default+ ----------- ------ ------------ ---------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1++Simple table indented two spaces:++ Right Left Center Default+ ----------- ------ ------------ ---------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1+ + Table: Demonstration of simple table syntax.++Multiline table with caption:++ --------------------------------------------------------------+ Centered Left Right Default aligned+ Header Aligned Aligned+ ----------- ---------- ------------ --------------------------+ First row 12.0 Example of a row that+ spans multiple lines.+ + Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ --------------------------------------------------------------+ + Table: Here's the caption. It may span multiple lines.++Multiline table without caption:++ --------------------------------------------------------------+ Centered Left Right Default aligned+ Header Aligned Aligned+ ----------- ---------- ------------ --------------------------+ First row 12.0 Example of a row that+ spans multiple lines.+ + Second row 5.0 Here's another one. Note+ the blank line between+ rows.+ --------------------------------------------------------------+++
+ tests/tables.native view
@@ -0,0 +1,84 @@+Pandoc (Meta [] [] "")+[ Para [Str "Simple",Space,Str "table",Space,Str "with",Space,Str "caption:"]+, Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax",Str "."] [AlignRight,AlignLeft,AlignCenter,AlignDefault] [0.15,8.75e-2,0.1625,0.125]+ [ [ Plain [Str "Right"] ]+ , [ Plain [Str "Left"] ]+ , [ Plain [Str "Center"] ]+ , [ Plain [Str "Default"] ] ] [+ [ [ Plain [Str "12"] ]+ , [ Plain [Str "12"] ]+ , [ Plain [Str "12"] ]+ , [ Plain [Str "12"] ] ],+ [ [ Plain [Str "123"] ]+ , [ Plain [Str "123"] ]+ , [ Plain [Str "123"] ]+ , [ Plain [Str "123"] ] ],+ [ [ Plain [Str "1"] ]+ , [ Plain [Str "1"] ]+ , [ Plain [Str "1"] ]+ , [ Plain [Str "1"] ] ] ]+, Para [Str "Simple",Space,Str "table",Space,Str "without",Space,Str "caption:"]+, Table [] [AlignRight,AlignLeft,AlignCenter,AlignDefault] [0.15,8.75e-2,0.1625,0.125]+ [ [ Plain [Str "Right"] ]+ , [ Plain [Str "Left"] ]+ , [ Plain [Str "Center"] ]+ , [ Plain [Str "Default"] ] ] [+ [ [ Plain [Str "12"] ]+ , [ Plain [Str "12"] ]+ , [ Plain [Str "12"] ]+ , [ Plain [Str "12"] ] ],+ [ [ Plain [Str "123"] ]+ , [ Plain [Str "123"] ]+ , [ Plain [Str "123"] ]+ , [ Plain [Str "123"] ] ],+ [ [ Plain [Str "1"] ]+ , [ Plain [Str "1"] ]+ , [ Plain [Str "1"] ]+ , [ Plain [Str "1"] ] ] ]+, Para [Str "Simple",Space,Str "table",Space,Str "indented",Space,Str "two",Space,Str "spaces:"]+, Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax",Str "."] [AlignRight,AlignLeft,AlignCenter,AlignDefault] [0.15,8.75e-2,0.1625,0.125]+ [ [ Plain [Str "Right"] ]+ , [ Plain [Str "Left"] ]+ , [ Plain [Str "Center"] ]+ , [ Plain [Str "Default"] ] ] [+ [ [ Plain [Str "12"] ]+ , [ Plain [Str "12"] ]+ , [ Plain [Str "12"] ]+ , [ Plain [Str "12"] ] ],+ [ [ Plain [Str "123"] ]+ , [ Plain [Str "123"] ]+ , [ Plain [Str "123"] ]+ , [ Plain [Str "123"] ] ],+ [ [ Plain [Str "1"] ]+ , [ Plain [Str "1"] ]+ , [ Plain [Str "1"] ]+ , [ Plain [Str "1"] ] ] ]+, Para [Str "Multiline",Space,Str "table",Space,Str "with",Space,Str "caption:"]+, Table [Str "Here",Str "'",Str "s",Space,Str "the",Space,Str "caption",Str ".",Space,Str "It",Space,Str "may",Space,Str "span",Space,Str "multiple",Space,Str "lines",Str "."] [AlignCenter,AlignLeft,AlignRight,AlignLeft] [0.15,0.1375,0.1625,0.3375]+ [ [ Plain [Str "Centered",Space,Str "Header"] ]+ , [ Plain [Str "Left",Space,Str "Aligned"] ]+ , [ Plain [Str "Right",Space,Str "Aligned"] ]+ , [ Plain [Str "Default",Space,Str "aligned"] ] ] [+ [ [ Plain [Str "First"] ]+ , [ Plain [Str "row"] ]+ , [ Plain [Str "12",Str ".",Str "0"] ]+ , [ Plain [Str "Example",Space,Str "of",Space,Str "a",Space,Str "row",Space,Str "that",Space,Str "spans",Space,Str "multiple",Space,Str "lines",Str "."] ] ],+ [ [ Plain [Str "Second"] ]+ , [ Plain [Str "row"] ]+ , [ Plain [Str "5",Str ".",Str "0"] ]+ , [ Plain [Str "Here",Str "'",Str "s",Space,Str "another",Space,Str "one",Str ".",Space,Str "Note",Space,Str "the",Space,Str "blank",Space,Str "line",Space,Str "between",Space,Str "rows",Str "."] ] ] ]+, Para [Str "Multiline",Space,Str "table",Space,Str "without",Space,Str "caption:"]+, Table [] [AlignCenter,AlignLeft,AlignRight,AlignLeft] [0.15,0.1375,0.1625,0.3375]+ [ [ Plain [Str "Centered",Space,Str "Header"] ]+ , [ Plain [Str "Left",Space,Str "Aligned"] ]+ , [ Plain [Str "Right",Space,Str "Aligned"] ]+ , [ Plain [Str "Default",Space,Str "aligned"] ] ] [+ [ [ Plain [Str "First"] ]+ , [ Plain [Str "row"] ]+ , [ Plain [Str "12",Str ".",Str "0"] ]+ , [ Plain [Str "Example",Space,Str "of",Space,Str "a",Space,Str "row",Space,Str "that",Space,Str "spans",Space,Str "multiple",Space,Str "lines",Str "."] ] ],+ [ [ Plain [Str "Second"] ]+ , [ Plain [Str "row"] ]+ , [ Plain [Str "5",Str ".",Str "0"] ]+ , [ Plain [Str "Here",Str "'",Str "s",Space,Str "another",Space,Str "one",Str ".",Space,Str "Note",Space,Str "the",Space,Str "blank",Space,Str "line",Space,Str "between",Space,Str "rows",Str "."] ] ] ] ]+
+ tests/tables.rst view
@@ -0,0 +1,71 @@+Simple table with caption:+++-------------+--------+--------------+-----------++| Right | Left | Center | Default |++=============+========+==============+===========++| 12 | 12 | 12 | 12 |++-------------+--------+--------------+-----------++| 123 | 123 | 123 | 123 |++-------------+--------+--------------+-----------++| 1 | 1 | 1 | 1 |++-------------+--------+--------------+-----------+++Table: Demonstration of simple table syntax.++Simple table without caption:+++-------------+--------+--------------+-----------++| Right | Left | Center | Default |++=============+========+==============+===========++| 12 | 12 | 12 | 12 |++-------------+--------+--------------+-----------++| 123 | 123 | 123 | 123 |++-------------+--------+--------------+-----------++| 1 | 1 | 1 | 1 |++-------------+--------+--------------+-----------+++Simple table indented two spaces:+++-------------+--------+--------------+-----------++| Right | Left | Center | Default |++=============+========+==============+===========++| 12 | 12 | 12 | 12 |++-------------+--------+--------------+-----------++| 123 | 123 | 123 | 123 |++-------------+--------+--------------+-----------++| 1 | 1 | 1 | 1 |++-------------+--------+--------------+-----------+++Table: Demonstration of simple table syntax.++Multiline table with caption:+++-------------+------------+--------------+----------------------------++| Centered | Left | Right | Default aligned |+| Header | Aligned | Aligned | |++=============+============+==============+============================++| First | row | 12.0 | Example of a row that |+| | | | spans multiple lines. |++-------------+------------+--------------+----------------------------++| Second | row | 5.0 | Here's another one. Note |+| | | | the blank line between |+| | | | rows. |++-------------+------------+--------------+----------------------------+++Table: Here's the caption. It may span multiple lines.++Multiline table without caption:+++-------------+------------+--------------+----------------------------++| Centered | Left | Right | Default aligned |+| Header | Aligned | Aligned | |++=============+============+==============+============================++| First | row | 12.0 | Example of a row that |+| | | | spans multiple lines. |++-------------+------------+--------------+----------------------------++| Second | row | 5.0 | Here's another one. Note |+| | | | the blank line between |+| | | | rows. |++-------------+------------+--------------+----------------------------+++
+ tests/tables.rtf view
@@ -0,0 +1,281 @@+{\pard \ql \f0 \sa180 \li0 \fi0 Simple table with caption:\par}+{+\trowd \trgaph120+\clbrdrb\brdrs\cellx1296\clbrdrb\brdrs\cellx2052\clbrdrb\brdrs\cellx3456\clbrdrb\brdrs\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 Right\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Left\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 Center\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Default\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2052\cellx3456\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 12\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 12\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 12\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 12\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2052\cellx3456\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 123\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 123\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 123\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 123\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2052\cellx3456\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 1\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 1\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 1\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 1\par}+\cell}+}+\intbl\row}+{\pard \ql \f0 \sa180 \li0 \fi0 Demonstration of simple table syntax.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Simple table without caption:\par}+{+\trowd \trgaph120+\clbrdrb\brdrs\cellx1296\clbrdrb\brdrs\cellx2052\clbrdrb\brdrs\cellx3456\clbrdrb\brdrs\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 Right\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Left\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 Center\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Default\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2052\cellx3456\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 12\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 12\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 12\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 12\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2052\cellx3456\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 123\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 123\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 123\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 123\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2052\cellx3456\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 1\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 1\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 1\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 1\par}+\cell}+}+\intbl\row}+{\pard \ql \f0 \sa180 \li0 \fi0 \par}+{\pard \ql \f0 \sa180 \li0 \fi0 Simple table indented two spaces:\par}+{+\trowd \trgaph120+\clbrdrb\brdrs\cellx1296\clbrdrb\brdrs\cellx2052\clbrdrb\brdrs\cellx3456\clbrdrb\brdrs\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 Right\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Left\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 Center\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Default\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2052\cellx3456\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 12\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 12\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 12\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 12\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2052\cellx3456\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 123\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 123\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 123\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 123\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2052\cellx3456\cellx4536+\trkeep\intbl+{+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 1\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 1\par}+\cell}+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 1\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 1\par}+\cell}+}+\intbl\row}+{\pard \ql \f0 \sa180 \li0 \fi0 Demonstration of simple table syntax.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Multiline table with caption:\par}+{+\trowd \trgaph120+\clbrdrb\brdrs\cellx1296\clbrdrb\brdrs\cellx2484\clbrdrb\brdrs\cellx3888\clbrdrb\brdrs\cellx6804+\trkeep\intbl+{+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 Centered Header\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Left Aligned\par}+\cell}+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 Right Aligned\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Default aligned\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2484\cellx3888\cellx6804+\trkeep\intbl+{+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 First\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 row\par}+\cell}+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 12.0\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Example of a row that spans multiple lines.\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2484\cellx3888\cellx6804+\trkeep\intbl+{+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 Second\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 row\par}+\cell}+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 5.0\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Here's another one. Note the blank line between rows.\par}+\cell}+}+\intbl\row}+{\pard \ql \f0 \sa180 \li0 \fi0 Here's the caption. It may span multiple lines.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Multiline table without caption:\par}+{+\trowd \trgaph120+\clbrdrb\brdrs\cellx1296\clbrdrb\brdrs\cellx2484\clbrdrb\brdrs\cellx3888\clbrdrb\brdrs\cellx6804+\trkeep\intbl+{+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 Centered Header\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Left Aligned\par}+\cell}+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 Right Aligned\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Default aligned\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2484\cellx3888\cellx6804+\trkeep\intbl+{+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 First\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 row\par}+\cell}+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 12.0\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Example of a row that spans multiple lines.\par}+\cell}+}+\intbl\row}+{+\trowd \trgaph120+\cellx1296\cellx2484\cellx3888\cellx6804+\trkeep\intbl+{+{\intbl {\pard \qc \f0 \sa0 \li0 \fi0 Second\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 row\par}+\cell}+{\intbl {\pard \qr \f0 \sa0 \li0 \fi0 5.0\par}+\cell}+{\intbl {\pard \ql \f0 \sa0 \li0 \fi0 Here's another one. Note the blank line between rows.\par}+\cell}+}+\intbl\row}+{\pard \ql \f0 \sa180 \li0 \fi0 \par}+
+ tests/tables.txt view
@@ -0,0 +1,57 @@+Simple table with caption:++ Right Left Center Default +------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 ++Table: Demonstration of simple table syntax.++Simple table without caption:++ Right Left Center Default +------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 ++Simple table indented two spaces:++ Right Left Center Default + ------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 ++ Table: Demonstration of simple table syntax.++Multiline table with caption:++---------------------------------------------------------------+ Centered Left Right+ Header Aligned Aligned Default aligned+---------- --------- ----------- ---------------------------+ First row 12.0 Example of a row that spans+ multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between rows.+---------------------------------------------------------------++Table: Here's the caption.+It may span multiple lines.++Multiline table without caption:++---------------------------------------------------------------+ Centered Left Right+ Header Aligned Aligned Default aligned+---------- --------- ----------- ---------------------------+ First row 12.0 Example of a row that spans+ multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between rows.+---------------------------------------------------------------+
+ tests/testsuite.native view
@@ -0,0 +1,398 @@+Pandoc (Meta [Str "Pandoc",Space,Str "Test",Space,Str "Suite"] ["John MacFarlane","Anonymous"] "July 17, 2006")+[ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc",Str ".",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber",Apostrophe,Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite",Str "."]+, HorizontalRule+, Header 1 [Str "Headers"]+, Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embedded",Space,Str "link"] ("/url","")]+, Header 3 [Str "Level",Space,Str "3",Space,Str "with",Space,Emph [Str "emphasis"]]+, Header 4 [Str "Level",Space,Str "4"]+, Header 5 [Str "Level",Space,Str "5"]+, Header 1 [Str "Level",Space,Str "1"]+, Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Emph [Str "emphasis"]]+, Header 3 [Str "Level",Space,Str "3"]+, Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]+, Header 2 [Str "Level",Space,Str "2"]+, Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]+, HorizontalRule+, Header 1 [Str "Paragraphs"]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph",Str "."]+, Para [Str "In",Space,Str "Markdown",Space,Str "1",Str ".",Str "0",Str ".",Str "0",Space,Str "and",Space,Str "earlier",Str ".",Space,Str "Version",Space,Str "8",Str ".",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item",Str ".",Space,Str "Because",Space,Str "a",Space,Str "hard",Str "-",Str "wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item",Str "."]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet",Str ".",Space,Str "*",Space,Str "criminey",Str "."]+, Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break",LineBreak,Str "here",Str "."]+, HorizontalRule+, Header 1 [Str "Block",Space,Str "Quotes"]+, Para [Str "E",Str "-",Str "mail",Space,Str "style:"]+, BlockQuote+ [ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote",Str ".",Space,Str "It",Space,Str "is",Space,Str "pretty",Space,Str "short",Str "."] ]++, BlockQuote+ [ Para [Str "Code",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote:"]+ , CodeBlock "sub status {\n print \"working\";\n}"+ , Para [Str "A",Space,Str "list:"]+ , OrderedList (1,Decimal,Period)+ [ [ Plain [Str "item",Space,Str "one"] ]+ , [ Plain [Str "item",Space,Str "two"] ] ]+ , Para [Str "Nested",Space,Str "block",Space,Str "quotes:"]+ , BlockQuote+ [ Para [Str "nested"] ]+ + , BlockQuote+ [ Para [Str "nested"] ]+ ]+, Para [Str "This",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "block",Space,Str "quote:",Space,Str "2",Space,Str ">",Space,Str "1",Str "."]+, Para [Str "Box",Str "-",Str "style:"]+, BlockQuote+ [ Para [Str "Example:"]+ , CodeBlock "sub status {\n print \"working\";\n}" ]+, BlockQuote+ [ OrderedList (1,Decimal,Period)+ [ [ Plain [Str "do",Space,Str "laundry"] ]+ , [ Plain [Str "take",Space,Str "out",Space,Str "the",Space,Str "trash"] ] ] ]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "nested",Space,Str "one:"]+, BlockQuote+ [ Para [Str "Joe",Space,Str "said:"]+ , BlockQuote+ [ Para [Str "Don",Apostrophe,Str "t",Space,Str "quote",Space,Str "me",Str "."] ]+ ]+, Para [Str "And",Space,Str "a",Space,Str "following",Space,Str "paragraph",Str "."]+, HorizontalRule+, Header 1 [Str "Code",Space,Str "Blocks"]+, Para [Str "Code:"]+, CodeBlock "---- (should be four hyphens)\n\nsub status {\n print \"working\";\n}\n\nthis code block is indented by one tab"+, Para [Str "And:"]+, CodeBlock " this code block is indented by two tabs\n\nThese should not be escaped: \\$ \\\\ \\> \\[ \\{"+, HorizontalRule+, Header 1 [Str "Lists"]+, Header 2 [Str "Unordered"]+, Para [Str "Asterisks",Space,Str "tight:"]+, BulletList+ [ [ Plain [Str "asterisk",Space,Str "1"] ]+ , [ Plain [Str "asterisk",Space,Str "2"] ]+ , [ Plain [Str "asterisk",Space,Str "3"] ] ]+, Para [Str "Asterisks",Space,Str "loose:"]+, BulletList+ [ [ Para [Str "asterisk",Space,Str "1"] ]+ , [ Para [Str "asterisk",Space,Str "2"] ]+ , [ Para [Str "asterisk",Space,Str "3"] ] ]+, Para [Str "Pluses",Space,Str "tight:"]+, BulletList+ [ [ Plain [Str "Plus",Space,Str "1"] ]+ , [ Plain [Str "Plus",Space,Str "2"] ]+ , [ Plain [Str "Plus",Space,Str "3"] ] ]+, Para [Str "Pluses",Space,Str "loose:"]+, BulletList+ [ [ Para [Str "Plus",Space,Str "1"] ]+ , [ Para [Str "Plus",Space,Str "2"] ]+ , [ Para [Str "Plus",Space,Str "3"] ] ]+, Para [Str "Minuses",Space,Str "tight:"]+, BulletList+ [ [ Plain [Str "Minus",Space,Str "1"] ]+ , [ Plain [Str "Minus",Space,Str "2"] ]+ , [ Plain [Str "Minus",Space,Str "3"] ] ]+, Para [Str "Minuses",Space,Str "loose:"]+, BulletList+ [ [ Para [Str "Minus",Space,Str "1"] ]+ , [ Para [Str "Minus",Space,Str "2"] ]+ , [ Para [Str "Minus",Space,Str "3"] ] ]+, Header 2 [Str "Ordered"]+, Para [Str "Tight:"]+, OrderedList (1,Decimal,Period)+ [ [ Plain [Str "First"] ]+ , [ Plain [Str "Second"] ]+ , [ Plain [Str "Third"] ] ]+, Para [Str "and:"]+, OrderedList (1,Decimal,Period)+ [ [ Plain [Str "One"] ]+ , [ Plain [Str "Two"] ]+ , [ Plain [Str "Three"] ] ]+, Para [Str "Loose",Space,Str "using",Space,Str "tabs:"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "First"] ]+ , [ Para [Str "Second"] ]+ , [ Para [Str "Third"] ] ]+, Para [Str "and",Space,Str "using",Space,Str "spaces:"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "One"] ]+ , [ Para [Str "Two"] ]+ , [ Para [Str "Three"] ] ]+, Para [Str "Multiple",Space,Str "paragraphs:"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "Item",Space,Str "1,",Space,Str "graf",Space,Str "one",Str "."]+ , Para [Str "Item",Space,Str "1",Str ".",Space,Str "graf",Space,Str "two",Str ".",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog",Apostrophe,Str "s",Space,Str "back",Str "."] ], [ Para [Str "Item",Space,Str "2",Str "."] ]+ , [ Para [Str "Item",Space,Str "3",Str "."] ] ]+, Header 2 [Str "Nested"]+, BulletList+ [ [ Plain [Str "Tab"]+ , BulletList+ [ [ Plain [Str "Tab"]+ , BulletList+ [ [ Plain [Str "Tab"] ]+ ] ] ] ] ]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "another:"]+, OrderedList (1,Decimal,Period)+ [ [ Plain [Str "First"] ]+ , [ Plain [Str "Second:"]+ , BulletList+ [ [ Plain [Str "Fee"] ]+ , [ Plain [Str "Fie"] ]+ , [ Plain [Str "Foe"] ] ] ], [ Plain [Str "Third"] ] ]+, Para [Str "Same",Space,Str "thing",Space,Str "but",Space,Str "with",Space,Str "paragraphs:"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "First"] ]+ , [ Para [Str "Second:"]+ , BulletList+ [ [ Plain [Str "Fee"] ]+ , [ Plain [Str "Fie"] ]+ , [ Plain [Str "Foe"] ] ] ], [ Para [Str "Third"] ] ]+, Header 2 [Str "Tabs",Space,Str "and",Space,Str "spaces"]+, BulletList+ [ [ Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"] ]+ , [ Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"]+ , BulletList+ [ [ Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"] ]+ , [ Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"] ] ] ] ]+, Header 2 [Str "Fancy",Space,Str "list",Space,Str "markers"]+, OrderedList (2,Decimal,TwoParens)+ [ [ Plain [Str "begins",Space,Str "with",Space,Str "2"] ]+ , [ Para [Str "and",Space,Str "now",Space,Str "3"]+ , Para [Str "with",Space,Str "a",Space,Str "continuation"]+ , OrderedList (4,LowerRoman,Period)+ [ [ Plain [Str "sublist",Space,Str "with",Space,Str "roman",Space,Str "numerals,",Space,Str "starting",Space,Str "with",Space,Str "4"] ]+ , [ Plain [Str "more",Space,Str "items"]+ , OrderedList (1,UpperAlpha,TwoParens)+ [ [ Plain [Str "a",Space,Str "subsublist"] ]+ , [ Plain [Str "a",Space,Str "subsublist"] ] ] ] ] ] ]+, Para [Str "Nesting:"]+, OrderedList (1,UpperAlpha,Period)+ [ [ Plain [Str "Upper",Space,Str "Alpha"]+ , OrderedList (1,UpperRoman,Period)+ [ [ Plain [Str "Upper",Space,Str "Roman",Str "."]+ , OrderedList (6,Decimal,TwoParens)+ [ [ Plain [Str "Decimal",Space,Str "start",Space,Str "with",Space,Str "6"]+ , OrderedList (3,LowerAlpha,OneParen)+ [ [ Plain [Str "Lower",Space,Str "alpha",Space,Str "with",Space,Str "paren"] ]+ ] ] ] ] ] ] ]+, Para [Str "Autonumbering:"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "Autonumber",Str "."] ]+ , [ Plain [Str "More",Str "."]+ , OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "Nested",Str "."] ]+ ] ] ]+, HorizontalRule+, Header 1 [Str "Definition",Space,Str "Lists"]+, Para [Str "Tight",Space,Str "using",Space,Str "spaces:"]+, DefinitionList+ [ ([Str "apple"],+ [ Plain [Str "red",Space,Str "fruit"] ]+ ),+ ([Str "orange"],+ [ Plain [Str "orange",Space,Str "fruit"] ]+ ),+ ([Str "banana"],+ [ Plain [Str "yellow",Space,Str "fruit"] ]+ ) ]+, Para [Str "Tight",Space,Str "using",Space,Str "tabs:"]+, DefinitionList+ [ ([Str "apple"],+ [ Plain [Str "red",Space,Str "fruit"] ]+ ),+ ([Str "orange"],+ [ Plain [Str "orange",Space,Str "fruit"] ]+ ),+ ([Str "banana"],+ [ Plain [Str "yellow",Space,Str "fruit"] ]+ ) ]+, Para [Str "Loose:"]+, DefinitionList+ [ ([Str "apple"],+ [ Para [Str "red",Space,Str "fruit"] ]+ ),+ ([Str "orange"],+ [ Para [Str "orange",Space,Str "fruit"] ]+ ),+ ([Str "banana"],+ [ Para [Str "yellow",Space,Str "fruit"] ]+ ) ]+, Para [Str "Multiple",Space,Str "blocks",Space,Str "with",Space,Str "italics:"]+, DefinitionList+ [ ([Emph [Str "apple"]],+ [ Para [Str "red",Space,Str "fruit"]+ , Para [Str "contains",Space,Str "seeds,",Space,Str "crisp,",Space,Str "pleasant",Space,Str "to",Space,Str "taste"] ] ),+ ([Emph [Str "orange"]],+ [ Para [Str "orange",Space,Str "fruit"]+ , CodeBlock "{ orange code block }"+ , BlockQuote+ [ Para [Str "orange",Space,Str "block",Space,Str "quote"] ]+ ] ) ]+, Header 1 [Str "HTML",Space,Str "Blocks"]+, Para [Str "Simple",Space,Str "block",Space,Str "on",Space,Str "one",Space,Str "line:"]+, RawHtml "<div>"+, Plain [Str "foo"]+, RawHtml "</div>\n"+, Para [Str "And",Space,Str "nested",Space,Str "without",Space,Str "indentation:"]+, RawHtml "<div>\n<div>\n<div>"+, Plain [Str "foo"]+, RawHtml "</div>\n</div>\n<div>"+, Plain [Str "bar"]+, RawHtml "</div>\n</div>\n"+, Para [Str "Interpreted",Space,Str "markdown",Space,Str "in",Space,Str "a",Space,Str "table:"]+, RawHtml "<table>\n<tr>\n<td>"+, Plain [Str "This",Space,Str "is",Space,Emph [Str "emphasized"]]+, RawHtml "</td>\n<td>"+, Plain [Str "And",Space,Str "this",Space,Str "is",Space,Strong [Str "strong"]]+, RawHtml "</td>\n</tr>\n</table>\n\n<script type=\"text/javascript\">document.write('This *should not* be interpreted as markdown');</script>\n"+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "simple",Space,Str "block:"]+, RawHtml "<div>\n "+, Plain [Str "foo"]+, RawHtml "</div>\n"+, Para [Str "This",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "code",Space,Str "block,",Space,Str "though:"]+, CodeBlock "<div>\n foo\n</div>"+, Para [Str "As",Space,Str "should",Space,Str "this:"]+, CodeBlock "<div>foo</div>"+, Para [Str "Now,",Space,Str "nested:"]+, RawHtml "<div>\n <div>\n <div>\n "+, Plain [Str "foo"]+, RawHtml "</div>\n </div>\n</div>\n"+, Para [Str "This",Space,Str "should",Space,Str "just",Space,Str "be",Space,Str "an",Space,Str "HTML",Space,Str "comment:"]+, RawHtml "<!-- Comment -->\n"+, Para [Str "Multiline:"]+, RawHtml "<!--\nBlah\nBlah\n-->\n\n<!--\n This is another comment.\n-->\n"+, Para [Str "Code",Space,Str "block:"]+, CodeBlock "<!-- Comment -->"+, Para [Str "Just",Space,Str "plain",Space,Str "comment,",Space,Str "with",Space,Str "trailing",Space,Str "spaces",Space,Str "on",Space,Str "the",Space,Str "line:"]+, RawHtml "<!-- foo --> \n"+, Para [Str "Code:"]+, CodeBlock "<hr />"+, Para [Str "Hr",Apostrophe,Str "s:"]+, RawHtml "<hr>\n\n<hr />\n\n<hr />\n\n<hr> \n\n<hr /> \n\n<hr /> \n\n<hr class=\"foo\" id=\"bar\" />\n\n<hr class=\"foo\" id=\"bar\" />\n\n<hr class=\"foo\" id=\"bar\">\n"+, HorizontalRule+, Header 1 [Str "Inline",Space,Str "Markup"]+, Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ",",Space,Str "and",Space,Str "so",Space,Emph [Str "is",Space,Str "this"],Str "."]+, Para [Str "This",Space,Str "is",Space,Strong [Str "strong"],Str ",",Space,Str "and",Space,Str "so",Space,Strong [Str "is",Space,Str "this"],Str "."]+, Para [Str "An",Space,Emph [Link [Str "emphasized",Space,Str "link"] ("/url","")],Str "."]+, Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em",Str "."]]]+, Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word",Str "."]+, Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em",Str "."]]]+, Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word",Str "."]+, Para [Str "This",Space,Str "is",Space,Str "code:",Space,Code ">",Str ",",Space,Code "$",Str ",",Space,Code "\\",Str ",",Space,Code "\\$",Str ",",Space,Code "<html>",Str "."]+, Para [Strikeout [Str "This",Space,Str "is",Space,Emph [Str "strikeout"],Str "."]]+, Para [Str "Superscripts:",Space,Str "a",Superscript [Str "bc"],Str "d",Space,Str "a",Superscript [Emph [Str "hello"]],Space,Str "a",Superscript [Str "hello",Str " ",Str "there"],Str "."]+, Para [Str "Subscripts:",Space,Str "H",Subscript [Str "2"],Str "O,",Space,Str "H",Subscript [Str "23"],Str "O,",Space,Str "H",Subscript [Str "many",Str " ",Str "of",Str " ",Str "them"],Str "O",Str "."]+, Para [Str "These",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "superscripts",Space,Str "or",Space,Str "subscripts,",Space,Str "because",Space,Str "of",Space,Str "the",Space,Str "unescaped",Space,Str "spaces:",Space,Str "a",Str "^",Str "b",Space,Str "c",Str "^",Str "d,",Space,Str "a",Str "~",Str "b",Space,Str "c",Str "~",Str "d",Str "."]+, HorizontalRule+, Header 1 [Str "Smart",Space,Str "quotes,",Space,Str "ellipses,",Space,Str "dashes"]+, Para [Quoted DoubleQuote [Str "Hello,"],Space,Str "said",Space,Str "the",Space,Str "spider",Str ".",Space,Quoted DoubleQuote [Quoted SingleQuote [Str "Shelob"],Space,Str "is",Space,Str "my",Space,Str "name",Str "."]]+, Para [Quoted SingleQuote [Str "A"],Str ",",Space,Quoted SingleQuote [Str "B"],Str ",",Space,Str "and",Space,Quoted SingleQuote [Str "C"],Space,Str "are",Space,Str "letters",Str "."]+, Para [Quoted SingleQuote [Str "Oak,"],Space,Quoted SingleQuote [Str "elm,"],Space,Str "and",Space,Quoted SingleQuote [Str "beech"],Space,Str "are",Space,Str "names",Space,Str "of",Space,Str "trees",Str ".",Space,Str "So",Space,Str "is",Space,Quoted SingleQuote [Str "pine",Str "."]]+, Para [Quoted SingleQuote [Str "He",Space,Str "said,",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go",Str "."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70",Apostrophe,Str "s?"]+, Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "quoted",Space,Quoted SingleQuote [Code "code"],Space,Str "and",Space,Str "a",Space,Quoted DoubleQuote [Link [Str "quoted",Space,Str "link"] ("http://example.com/?foo=1&bar=2","")],Str "."]+, Para [Str "Some",Space,Str "dashes:",Space,Str "one",EmDash,Str "two",EmDash,Str "three",EmDash,Str "four",EmDash,Str "five",Str "."]+, Para [Str "Dashes",Space,Str "between",Space,Str "numbers:",Space,Str "5",EnDash,Str "7,",Space,Str "255",EnDash,Str "66,",Space,Str "1987",EnDash,Str "1999",Str "."]+, Para [Str "Ellipses",Ellipses,Str "and",Ellipses,Str "and",Ellipses,Str "."]+, HorizontalRule+, Header 1 [Str "LaTeX"]+, BulletList+ [ [ Plain [TeX "\\cite[22-23]{smith.1899}"] ]+ , [ Plain [TeX "\\doublespacing"] ]+ , [ Plain [TeX "$2+2=4$"] ]+ , [ Plain [TeX "$x \\in y$"] ]+ , [ Plain [TeX "$\\alpha \\wedge \\omega$"] ]+ , [ Plain [TeX "$223$"] ]+ , [ Plain [TeX "$p$",Str "-",Str "Tree"] ]+ , [ Plain [TeX "$\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}$"] ]+ , [ Plain [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it:",Space,TeX "$\\alpha + \\omega \\times x^2$",Str "."] ] ]+, Para [Str "These",Space,Str "shouldn",Apostrophe,Str "t",Space,Str "be",Space,Str "math:"]+, BulletList+ [ [ Plain [Str "To",Space,Str "get",Space,Str "the",Space,Str "famous",Space,Str "equation,",Space,Str "write",Space,Code "$e = mc^2$",Str "."] ]+ , [ Plain [Str "$",Str "22,000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money",Str ".",Space,Str "So",Space,Str "is",Space,Str "$",Str "34,000",Str ".",Space,Str "(It",Space,Str "worked",Space,Str "if",Space,Quoted DoubleQuote [Str "lot"],Space,Str "is",Space,Str "emphasized",Str ".",Str ")"] ]+ , [ Plain [Str "Escaped",Space,Code "$",Str ":",Space,Str "$",Str "73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23",Str "$",Str "."] ] ]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]+, Para [TeX "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}"]+, HorizontalRule+, Header 1 [Str "Special",Space,Str "Characters"]+, Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode:"]+, BulletList+ [ [ Plain [Str "I",Space,Str "hat:",Space,Str "\206"] ]+ , [ Plain [Str "o",Space,Str "umlaut:",Space,Str "\246"] ]+ , [ Plain [Str "section:",Space,Str "\167"] ]+ , [ Plain [Str "set",Space,Str "membership:",Space,Str "\8712"] ]+ , [ Plain [Str "copyright:",Space,Str "\169"] ] ]+, Para [Str "AT",Str "&",Str "T",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "their",Space,Str "name",Str "."]+, Para [Str "AT",Str "&",Str "T",Space,Str "is",Space,Str "another",Space,Str "way",Space,Str "to",Space,Str "write",Space,Str "it",Str "."]+, Para [Str "This",Space,Str "&",Space,Str "that",Str "."]+, Para [Str "4",Space,Str "<",Space,Str "5",Str "."]+, Para [Str "6",Space,Str ">",Space,Str "5",Str "."]+, Para [Str "Backslash:",Space,Str "\\"]+, Para [Str "Backtick:",Space,Str "`"]+, Para [Str "Asterisk:",Space,Str "*"]+, Para [Str "Underscore:",Space,Str "_"]+, Para [Str "Left",Space,Str "brace:",Space,Str "{"]+, Para [Str "Right",Space,Str "brace:",Space,Str "}"]+, Para [Str "Left",Space,Str "bracket:",Space,Str "["]+, Para [Str "Right",Space,Str "bracket:",Space,Str "]"]+, Para [Str "Left",Space,Str "paren:",Space,Str "("]+, Para [Str "Right",Space,Str "paren:",Space,Str ")"]+, Para [Str "Greater",Str "-",Str "than:",Space,Str ">"]+, Para [Str "Hash:",Space,Str "#"]+, Para [Str "Period:",Space,Str "."]+, Para [Str "Bang:",Space,Str "!"]+, Para [Str "Plus:",Space,Str "+"]+, Para [Str "Minus:",Space,Str "-"]+, HorizontalRule+, Header 1 [Str "Links"]+, Header 2 [Str "Explicit"]+, Para [Str "Just",Space,Str "a",Space,Link [Str "URL"] ("/url/",""),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title"),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title preceded by two spaces"),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title preceded by a tab"),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title with \"quotes\" in it")]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title with single quotes")]+, Para [Link [Str "with",Str "_",Str "underscore"] ("/url/with_underscore","")]+, Para [Link [Str "Email",Space,Str "link"] ("mailto:nobody@nowhere.net","")]+, Para [Link [Str "Empty"] ("",""),Str "."]+, Header 2 [Str "Reference"]+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+, Para [Str "With",Space,Link [Str "embedded",Space,Str "[",Str "brackets",Str "]"] ("/url/",""),Str "."]+, Para [Link [Str "b"] ("/url/",""),Space,Str "by",Space,Str "itself",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "link",Str "."]+, Para [Str "Indented",Space,Link [Str "once"] ("/url",""),Str "."]+, Para [Str "Indented",Space,Link [Str "twice"] ("/url",""),Str "."]+, Para [Str "Indented",Space,Link [Str "thrice"] ("/url",""),Str "."]+, Para [Str "This",Space,Str "should",Space,Str "[",Str "not",Str "]",Str "[",Str "]",Space,Str "be",Space,Str "a",Space,Str "link",Str "."]+, CodeBlock "[not]: /url"+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/","Title with \"quotes\" inside"),Str "."]+, Para [Str "Foo",Space,Link [Str "biz"] ("/url/","Title with \"quote\" inside"),Str "."]+, Header 2 [Str "With",Space,Str "ampersands"]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text:",Space,Link [Str "AT",Str "&",Str "T"] ("http://att.com/","AT&T"),Str "."]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]+, Header 2 [Str "Autolinks"]+, Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link [Code "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]+, BulletList+ [ [ Plain [Str "In",Space,Str "a",Space,Str "list?"] ]+ , [ Plain [Link [Code "http://example.com/"] ("http://example.com/","")] ]+ , [ Plain [Str "It",Space,Str "should",Str "."] ] ]+, Para [Str "An",Space,Str "e",Str "-",Str "mail",Space,Str "address:",Space,Link [Code "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]+, BlockQuote+ [ Para [Str "Blockquoted:",Space,Link [Code "http://example.com/"] ("http://example.com/","")] ]++, Para [Str "Auto",Str "-",Str "links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",Space,Code "<http://example.com/>"]+, CodeBlock "or here: <http://example.com/>"+, HorizontalRule+, Header 1 [Str "Images"]+, Para [Str "From",Space,Quoted DoubleQuote [Str "Voyage",Space,Str "dans",Space,Str "la",Space,Str "Lune"],Space,Str "by",Space,Str "Georges",Space,Str "Melies",Space,Str "(1902):"]+, Para [Image [Str "lalune"] ("lalune.jpg","Voyage dans la Lune")]+, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image [Str "movie"] ("movie.jpg",""),Space,Str "icon",Str "."]+, HorizontalRule+, Header 1 [Str "Footnotes"]+, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote",Str ".",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference",Str ".",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document",Str "."]],Space,Str "and",Space,Str "another",Str ".",Note [Para [Str "Here",Apostrophe,Str "s",Space,Str "the",Space,Str "long",Space,Str "note",Str ".",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks",Str "."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "list",Space,Str "items)",Str "."],CodeBlock " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line,",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block",Str "."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space",Str ".",Str "[",Str "^",Str "my",Space,Str "note",Str "]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note",Str ".",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type",Str ".",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code "]",Space,Str "verbatim",Space,Str "characters,",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[",Str "bracketed",Space,Str "text",Str "]",Str "."]]]+, BlockQuote+ [ Para [Str "Notes",Space,Str "can",Space,Str "go",Space,Str "in",Space,Str "quotes",Str ".",Note [Para [Str "In",Space,Str "quote",Str "."]]] ]++, OrderedList (1,Decimal,Period)+ [ [ Plain [Str "And",Space,Str "in",Space,Str "list",Space,Str "items",Str ".",Note [Para [Str "In",Space,Str "list",Str "."]]] ]+ ]+, Para [Str "This",Space,Str "paragraph",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "part",Space,Str "of",Space,Str "the",Space,Str "note,",Space,Str "as",Space,Str "it",Space,Str "is",Space,Str "not",Space,Str "indented",Str "."] ]+
+ tests/testsuite.txt view
@@ -0,0 +1,701 @@+% Pandoc Test Suite+% John MacFarlane, Anonymous+% July 17, 2006++This is a set of tests for pandoc. Most of them are adapted from+John Gruber's markdown test suite.++-----++# Headers++## Level 2 with an [embedded link](/url)++### Level 3 with *emphasis*++#### Level 4++##### Level 5++Level 1+=======++Level 2 with *emphasis*+-----------------------++### Level 3+with no blank line++Level 2+-------+with no blank line++----------++# 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.++Here's one with a bullet.+* criminey.++There should be a hard line break +here.++---++# Block Quotes++E-mail style:++> This is a block quote.+> It is pretty short.++> Code in a block quote: +> +> sub status {+> print "working";+> }+> +> A list: +> +> 1. item one+> 2. item two+>+> Nested block quotes:+>+> > nested+>+>> nested+>++This should not be a block quote: 2+> 1.++Box-style:++,----+| Example:+| +| sub status {+| print "working";+| }+`----++,----+| 1. do laundry+| 2. take out the trash+`----++Here's a nested one:++,----+| Joe said:+|+| ,----+| | Don't quote me.+| `----+`----++And a following paragraph.++* * * *++# Code Blocks++Code:++ ---- (should be four hyphens)++ sub status {+ print "working";+ }++ this code block is indented by one tab++And:++ this code block is indented by two tabs++ These should not be escaped: \$ \\ \> \[ \{++___________++# Lists++## Unordered++Asterisks tight:++* asterisk 1+* asterisk 2+* asterisk 3++Asterisks loose:++* asterisk 1++* asterisk 2++* asterisk 3++Pluses tight:+++ Plus 1++ Plus 2++ Plus 3++Pluses loose:+++ Plus 1+++ Plus 2+++ Plus 3++Minuses tight:++- Minus 1+- Minus 2+- Minus 3++Minuses loose:++- Minus 1++- Minus 2++- Minus 3++## Ordered++Tight:++1. First+2. Second+3. Third++and:++1. One+2. Two+3. Three++Loose using tabs:++1. First++2. Second++3. Third++and using spaces:++1. One++2. Two++3. Three++Multiple paragraphs:++1. Item 1, graf one.++ Item 1. graf two. The quick brown fox jumped over the lazy dog's+ back.+ +2. Item 2.++3. Item 3.++## Nested++* Tab+ * Tab+ * Tab++Here's another:++1. First+2. Second:+ * Fee+ * Fie+ * Foe+3. Third++Same thing but with paragraphs:++1. First++2. Second:++ * Fee+ * Fie+ * Foe++3. Third ++## Tabs and spaces+++ this is a list item+ indented with tabs+++ this is a list item+ indented with spaces++ + this is an example list item+ indented with tabs+ + + this is an example list item+ indented with spaces++## Fancy list markers++(2) begins with 2+(3) and now 3++ with a continuation++ iv. sublist with roman numerals,+ starting with 4+ v. more items+ (A) a subsublist+ (B) a subsublist++Nesting:++A. Upper Alpha+ I. Upper Roman.+ (6) Decimal start with 6+ c) Lower alpha with paren++Autonumbering:++ #. Autonumber.+ #. More.+ #. Nested.++ * * * * *++# Definition Lists++Tight using spaces:++apple+: red fruit+orange+: orange fruit+banana+: yellow fruit++Tight using tabs:++apple+: red fruit+orange+: orange fruit+banana+: yellow fruit++Loose:++apple+: red fruit++orange+: orange fruit++banana+: yellow fruit++Multiple blocks with italics:++*apple*+: red fruit++: contains seeds,+ crisp, pleasant to taste++*orange*+: orange fruit++: { orange code block }++: > orange block quote++# HTML Blocks++Simple block on one line:++<div>foo</div>++And nested without indentation:++<div>+<div>+<div>+foo+</div>+</div>+<div>bar</div>+</div>++Interpreted markdown in a table:++<table>+<tr>+<td>This is *emphasized*</td>+<td>And this is **strong**</td>+</tr>+</table>++<script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>++Here's a simple block:++<div>+ foo+</div>++This should be a code block, though:++ <div>+ foo+ </div>++As should this:++ <div>foo</div>++Now, nested:++<div>+ <div>+ <div>+ foo+ </div>+ </div>+</div>++This should just be an HTML comment:++<!-- Comment -->++Multiline:++<!--+Blah+Blah+-->++<!--+ This is another comment.+-->++Code block:++ <!-- Comment -->++Just plain comment, with trailing spaces on the line:++<!-- foo --> ++Code:++ <hr />+ +Hr's:++<hr>++<hr/>++<hr />++<hr> ++<hr/> ++<hr /> ++<hr class="foo" id="bar" />++<hr class="foo" id="bar"/>++<hr class="foo" id="bar" >++-----++# Inline Markup++This is *emphasized*, and so _is this_.++This is **strong**, and so __is this__.++An *[emphasized link](/url)*.++***This is strong and em.***++So is ***this*** word.++___This is strong and em.___++So is ___this___ word.++This is code: `>`, `$`, `\`, `\$`, `<html>`.++~~This is *strikeout*.~~++Superscripts: a^bc^d a^*hello*^ a^hello\ there^.++Subscripts: H~2~O, H~23~O, H~many\ of\ them~O.++These should not be superscripts or subscripts,+because of the unescaped spaces: a^b c^d, a~b c~d.++-----++# Smart quotes, ellipses, dashes++"Hello," said the spider. "'Shelob' is my name."++'A', 'B', and 'C' are letters.++'Oak,' 'elm,' and 'beech' are names of trees.+So is 'pine.'++'He said, "I want to go."' Were you alive in the+70's?++Here is some quoted '`code`' and a "[quoted link][1]".++Some dashes: one---two --- three--four -- five.++Dashes between numbers: 5-7, 255-66, 1987-1999. ++Ellipses...and. . .and . . . .++-----++# LaTeX++- \cite[22-23]{smith.1899}+- \doublespacing+- $2+2=4$+- $x \in y$+- $\alpha \wedge \omega$+- $223$ +- $p$-Tree+- $\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$ +- Here's one that has a line break in it: $\alpha + \omega \times+x^2$. ++These shouldn't be math:++- To get the famous equation, write `$e = mc^2$`.+- $22,000 is a *lot* of money. So is $34,000.+ (It worked if "lot" is emphasized.)+- Escaped `$`: $73 *this should be emphasized* 23\$.++Here's a LaTeX table:++\begin{tabular}{|l|l|}\hline+Animal & Number \\ \hline+Dog & 2 \\+Cat & 1 \\ \hline+\end{tabular}++* * * * *++# Special Characters++Here is some unicode:++- I hat: Î+- o umlaut: ö+- section: § +- set membership: ∈+- copyright: ©++AT&T has an ampersand in their name.++AT&T is another way to write it.++This & that.++4 < 5.++6 > 5.++Backslash: \\++Backtick: \`++Asterisk: \*++Underscore: \_++Left brace: \{++Right brace: \}++Left bracket: \[++Right bracket: \]++Left paren: \(++Right paren: \)++Greater-than: \>++Hash: \#++Period: \.++Bang: \!++Plus: \+++Minus: \-++- - - - - - - - - - - - -++# Links++## Explicit++Just a [URL](/url/).++[URL and title](/url/ "title").++[URL and title](/url/ "title preceded by two spaces").++[URL and title](/url/ "title preceded by a tab").++[URL and title](/url/ "title with "quotes" in it")++[URL and title](/url/ 'title with single quotes')++[with\_underscore](/url/with_underscore)++[Email link](mailto:nobody@nowhere.net)++[Empty]().++## Reference++Foo [bar] [a].++Foo [bar][a].++Foo [bar]+[a].++[a]: /url/++With [embedded [brackets]] [b].++[b] by itself should be a link.++Indented [once][].++Indented [twice][].++Indented [thrice][].++This should [not][] be a link.++ [once]: /url++ [twice]: /url++ [thrice]: /url++ [not]: /url++[b]: /url/++Foo [bar][].++Foo [biz](/url/ "Title with "quote" inside").++ [bar]: /url/ "Title with "quotes" inside"++## With ampersands++Here's a [link with an ampersand in the URL] [1].++Here's a link with an amersand in the link text: [AT&T] [2].++Here's an [inline link](/script?foo=1&bar=2).++Here's an [inline link in pointy braces](</script?foo=1&bar=2>).++[1]: http://example.com/?foo=1&bar=2+[2]: http://att.com/ "AT&T" ++## Autolinks++With an ampersand: <http://example.com/?foo=1&bar=2>++* In a list?+* <http://example.com/>+* It should.++An e-mail address: <nobody@nowhere.net>++> Blockquoted: <http://example.com/>++Auto-links should not occur here: `<http://example.com/>`++ or here: <http://example.com/>++----++# Images++From "Voyage dans la Lune" by Georges Melies (1902):++![lalune][]++ [lalune]: lalune.jpg "Voyage dans la Lune"++Here is a movie  icon.++----++# Footnotes++Here is a footnote reference,[^1] and another.[^longnote]+This should *not* be a footnote reference, because it +contains a space.[^my note] Here is an inline note.^[This+is *easier* to type. Inline notes may contain+[links](http://google.com) and `]` verbatim characters,+as well as [bracketed text].]++> Notes can go in quotes.^[In quote.]++1. And in list items.^[In list.]++[^longnote]: 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).++ { <code> }++ If you want, you can indent every line, but you can also be+ lazy and just indent the first line of each block.++This paragraph should not be part of the note, as it is not indented.++[^1]: Here is the footnote. It can go anywhere after the footnote+reference. It need not be placed at the end of the document.
+ tests/writer.context view
@@ -0,0 +1,764 @@+\enableregime[utf] % use UTF-8++\setupcolors[state=start]+\setupinteraction[state=start, color=middlered] % needed for hyperlinks++\setuppapersize[letter][letter] % use letter paper+\setuplayout[width=middle, backspace=1.5in, cutspace=1.5in,+ height=middle, header=0.75in, footer=0.75in] % page layout+\setuppagenumbering[location={footer,center}] % number pages+\setupbodyfont[11pt] % 11pt font+\setupwhitespace[medium] % inter-paragraph spacing++\setuphead[section][style=\tfc]+\setuphead[subsection][style=\tfb]+\setuphead[subsubsection][style=\bf]++% define title block commands+\unprotect+\def\doctitle#1{\gdef\@title{#1}}+\def\author#1{\gdef\@author{#1}}+\def\date#1{\gdef\@date{#1}}+\date{\currentdate} % Default to today unless specified otherwise.+\def\maketitle{%+ \startalignment[center]+ \blank[2*big]+ {\tfd \@title}+ \blank[3*medium]+ {\tfa \@author}+ \blank[2*medium]+ {\tfa \@date}+ \blank[3*medium]+ \stopalignment}+\protect++% define descr (for definition lists)+\definedescription[descr][+ headstyle=bold,style=normal,align=left,location=hanging,+ width=broad,margin=1cm]++% define ltxitem (for bulleted lists) +\defineitemgroup[ltxitem][levels=4]+\setupitemgroup[ltxitem][1][1]+\setupitemgroup[ltxitem][2][2]+\setupitemgroup[ltxitem][3][3]+\setupitemgroup[ltxitem][4][4,packed]++% define ltxenum (for enumerated lists)+\defineitemgroup[ltxenum][levels=4]+\setupitemgroup[ltxenum][1][n]+\setupitemgroup[ltxenum][2][a]+\setupitemgroup[ltxenum][3][r]+\setupitemgroup[ltxenum][4][A,packed]++\setupthinrules[width=15em] % width of horizontal rules++% for block quotations+\definestartstop [blockquote]+ [before={\startnarrower\switchtobodyfont[11pt]+ \whitespace\setupindenting[no]},+ after={\stopnarrower\whitespace}]++\setupheads[sectionnumber=no, style=\bf]+\doctitle{Pandoc Test Suite}+ \author{John MacFarlane \& Anonymous}+ \date{July 17, 2006}++\starttext+\maketitle++This is a set of tests for pandoc. Most of them are adapted from John Gruber's markdown test suite.++\thinrule++\section{Headers}++\subsection{Level 2 with an \useurl[1][/url][][embedded link]\from[1]}++\subsubsection{Level 3 with {\em emphasis}}++Level 4++Level 5++\section{Level 1}++\subsection{Level 2 with {\em emphasis}}++\subsubsection{Level 3}++with no blank line++\subsection{Level 2}++with no blank line++\thinrule++\section{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.++Here's one with a bullet. * criminey.++There should be a hard line break\crlf+here.++\thinrule++\section{Block Quotes}++E-mail style:++\startblockquote+This is a block quote. It is pretty short.++\stopblockquote++\startblockquote+Code in a block quote:++\starttyping+sub status {+ print "working";+}+\stoptyping+A list:++\startitemize+\sym{1.} item one+\sym{2.} item two+\stopitemize+Nested block quotes:++\startblockquote+nested++\stopblockquote++\startblockquote+nested++\stopblockquote++\stopblockquote++This should not be a block quote: 2 \lettermore{} 1.++Box-style:++\startblockquote+Example:++\starttyping+sub status {+ print "working";+}+\stoptyping+\stopblockquote++\startblockquote+\startitemize+\sym{1.} do laundry+\sym{2.} take out the trash+\stopitemize+\stopblockquote++Here's a nested one:++\startblockquote+Joe said:++\startblockquote+Don't quote me.++\stopblockquote++\stopblockquote++And a following paragraph.++\thinrule++\section{Code Blocks}++Code:++\starttyping+---- (should be four hyphens)++sub status {+ print "working";+}++this code block is indented by one tab+\stoptyping+And:++\starttyping+ this code block is indented by two tabs++These should not be escaped: \$ \\ \> \[ \{+\stoptyping+\thinrule++\section{Lists}++\subsection{Unordered}++Asterisks tight:++\startltxitem+\item asterisk 1+\item asterisk 2+\item asterisk 3+\stopltxitem+Asterisks loose:++\startltxitem+\item asterisk 1++\item asterisk 2++\item asterisk 3++\stopltxitem+Pluses tight:++\startltxitem+\item Plus 1+\item Plus 2+\item Plus 3+\stopltxitem+Pluses loose:++\startltxitem+\item Plus 1++\item Plus 2++\item Plus 3++\stopltxitem+Minuses tight:++\startltxitem+\item Minus 1+\item Minus 2+\item Minus 3+\stopltxitem+Minuses loose:++\startltxitem+\item Minus 1++\item Minus 2++\item Minus 3++\stopltxitem+\subsection{Ordered}++Tight:++\startitemize+\sym{1.} First+\sym{2.} Second+\sym{3.} Third+\stopitemize+and:++\startitemize+\sym{1.} One+\sym{2.} Two+\sym{3.} Three+\stopitemize+Loose using tabs:++\startitemize+\sym{1.} First++\sym{2.} Second++\sym{3.} Third++\stopitemize+and using spaces:++\startitemize+\sym{1.} One++\sym{2.} Two++\sym{3.} Three++\stopitemize+Multiple paragraphs:++\startitemize+\sym{1.} Item 1, graf one.++Item 1. graf two. The quick brown fox jumped over the lazy dog's back.++\sym{2.} Item 2.++\sym{3.} Item 3.++\stopitemize+\subsection{Nested}++\startltxitem+\item Tab+\startltxitem+\item Tab+\startltxitem+\item Tab+\stopltxitem+\stopltxitem+\stopltxitem+Here's another:++\startitemize+\sym{1.} First+\sym{2.} Second:+\startltxitem+\item Fee+\item Fie+\item Foe+\stopltxitem+\sym{3.} Third+\stopitemize+Same thing but with paragraphs:++\startitemize+\sym{1.} First++\sym{2.} Second:++\startltxitem+\item Fee+\item Fie+\item Foe+\stopltxitem+\sym{3.} Third++\stopitemize+\subsection{Tabs and spaces}++\startltxitem+\item this is a list item indented with tabs++\item this is a list item indented with spaces++\startltxitem+\item this is an example list item indented with tabs++\item this is an example list item indented with spaces++\stopltxitem+\stopltxitem+\subsection{Fancy list markers}++\startitemize[width=2em]+\sym{(2)} begins with 2+\sym{(3)} and now 3++with a continuation++\startitemize[width=2em]+\sym{iv.} sublist with roman numerals, starting with 4+\sym{v.} more items+\startitemize[width=2em]+\sym{(A)} a subsublist+\sym{(B)} a subsublist+\stopitemize+\stopitemize+\stopitemize+Nesting:++\startitemize+\sym{A.} Upper Alpha+\startitemize+\sym{I.} Upper Roman.+\startitemize[width=2em]+\sym{(6)} Decimal start with 6+\startitemize+\sym{c)} Lower alpha with paren+\stopitemize+\stopitemize+\stopitemize+\stopitemize+Autonumbering:++\startltxenum+\item Autonumber.+\item More.+\startltxenum+\item Nested.+\stopltxenum+\stopltxenum+\thinrule++\section{Definition Lists}++Tight using spaces:++\startdescr{apple}+red fruit++\stopdescr+\startdescr{orange}+orange fruit++\stopdescr+\startdescr{banana}+yellow fruit++\stopdescr++Tight using tabs:++\startdescr{apple}+red fruit++\stopdescr+\startdescr{orange}+orange fruit++\stopdescr+\startdescr{banana}+yellow fruit++\stopdescr++Loose:++\startdescr{apple}+red fruit+++\stopdescr+\startdescr{orange}+orange fruit+++\stopdescr+\startdescr{banana}+yellow fruit+++\stopdescr++Multiple blocks with italics:++\startdescr{{\em apple}}+red fruit++contains seeds, crisp, pleasant to taste+++\stopdescr+\startdescr{{\em orange}}+orange fruit++\starttyping+{ orange code block }+\stoptyping+\startblockquote+orange block quote++\stopblockquote+++\stopdescr++\section{HTML Blocks}++Simple block on one line:++foo+And nested without indentation:++foo+bar+Interpreted markdown in a table:++This is {\em emphasized}+And this is {\bf strong}+Here's a simple block:++foo+This should be a code block, though:++\starttyping+<div>+ foo+</div>+\stoptyping+As should this:++\starttyping+<div>foo</div>+\stoptyping+Now, nested:++foo+This should just be an HTML comment:++Multiline:++Code block:++\starttyping+<!-- Comment -->+\stoptyping+Just plain comment, with trailing spaces on the line:++Code:++\starttyping+<hr />+\stoptyping+Hr's:++\thinrule++\section{Inline Markup}++This is {\em emphasized}, and so {\em is this}.++This is {\bf strong}, and so {\bf is this}.++An {\em \useurl[2][/url][][emphasized link]\from[2]}.++{\bf {\em This is strong and em.}}++So is {\bf {\em this}} word.++{\bf {\em This is strong and em.}}++So is {\bf {\em this}} word.++This is code: \type{>}, \type{$}, \type{\}, \type{\$}, \type{<html>}.++\overstrikes{This is {\em strikeout}.}++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.++These should not be superscripts or subscripts, because of the unescaped spaces: a\letterhat{}b c\letterhat{}d, a\lettertilde{}b c\lettertilde{}d.++\thinrule++\section{Smart quotes, ellipses, dashes}++\quotation{Hello,} said the spider. \quotation{\quote{Shelob} is my name.}++\quote{A}, \quote{B}, and \quote{C} are letters.++\quote{Oak,} \quote{elm,} and \quote{beech} are names of trees. So is \quote{pine.}++\quote{He said, \quotation{I want to go.}} Were you alive in the 70's?++Here is some quoted \quote{\type{code}} and a \quotation{\useurl[3][http://example.com/?foo=1&bar=2][][quoted link]\from[3]}.++Some dashes: one---two---three---four---five.++Dashes between numbers: 5--7, 255--66, 1987--1999.++Ellipses\ldots{}and\ldots{}and\ldots{}.++\thinrule++\section{Special Characters}++Here is some unicode:++\startltxitem+\item I hat: Î+\item o umlaut: ö+\item section: §+\item set membership: ∈+\item copyright: ©+\stopltxitem+AT\&T has an ampersand in their name.++AT\&T is another way to write it.++This \& that.++4 \letterless{} 5.++6 \lettermore{} 5.++Backslash: \letterbackslash{}++Backtick: `++Asterisk: *++Underscore: \letterunderscore{}++Left brace: \letteropenbrace{}++Right brace: \letterclosebrace{}++Left bracket: [++Right bracket: ]++Left paren: (++Right paren: )++Greater-than: \lettermore{}++Hash: \#++Period: .++Bang: !++Plus: +++Minus: -++\thinrule++\section{Links}++\subsection{Explicit}++Just a \useurl[4][/url/][][URL]\from[4].++\useurl[5][/url/][][URL and title]\from[5].++\useurl[6][/url/][][URL and title]\from[6].++\useurl[7][/url/][][URL and title]\from[7].++\useurl[8][/url/][][URL and title]\from[8]++\useurl[9][/url/][][URL and title]\from[9]++\useurl[10][/url/with_underscore][][with\letterunderscore{}underscore]\from[10]++\useurl[11][mailto:nobody@nowhere.net][][Email link]\from[11]++\useurl[12][][][Empty]\from[12].++\subsection{Reference}++Foo \useurl[13][/url/][][bar]\from[13].++Foo \useurl[14][/url/][][bar]\from[14].++Foo \useurl[15][/url/][][bar]\from[15].++With \useurl[16][/url/][][embedded [brackets]]\from[16].++\useurl[17][/url/][][b]\from[17] by itself should be a link.++Indented \useurl[18][/url][][once]\from[18].++Indented \useurl[19][/url][][twice]\from[19].++Indented \useurl[20][/url][][thrice]\from[20].++This should [not][] be a link.++\starttyping+[not]: /url+\stoptyping+Foo \useurl[21][/url/][][bar]\from[21].++Foo \useurl[22][/url/][][biz]\from[22].++\subsection{With ampersands}++Here's a \useurl[23][http://example.com/?foo=1&bar=2][][link with an ampersand in the URL]\from[23].++Here's a link with an amersand in the link text: \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[26][/script?foo=1&bar=2][][inline link in pointy braces]\from[26].++\subsection{Autolinks}++With an ampersand: \useurl[27][http://example.com/?foo=1&bar=2][][http://example.com/?foo=1\&bar=2]\from[27]++\startltxitem+\item In a list?+\item \useurl[28][http://example.com/][][http://example.com/]\from[28]+\item It should.+\stopltxitem+An e-mail address: \useurl[29][mailto:nobody@nowhere.net][][nobody@nowhere.net]\from[29]++\startblockquote+Blockquoted: \useurl[30][http://example.com/][][http://example.com/]\from[30]++\stopblockquote++Auto-links should not occur here: \type{<http://example.com/>}++\starttyping+or here: <http://example.com/>+\stoptyping+\thinrule++\section{Images}++From \quotation{Voyage dans la Lune} by Georges Melies (1902):++\placefigure+[]+[fig:lalune]+{Voyage dans la Lune}+{\externalfigure[lalune.jpg]}++Here is a movie \placefigure+[]+[fig:movie]+{}+{\externalfigure[movie.jpg]} icon.++\thinrule++\section{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).++\starttyping+ { <code> }+\stoptyping+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 {\em not} be a footnote reference, because it contains a space.[\letterhat{}my note] Here is an inline note.\footnote{This is {\em easier} to type. Inline notes may contain \useurl[31][http://google.com][][links]\from[31] and \type{]} verbatim characters, as well as [bracketed text].++}++\startblockquote+Notes can go in quotes.\footnote{In quote.++}++\stopblockquote++\startitemize+\sym{1.} And in list items.\footnote{In list.++}+\stopitemize+This paragraph should not be part of the note, as it is not indented.+++\stoptext+
+ tests/writer.docbook view
@@ -0,0 +1,1274 @@+<?xml version="1.0" encoding="utf-8" ?>+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"+ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">++<article>+ <articleinfo>+ <title>Pandoc Test Suite</title>+ <author>+ <firstname>John</firstname>+ <surname>MacFarlane</surname>+ </author>+ <author>+ <firstname></firstname>+ <surname>Anonymous</surname>+ </author>+ <date>July 17, 2006</date>+ </articleinfo>+ <para>+ This is a set of tests for pandoc. Most of them are adapted from+ John Gruber's markdown test suite.+ </para>+ <section>+ <title>Headers</title>+ <section>+ <title>Level 2 with an+ <ulink url="/url">embedded link</ulink></title>+ <section>+ <title>Level 3 with <emphasis>emphasis</emphasis></title>+ <section>+ <title>Level 4</title>+ <section>+ <title>Level 5</title>+ <para>+ </para>+ </section>+ </section>+ </section>+ </section>+ </section>+ <section>+ <title>Level 1</title>+ <section>+ <title>Level 2 with <emphasis>emphasis</emphasis></title>+ <section>+ <title>Level 3</title>+ <para>+ with no blank line+ </para>+ </section>+ </section>+ <section>+ <title>Level 2</title>+ <para>+ with no blank line+ </para>+ </section>+ </section>+ <section>+ <title>Paragraphs</title>+ <para>+ Here's a regular paragraph.+ </para>+ <para>+ 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.+ </para>+ <para>+ Here's one with a bullet. * criminey.+ </para>+ <para>+ There should be a hard line+ break<literallayout></literallayout>here.+ </para>+ </section>+ <section>+ <title>Block Quotes</title>+ <para>+ E-mail style:+ </para>+ <blockquote>+ <para>+ This is a block quote. It is pretty short.+ </para>+ </blockquote>+ <blockquote>+ <para>+ Code in a block quote:+ </para>+ <screen>+sub status {+ print "working";+}+</screen>+ <para>+ A list:+ </para>+ <orderedlist numeration="arabic">+ <listitem>+ <para>+ item one+ </para>+ </listitem>+ <listitem>+ <para>+ item two+ </para>+ </listitem>+ </orderedlist>+ <para>+ Nested block quotes:+ </para>+ <blockquote>+ <para>+ nested+ </para>+ </blockquote>+ <blockquote>+ <para>+ nested+ </para>+ </blockquote>+ </blockquote>+ <para>+ This should not be a block quote: 2 > 1.+ </para>+ <para>+ Box-style:+ </para>+ <blockquote>+ <para>+ Example:+ </para>+ <screen>+sub status {+ print "working";+}+</screen>+ </blockquote>+ <blockquote>+ <orderedlist numeration="arabic">+ <listitem>+ <para>+ do laundry+ </para>+ </listitem>+ <listitem>+ <para>+ take out the trash+ </para>+ </listitem>+ </orderedlist>+ </blockquote>+ <para>+ Here's a nested one:+ </para>+ <blockquote>+ <para>+ Joe said:+ </para>+ <blockquote>+ <para>+ Don't quote me.+ </para>+ </blockquote>+ </blockquote>+ <para>+ And a following paragraph.+ </para>+ </section>+ <section>+ <title>Code Blocks</title>+ <para>+ Code:+ </para>+ <screen>+---- (should be four hyphens)++sub status {+ print "working";+}++this code block is indented by one tab+</screen>+ <para>+ And:+ </para>+ <screen>+ this code block is indented by two tabs++These should not be escaped: \$ \\ \> \[ \{+</screen>+ </section>+ <section>+ <title>Lists</title>+ <section>+ <title>Unordered</title>+ <para>+ Asterisks tight:+ </para>+ <itemizedlist>+ <listitem>+ <para>+ asterisk 1+ </para>+ </listitem>+ <listitem>+ <para>+ asterisk 2+ </para>+ </listitem>+ <listitem>+ <para>+ asterisk 3+ </para>+ </listitem>+ </itemizedlist>+ <para>+ Asterisks loose:+ </para>+ <itemizedlist>+ <listitem>+ <para>+ asterisk 1+ </para>+ </listitem>+ <listitem>+ <para>+ asterisk 2+ </para>+ </listitem>+ <listitem>+ <para>+ asterisk 3+ </para>+ </listitem>+ </itemizedlist>+ <para>+ Pluses tight:+ </para>+ <itemizedlist>+ <listitem>+ <para>+ Plus 1+ </para>+ </listitem>+ <listitem>+ <para>+ Plus 2+ </para>+ </listitem>+ <listitem>+ <para>+ Plus 3+ </para>+ </listitem>+ </itemizedlist>+ <para>+ Pluses loose:+ </para>+ <itemizedlist>+ <listitem>+ <para>+ Plus 1+ </para>+ </listitem>+ <listitem>+ <para>+ Plus 2+ </para>+ </listitem>+ <listitem>+ <para>+ Plus 3+ </para>+ </listitem>+ </itemizedlist>+ <para>+ Minuses tight:+ </para>+ <itemizedlist>+ <listitem>+ <para>+ Minus 1+ </para>+ </listitem>+ <listitem>+ <para>+ Minus 2+ </para>+ </listitem>+ <listitem>+ <para>+ Minus 3+ </para>+ </listitem>+ </itemizedlist>+ <para>+ Minuses loose:+ </para>+ <itemizedlist>+ <listitem>+ <para>+ Minus 1+ </para>+ </listitem>+ <listitem>+ <para>+ Minus 2+ </para>+ </listitem>+ <listitem>+ <para>+ Minus 3+ </para>+ </listitem>+ </itemizedlist>+ </section>+ <section>+ <title>Ordered</title>+ <para>+ Tight:+ </para>+ <orderedlist numeration="arabic">+ <listitem>+ <para>+ First+ </para>+ </listitem>+ <listitem>+ <para>+ Second+ </para>+ </listitem>+ <listitem>+ <para>+ Third+ </para>+ </listitem>+ </orderedlist>+ <para>+ and:+ </para>+ <orderedlist numeration="arabic">+ <listitem>+ <para>+ One+ </para>+ </listitem>+ <listitem>+ <para>+ Two+ </para>+ </listitem>+ <listitem>+ <para>+ Three+ </para>+ </listitem>+ </orderedlist>+ <para>+ Loose using tabs:+ </para>+ <orderedlist numeration="arabic">+ <listitem>+ <para>+ First+ </para>+ </listitem>+ <listitem>+ <para>+ Second+ </para>+ </listitem>+ <listitem>+ <para>+ Third+ </para>+ </listitem>+ </orderedlist>+ <para>+ and using spaces:+ </para>+ <orderedlist numeration="arabic">+ <listitem>+ <para>+ One+ </para>+ </listitem>+ <listitem>+ <para>+ Two+ </para>+ </listitem>+ <listitem>+ <para>+ Three+ </para>+ </listitem>+ </orderedlist>+ <para>+ Multiple paragraphs:+ </para>+ <orderedlist numeration="arabic">+ <listitem>+ <para>+ Item 1, graf one.+ </para>+ <para>+ Item 1. graf two. The quick brown fox jumped over the lazy dog's+ back.+ </para>+ </listitem>+ <listitem>+ <para>+ Item 2.+ </para>+ </listitem>+ <listitem>+ <para>+ Item 3.+ </para>+ </listitem>+ </orderedlist>+ </section>+ <section>+ <title>Nested</title>+ <itemizedlist>+ <listitem>+ <para>+ Tab+ </para>+ <itemizedlist>+ <listitem>+ <para>+ Tab+ </para>+ <itemizedlist>+ <listitem>+ <para>+ Tab+ </para>+ </listitem>+ </itemizedlist>+ </listitem>+ </itemizedlist>+ </listitem>+ </itemizedlist>+ <para>+ Here's another:+ </para>+ <orderedlist numeration="arabic">+ <listitem>+ <para>+ First+ </para>+ </listitem>+ <listitem>+ <para>+ Second:+ </para>+ <itemizedlist>+ <listitem>+ <para>+ Fee+ </para>+ </listitem>+ <listitem>+ <para>+ Fie+ </para>+ </listitem>+ <listitem>+ <para>+ Foe+ </para>+ </listitem>+ </itemizedlist>+ </listitem>+ <listitem>+ <para>+ Third+ </para>+ </listitem>+ </orderedlist>+ <para>+ Same thing but with paragraphs:+ </para>+ <orderedlist numeration="arabic">+ <listitem>+ <para>+ First+ </para>+ </listitem>+ <listitem>+ <para>+ Second:+ </para>+ <itemizedlist>+ <listitem>+ <para>+ Fee+ </para>+ </listitem>+ <listitem>+ <para>+ Fie+ </para>+ </listitem>+ <listitem>+ <para>+ Foe+ </para>+ </listitem>+ </itemizedlist>+ </listitem>+ <listitem>+ <para>+ Third+ </para>+ </listitem>+ </orderedlist>+ </section>+ <section>+ <title>Tabs and spaces</title>+ <itemizedlist>+ <listitem>+ <para>+ this is a list item indented with tabs+ </para>+ </listitem>+ <listitem>+ <para>+ this is a list item indented with spaces+ </para>+ <itemizedlist>+ <listitem>+ <para>+ this is an example list item indented with tabs+ </para>+ </listitem>+ <listitem>+ <para>+ this is an example list item indented with spaces+ </para>+ </listitem>+ </itemizedlist>+ </listitem>+ </itemizedlist>+ </section>+ <section>+ <title>Fancy list markers</title>+ <orderedlist numeration="arabic">+ <listitem override="2">+ <para>+ begins with 2+ </para>+ </listitem>+ <listitem>+ <para>+ and now 3+ </para>+ <para>+ with a continuation+ </para>+ <orderedlist numeration="lowerroman">+ <listitem override="4">+ <para>+ sublist with roman numerals, starting with 4+ </para>+ </listitem>+ <listitem>+ <para>+ more items+ </para>+ <orderedlist numeration="upperalpha">+ <listitem>+ <para>+ a subsublist+ </para>+ </listitem>+ <listitem>+ <para>+ a subsublist+ </para>+ </listitem>+ </orderedlist>+ </listitem>+ </orderedlist>+ </listitem>+ </orderedlist>+ <para>+ Nesting:+ </para>+ <orderedlist numeration="upperalpha">+ <listitem>+ <para>+ Upper Alpha+ </para>+ <orderedlist numeration="upperroman">+ <listitem>+ <para>+ Upper Roman.+ </para>+ <orderedlist numeration="arabic">+ <listitem override="6">+ <para>+ Decimal start with 6+ </para>+ <orderedlist numeration="loweralpha">+ <listitem override="3">+ <para>+ Lower alpha with paren+ </para>+ </listitem>+ </orderedlist>+ </listitem>+ </orderedlist>+ </listitem>+ </orderedlist>+ </listitem>+ </orderedlist>+ <para>+ Autonumbering:+ </para>+ <orderedlist>+ <listitem>+ <para>+ Autonumber.+ </para>+ </listitem>+ <listitem>+ <para>+ More.+ </para>+ <orderedlist>+ <listitem>+ <para>+ Nested.+ </para>+ </listitem>+ </orderedlist>+ </listitem>+ </orderedlist>+ </section>+ </section>+ <section>+ <title>Definition Lists</title>+ <para>+ Tight using spaces:+ </para>+ <variablelist>+ <varlistentry>+ <term>+ apple+ </term>+ <listitem>+ <para>+ red fruit+ </para>+ </listitem>+ </varlistentry>+ <varlistentry>+ <term>+ orange+ </term>+ <listitem>+ <para>+ orange fruit+ </para>+ </listitem>+ </varlistentry>+ <varlistentry>+ <term>+ banana+ </term>+ <listitem>+ <para>+ yellow fruit+ </para>+ </listitem>+ </varlistentry>+ </variablelist>+ <para>+ Tight using tabs:+ </para>+ <variablelist>+ <varlistentry>+ <term>+ apple+ </term>+ <listitem>+ <para>+ red fruit+ </para>+ </listitem>+ </varlistentry>+ <varlistentry>+ <term>+ orange+ </term>+ <listitem>+ <para>+ orange fruit+ </para>+ </listitem>+ </varlistentry>+ <varlistentry>+ <term>+ banana+ </term>+ <listitem>+ <para>+ yellow fruit+ </para>+ </listitem>+ </varlistentry>+ </variablelist>+ <para>+ Loose:+ </para>+ <variablelist>+ <varlistentry>+ <term>+ apple+ </term>+ <listitem>+ <para>+ red fruit+ </para>+ </listitem>+ </varlistentry>+ <varlistentry>+ <term>+ orange+ </term>+ <listitem>+ <para>+ orange fruit+ </para>+ </listitem>+ </varlistentry>+ <varlistentry>+ <term>+ banana+ </term>+ <listitem>+ <para>+ yellow fruit+ </para>+ </listitem>+ </varlistentry>+ </variablelist>+ <para>+ Multiple blocks with italics:+ </para>+ <variablelist>+ <varlistentry>+ <term>+ <emphasis>apple</emphasis>+ </term>+ <listitem>+ <para>+ red fruit+ </para>+ <para>+ contains seeds, crisp, pleasant to taste+ </para>+ </listitem>+ </varlistentry>+ <varlistentry>+ <term>+ <emphasis>orange</emphasis>+ </term>+ <listitem>+ <para>+ orange fruit+ </para>+ <screen>+{ orange code block }+</screen>+ <blockquote>+ <para>+ orange block quote+ </para>+ </blockquote>+ </listitem>+ </varlistentry>+ </variablelist>+ </section>+ <section>+ <title>Inline Markup</title>+ <para>+ This is <emphasis>emphasized</emphasis>, and so+ <emphasis>is this</emphasis>.+ </para>+ <para>+ This is <emphasis role="strong">strong</emphasis>, and so+ <emphasis role="strong">is this</emphasis>.+ </para>+ <para>+ An <emphasis><ulink url="/url">emphasized link</ulink></emphasis>.+ </para>+ <para>+ <emphasis role="strong"><emphasis>This is strong and em.</emphasis></emphasis>+ </para>+ <para>+ So is <emphasis role="strong"><emphasis>this</emphasis></emphasis>+ word.+ </para>+ <para>+ <emphasis role="strong"><emphasis>This is strong and em.</emphasis></emphasis>+ </para>+ <para>+ So is <emphasis role="strong"><emphasis>this</emphasis></emphasis>+ word.+ </para>+ <para>+ This is code: <literal>></literal>, <literal>$</literal>,+ <literal>\</literal>, <literal>\$</literal>,+ <literal><html></literal>.+ </para>+ <para>+ <emphasis role="strikethrough">This is <emphasis>strikeout</emphasis>.</emphasis>+ </para>+ <para>+ Superscripts: a<superscript>bc</superscript>d+ a<superscript><emphasis>hello</emphasis></superscript>+ a<superscript>hello there</superscript>.+ </para>+ <para>+ Subscripts: H<subscript>2</subscript>O,+ H<subscript>23</subscript>O, H<subscript>many of them</subscript>O.+ </para>+ <para>+ These should not be superscripts or subscripts, because of the+ unescaped spaces: a^b c^d, a~b c~d.+ </para>+ </section>+ <section>+ <title>Smart quotes, ellipses, dashes</title>+ <para>+ <quote>Hello,</quote> said the spider.+ <quote><quote>Shelob</quote> is my name.</quote>+ </para>+ <para>+ <quote>A</quote>, <quote>B</quote>, and <quote>C</quote> are+ letters.+ </para>+ <para>+ <quote>Oak,</quote> <quote>elm,</quote> and <quote>beech</quote>+ are names of trees. So is <quote>pine.</quote>+ </para>+ <para>+ <quote>He said, <quote>I want to go.</quote></quote> Were you alive+ in the 70's?+ </para>+ <para>+ Here is some quoted <quote><literal>code</literal></quote> and a+ <quote><ulink url="http://example.com/?foo=1&bar=2">quoted link</ulink></quote>.+ </para>+ <para>+ Some dashes: one—two—three—four—five.+ </para>+ <para>+ Dashes between numbers: 5–7, 255–66, 1987–1999.+ </para>+ <para>+ Ellipses…and…and….+ </para>+ </section>+ <section>+ <title>LaTeX</title>+ <itemizedlist>+ <listitem>+ <para>+ <literal>\cite[22-23]{smith.1899}</literal>+ </para>+ </listitem>+ <listitem>+ <para>+ <literal>\doublespacing</literal>+ </para>+ </listitem>+ <listitem>+ <para>+ <literal>$2+2=4$</literal>+ </para>+ </listitem>+ <listitem>+ <para>+ <literal>$x \in y$</literal>+ </para>+ </listitem>+ <listitem>+ <para>+ <literal>$\alpha \wedge \omega$</literal>+ </para>+ </listitem>+ <listitem>+ <para>+ <literal>$223$</literal>+ </para>+ </listitem>+ <listitem>+ <para>+ <literal>$p$</literal>-Tree+ </para>+ </listitem>+ <listitem>+ <para>+ <literal>$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</literal>+ </para>+ </listitem>+ <listitem>+ <para>+ Here's one that has a line break in it:+ <literal>$\alpha + \omega \times x^2$</literal>.+ </para>+ </listitem>+ </itemizedlist>+ <para>+ These shouldn't be math:+ </para>+ <itemizedlist>+ <listitem>+ <para>+ To get the famous equation, write <literal>$e = mc^2$</literal>.+ </para>+ </listitem>+ <listitem>+ <para>+ $22,000 is a <emphasis>lot</emphasis> of money. So is $34,000. (It+ worked if <quote>lot</quote> is emphasized.)+ </para>+ </listitem>+ <listitem>+ <para>+ Escaped <literal>$</literal>: $73+ <emphasis>this should be emphasized</emphasis> 23$.+ </para>+ </listitem>+ </itemizedlist>+ <para>+ Here's a LaTeX table:+ </para>+ <para>+ <literal>\begin{tabular}{|l|l|}\hline+Animal & Number \\ \hline+Dog & 2 \\+Cat & 1 \\ \hline+\end{tabular}</literal>+ </para>+ </section>+ <section>+ <title>Special Characters</title>+ <para>+ Here is some unicode:+ </para>+ <itemizedlist>+ <listitem>+ <para>+ I hat: Î+ </para>+ </listitem>+ <listitem>+ <para>+ o umlaut: ö+ </para>+ </listitem>+ <listitem>+ <para>+ section: §+ </para>+ </listitem>+ <listitem>+ <para>+ set membership: ∈+ </para>+ </listitem>+ <listitem>+ <para>+ copyright: ©+ </para>+ </listitem>+ </itemizedlist>+ <para>+ AT&T has an ampersand in their name.+ </para>+ <para>+ AT&T is another way to write it.+ </para>+ <para>+ This & that.+ </para>+ <para>+ 4 < 5.+ </para>+ <para>+ 6 > 5.+ </para>+ <para>+ Backslash: \+ </para>+ <para>+ Backtick: `+ </para>+ <para>+ Asterisk: *+ </para>+ <para>+ Underscore: _+ </para>+ <para>+ Left brace: {+ </para>+ <para>+ Right brace: }+ </para>+ <para>+ Left bracket: [+ </para>+ <para>+ Right bracket: ]+ </para>+ <para>+ Left paren: (+ </para>+ <para>+ Right paren: )+ </para>+ <para>+ Greater-than: >+ </para>+ <para>+ Hash: #+ </para>+ <para>+ Period: .+ </para>+ <para>+ Bang: !+ </para>+ <para>+ Plus: ++ </para>+ <para>+ Minus: -+ </para>+ </section>+ <section>+ <title>Links</title>+ <section>+ <title>Explicit</title>+ <para>+ Just a <ulink url="/url/">URL</ulink>.+ </para>+ <para>+ <ulink url="/url/">URL and title</ulink>.+ </para>+ <para>+ <ulink url="/url/">URL and title</ulink>.+ </para>+ <para>+ <ulink url="/url/">URL and title</ulink>.+ </para>+ <para>+ <ulink url="/url/">URL and title</ulink>+ </para>+ <para>+ <ulink url="/url/">URL and title</ulink>+ </para>+ <para>+ <ulink url="/url/with_underscore">with_underscore</ulink>+ </para>+ <para>+ Email link (<email>nobody@nowhere.net</email>)+ </para>+ <para>+ <ulink url="">Empty</ulink>.+ </para>+ </section>+ <section>+ <title>Reference</title>+ <para>+ Foo <ulink url="/url/">bar</ulink>.+ </para>+ <para>+ Foo <ulink url="/url/">bar</ulink>.+ </para>+ <para>+ Foo <ulink url="/url/">bar</ulink>.+ </para>+ <para>+ With <ulink url="/url/">embedded [brackets]</ulink>.+ </para>+ <para>+ <ulink url="/url/">b</ulink> by itself should be a link.+ </para>+ <para>+ Indented <ulink url="/url">once</ulink>.+ </para>+ <para>+ Indented <ulink url="/url">twice</ulink>.+ </para>+ <para>+ Indented <ulink url="/url">thrice</ulink>.+ </para>+ <para>+ This should [not][] be a link.+ </para>+ <screen>+[not]: /url+</screen>+ <para>+ Foo <ulink url="/url/">bar</ulink>.+ </para>+ <para>+ Foo <ulink url="/url/">biz</ulink>.+ </para>+ </section>+ <section>+ <title>With ampersands</title>+ <para>+ Here's a+ <ulink url="http://example.com/?foo=1&bar=2">link with an ampersand in the URL</ulink>.+ </para>+ <para>+ Here's a link with an amersand in the link text:+ <ulink url="http://att.com/">AT&T</ulink>.+ </para>+ <para>+ Here's an <ulink url="/script?foo=1&bar=2">inline link</ulink>.+ </para>+ <para>+ Here's an+ <ulink url="/script?foo=1&bar=2">inline link in pointy braces</ulink>.+ </para>+ </section>+ <section>+ <title>Autolinks</title>+ <para>+ With an ampersand:+ <ulink url="http://example.com/?foo=1&bar=2"><literal>http://example.com/?foo=1&bar=2</literal></ulink>+ </para>+ <itemizedlist>+ <listitem>+ <para>+ In a list?+ </para>+ </listitem>+ <listitem>+ <para>+ <ulink url="http://example.com/"><literal>http://example.com/</literal></ulink>+ </para>+ </listitem>+ <listitem>+ <para>+ It should.+ </para>+ </listitem>+ </itemizedlist>+ <para>+ An e-mail address: <email>nobody@nowhere.net</email>+ </para>+ <blockquote>+ <para>+ Blockquoted:+ <ulink url="http://example.com/"><literal>http://example.com/</literal></ulink>+ </para>+ </blockquote>+ <para>+ Auto-links should not occur here:+ <literal><http://example.com/></literal>+ </para>+ <screen>+or here: <http://example.com/>+</screen>+ </section>+ </section>+ <section>+ <title>Images</title>+ <para>+ From <quote>Voyage dans la Lune</quote> by Georges Melies (1902):+ </para>+ <para>+ <inlinemediaobject>+ <imageobject>+ <objectinfo>+ <title>+ Voyage dans la Lune+ </title>+ </objectinfo>+ <imagedata fileref="lalune.jpg" />+ </imageobject>+ </inlinemediaobject>+ </para>+ <para>+ Here is a movie+ <inlinemediaobject>+ <imageobject>+ <imagedata fileref="movie.jpg" />+ </imageobject>+ </inlinemediaobject>+ icon.+ </para>+ </section>+ <section>+ <title>Footnotes</title>+ <para>+ Here is a footnote+ reference,<footnote>+ <para>+ Here is the footnote. It can go anywhere after the footnote+ reference. It need not be placed at the end of the document.+ </para>+ </footnote>+ and+ another.<footnote>+ <para>+ Here's the long note. This one contains multiple blocks.+ </para>+ <para>+ Subsequent blocks are indented to show that they belong to the+ footnote (as with list items).+ </para>+ <screen>+ { <code> }+</screen>+ <para>+ If you want, you can indent every line, but you can also be lazy+ and just indent the first line of each block.+ </para>+ </footnote>+ This should <emphasis>not</emphasis> be a footnote reference,+ because it contains a space.[^my note] Here is an inline+ note.<footnote>+ <para>+ This is <emphasis>easier</emphasis> to type. Inline notes may+ contain <ulink url="http://google.com">links</ulink> and+ <literal>]</literal> verbatim characters, as well as [bracketed+ text].+ </para>+ </footnote>+ </para>+ <blockquote>+ <para>+ Notes can go in+ quotes.<footnote>+ <para>+ In quote.+ </para>+ </footnote>+ </para>+ </blockquote>+ <orderedlist numeration="arabic">+ <listitem>+ <para>+ And in list+ items.<footnote>+ <para>+ In list.+ </para>+ </footnote>+ </para>+ </listitem>+ </orderedlist>+ <para>+ This paragraph should not be part of the note, as it is not+ indented.+ </para>+ </section>+</article>+
+ tests/writer.html view
@@ -0,0 +1,1112 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html+><head+ ><title+ >Pandoc Test Suite</title+ ><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"+ /><meta name="generator" content="pandoc"+ /><meta name="author" content="John MacFarlane"+ /><meta name="author" content="Anonymous"+ /><meta name="date" content="July 17, 2006"+ /><style type="text/css"+ >+.strikeout { text-decoration: line-through; }+ol.decimal { list-style-type: decimal; }+ol.lower-alpha { list-style-type: lower-alpha; }+ol.lower-roman { list-style-type: lower-roman; }+ol.upper-alpha { list-style-type: upper-alpha; }+ol.upper-roman { list-style-type: upper-roman; }+</style+ ></head+ ><body+ ><h1 class="title"+ >Pandoc Test Suite</h1+ ><p+ >This is a set of tests for pandoc. Most of them are adapted from John Gruber’s markdown test suite.</p+ ><hr+ /><h1 id="headers"+ >Headers</h1+ ><h2 id="level-2-with-an-embedded-link"+ >Level 2 with an <a href="/url"+ >embedded link</a+ ></h2+ ><h3 id="level-3-with-emphasis"+ >Level 3 with <em+ >emphasis</em+ ></h3+ ><h4 id="level-4"+ >Level 4</h4+ ><h5 id="level-5"+ >Level 5</h5+ ><h1 id="level-1"+ >Level 1</h1+ ><h2 id="level-2-with-emphasis"+ >Level 2 with <em+ >emphasis</em+ ></h2+ ><h3 id="level-3"+ >Level 3</h3+ ><p+ >with no blank line</p+ ><h2 id="level-2"+ >Level 2</h2+ ><p+ >with no blank line</p+ ><hr+ /><h1 id="paragraphs"+ >Paragraphs</h1+ ><p+ >Here’s a regular paragraph.</p+ ><p+ >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.</p+ ><p+ >Here’s one with a bullet. * criminey.</p+ ><p+ >There should be a hard line break<br+ />here.</p+ ><hr+ /><h1 id="block-quotes"+ >Block Quotes</h1+ ><p+ >E-mail style:</p+ ><blockquote+ ><p+ >This is a block quote. It is pretty short.</p+ ></blockquote+ ><blockquote+ ><p+ >Code in a block quote:</p+ ><pre+ ><code+ >sub status {+ print "working";+}+</code+ ></pre+ ><p+ >A list:</p+ ><ol class="decimal"+ ><li+ >item one</li+ ><li+ >item two</li+ ></ol+ ><p+ >Nested block quotes:</p+ ><blockquote+ ><p+ >nested</p+ ></blockquote+ ><blockquote+ ><p+ >nested</p+ ></blockquote+ ></blockquote+ ><p+ >This should not be a block quote: 2 > 1.</p+ ><p+ >Box-style:</p+ ><blockquote+ ><p+ >Example:</p+ ><pre+ ><code+ >sub status {+ print "working";+}+</code+ ></pre+ ></blockquote+ ><blockquote+ ><ol class="decimal"+ ><li+ >do laundry</li+ ><li+ >take out the trash</li+ ></ol+ ></blockquote+ ><p+ >Here’s a nested one:</p+ ><blockquote+ ><p+ >Joe said:</p+ ><blockquote+ ><p+ >Don’t quote me.</p+ ></blockquote+ ></blockquote+ ><p+ >And a following paragraph.</p+ ><hr+ /><h1 id="code-blocks"+ >Code Blocks</h1+ ><p+ >Code:</p+ ><pre+ ><code+ >---- (should be four hyphens)++sub status {+ print "working";+}++this code block is indented by one tab+</code+ ></pre+ ><p+ >And:</p+ ><pre+ ><code+ > this code block is indented by two tabs++These should not be escaped: \$ \\ \> \[ \{+</code+ ></pre+ ><hr+ /><h1 id="lists"+ >Lists</h1+ ><h2 id="unordered"+ >Unordered</h2+ ><p+ >Asterisks tight:</p+ ><ul+ ><li+ >asterisk 1</li+ ><li+ >asterisk 2</li+ ><li+ >asterisk 3</li+ ></ul+ ><p+ >Asterisks loose:</p+ ><ul+ ><li+ ><p+ >asterisk 1</p+ ></li+ ><li+ ><p+ >asterisk 2</p+ ></li+ ><li+ ><p+ >asterisk 3</p+ ></li+ ></ul+ ><p+ >Pluses tight:</p+ ><ul+ ><li+ >Plus 1</li+ ><li+ >Plus 2</li+ ><li+ >Plus 3</li+ ></ul+ ><p+ >Pluses loose:</p+ ><ul+ ><li+ ><p+ >Plus 1</p+ ></li+ ><li+ ><p+ >Plus 2</p+ ></li+ ><li+ ><p+ >Plus 3</p+ ></li+ ></ul+ ><p+ >Minuses tight:</p+ ><ul+ ><li+ >Minus 1</li+ ><li+ >Minus 2</li+ ><li+ >Minus 3</li+ ></ul+ ><p+ >Minuses loose:</p+ ><ul+ ><li+ ><p+ >Minus 1</p+ ></li+ ><li+ ><p+ >Minus 2</p+ ></li+ ><li+ ><p+ >Minus 3</p+ ></li+ ></ul+ ><h2 id="ordered"+ >Ordered</h2+ ><p+ >Tight:</p+ ><ol class="decimal"+ ><li+ >First</li+ ><li+ >Second</li+ ><li+ >Third</li+ ></ol+ ><p+ >and:</p+ ><ol class="decimal"+ ><li+ >One</li+ ><li+ >Two</li+ ><li+ >Three</li+ ></ol+ ><p+ >Loose using tabs:</p+ ><ol class="decimal"+ ><li+ ><p+ >First</p+ ></li+ ><li+ ><p+ >Second</p+ ></li+ ><li+ ><p+ >Third</p+ ></li+ ></ol+ ><p+ >and using spaces:</p+ ><ol class="decimal"+ ><li+ ><p+ >One</p+ ></li+ ><li+ ><p+ >Two</p+ ></li+ ><li+ ><p+ >Three</p+ ></li+ ></ol+ ><p+ >Multiple paragraphs:</p+ ><ol class="decimal"+ ><li+ ><p+ >Item 1, graf one.</p+ ><p+ >Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.</p+ ></li+ ><li+ ><p+ >Item 2.</p+ ></li+ ><li+ ><p+ >Item 3.</p+ ></li+ ></ol+ ><h2 id="nested"+ >Nested</h2+ ><ul+ ><li+ >Tab<ul+ ><li+ >Tab<ul+ ><li+ >Tab</li+ ></ul+ ></li+ ></ul+ ></li+ ></ul+ ><p+ >Here’s another:</p+ ><ol class="decimal"+ ><li+ >First</li+ ><li+ >Second:<ul+ ><li+ >Fee</li+ ><li+ >Fie</li+ ><li+ >Foe</li+ ></ul+ ></li+ ><li+ >Third</li+ ></ol+ ><p+ >Same thing but with paragraphs:</p+ ><ol class="decimal"+ ><li+ ><p+ >First</p+ ></li+ ><li+ ><p+ >Second:</p+ ><ul+ ><li+ >Fee</li+ ><li+ >Fie</li+ ><li+ >Foe</li+ ></ul+ ></li+ ><li+ ><p+ >Third</p+ ></li+ ></ol+ ><h2 id="tabs-and-spaces"+ >Tabs and spaces</h2+ ><ul+ ><li+ ><p+ >this is a list item indented with tabs</p+ ></li+ ><li+ ><p+ >this is a list item indented with spaces</p+ ><ul+ ><li+ ><p+ >this is an example list item indented with tabs</p+ ></li+ ><li+ ><p+ >this is an example list item indented with spaces</p+ ></li+ ></ul+ ></li+ ></ul+ ><h2 id="fancy-list-markers"+ >Fancy list markers</h2+ ><ol start="2" class="decimal"+ ><li+ >begins with 2</li+ ><li+ ><p+ >and now 3</p+ ><p+ >with a continuation</p+ ><ol start="4" class="lower-roman"+ ><li+ >sublist with roman numerals, starting with 4</li+ ><li+ >more items<ol class="upper-alpha"+ ><li+ >a subsublist</li+ ><li+ >a subsublist</li+ ></ol+ ></li+ ></ol+ ></li+ ></ol+ ><p+ >Nesting:</p+ ><ol class="upper-alpha"+ ><li+ >Upper Alpha<ol class="upper-roman"+ ><li+ >Upper Roman.<ol start="6" class="decimal"+ ><li+ >Decimal start with 6<ol start="3" class="lower-alpha"+ ><li+ >Lower alpha with paren</li+ ></ol+ ></li+ ></ol+ ></li+ ></ol+ ></li+ ></ol+ ><p+ >Autonumbering:</p+ ><ol+ ><li+ >Autonumber.</li+ ><li+ >More.<ol+ ><li+ >Nested.</li+ ></ol+ ></li+ ></ol+ ><hr+ /><h1 id="definition-lists"+ >Definition Lists</h1+ ><p+ >Tight using spaces:</p+ ><dl+ ><dt+ >apple</dt+ ><dd+ >red fruit</dd+ ><dt+ >orange</dt+ ><dd+ >orange fruit</dd+ ><dt+ >banana</dt+ ><dd+ >yellow fruit</dd+ ></dl+ ><p+ >Tight using tabs:</p+ ><dl+ ><dt+ >apple</dt+ ><dd+ >red fruit</dd+ ><dt+ >orange</dt+ ><dd+ >orange fruit</dd+ ><dt+ >banana</dt+ ><dd+ >yellow fruit</dd+ ></dl+ ><p+ >Loose:</p+ ><dl+ ><dt+ >apple</dt+ ><dd+ ><p+ >red fruit</p+ ></dd+ ><dt+ >orange</dt+ ><dd+ ><p+ >orange fruit</p+ ></dd+ ><dt+ >banana</dt+ ><dd+ ><p+ >yellow fruit</p+ ></dd+ ></dl+ ><p+ >Multiple blocks with italics:</p+ ><dl+ ><dt+ ><em+ >apple</em+ ></dt+ ><dd+ ><p+ >red fruit</p+ ><p+ >contains seeds, crisp, pleasant to taste</p+ ></dd+ ><dt+ ><em+ >orange</em+ ></dt+ ><dd+ ><p+ >orange fruit</p+ ><pre+ ><code+ >{ orange code block }+</code+ ></pre+ ><blockquote+ ><p+ >orange block quote</p+ ></blockquote+ ></dd+ ></dl+ ><h1 id="html-blocks"+ >HTML Blocks</h1+ ><p+ >Simple block on one line:</p+ ><div>foo</div>+<p+ >And nested without indentation:</p+ ><div>+<div>+<div>foo</div>+</div>+<div>bar</div>+</div>+<p+ >Interpreted markdown in a table:</p+ ><table>+<tr>+<td>This is <em+ >emphasized</em+ ></td>+<td>And this is <strong+ >strong</strong+ ></td>+</tr>+</table>++<script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>+<p+ >Here’s a simple block:</p+ ><div>+ foo</div>+<p+ >This should be a code block, though:</p+ ><pre+ ><code+ ><div>+ foo+</div>+</code+ ></pre+ ><p+ >As should this:</p+ ><pre+ ><code+ ><div>foo</div>+</code+ ></pre+ ><p+ >Now, nested:</p+ ><div>+ <div>+ <div>+ foo</div>+ </div>+</div>+<p+ >This should just be an HTML comment:</p+ ><!-- Comment -->+<p+ >Multiline:</p+ ><!--+Blah+Blah+-->++<!--+ This is another comment.+-->+<p+ >Code block:</p+ ><pre+ ><code+ ><!-- Comment -->+</code+ ></pre+ ><p+ >Just plain comment, with trailing spaces on the line:</p+ ><!-- foo --> +<p+ >Code:</p+ ><pre+ ><code+ ><hr />+</code+ ></pre+ ><p+ >Hr’s:</p+ ><hr>++<hr />++<hr />++<hr> ++<hr /> ++<hr /> ++<hr class="foo" id="bar" />++<hr class="foo" id="bar" />++<hr class="foo" id="bar">+<hr+ /><h1 id="inline-markup"+ >Inline Markup</h1+ ><p+ >This is <em+ >emphasized</em+ >, and so <em+ >is this</em+ >.</p+ ><p+ >This is <strong+ >strong</strong+ >, and so <strong+ >is this</strong+ >.</p+ ><p+ >An <em+ ><a href="/url"+ >emphasized link</a+ ></em+ >.</p+ ><p+ ><strong+ ><em+ >This is strong and em.</em+ ></strong+ ></p+ ><p+ >So is <strong+ ><em+ >this</em+ ></strong+ > word.</p+ ><p+ ><strong+ ><em+ >This is strong and em.</em+ ></strong+ ></p+ ><p+ >So is <strong+ ><em+ >this</em+ ></strong+ > word.</p+ ><p+ >This is code: <code+ >></code+ >, <code+ >$</code+ >, <code+ >\</code+ >, <code+ >\$</code+ >, <code+ ><html></code+ >.</p+ ><p+ ><span class="strikeout"+ >This is <em+ >strikeout</em+ >.</span+ ></p+ ><p+ >Superscripts: a<sup+ >bc</sup+ >d a<sup+ ><em+ >hello</em+ ></sup+ > a<sup+ >hello there</sup+ >.</p+ ><p+ >Subscripts: H<sub+ >2</sub+ >O, H<sub+ >23</sub+ >O, H<sub+ >many of them</sub+ >O.</p+ ><p+ >These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.</p+ ><hr+ /><h1 id="smart-quotes-ellipses-dashes"+ >Smart quotes, ellipses, dashes</h1+ ><p+ >“Hello,” said the spider. “‘Shelob’ is my name.”</p+ ><p+ >‘A’, ‘B’, and ‘C’ are letters.</p+ ><p+ >‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’</p+ ><p+ >‘He said, “I want to go.”’ Were you alive in the 70’s?</p+ ><p+ >Here is some quoted ‘<code+ >code</code+ >’ and a “<a href="http://example.com/?foo=1&bar=2"+ >quoted link</a+ >”.</p+ ><p+ >Some dashes: one—two—three—four—five.</p+ ><p+ >Dashes between numbers: 5–7, 255–66, 1987–1999.</p+ ><p+ >Ellipses…and…and….</p+ ><hr+ /><h1 id="latex"+ >LaTeX</h1+ ><ul+ ><li+ >\cite[22-23]{smith.1899}</li+ ><li+ >\doublespacing</li+ ><li+ >$2+2=4$</li+ ><li+ >$x \in y$</li+ ><li+ >$\alpha \wedge \omega$</li+ ><li+ >$223$</li+ ><li+ >$p$-Tree</li+ ><li+ >$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</li+ ><li+ >Here’s one that has a line break in it: $\alpha + \omega \times x^2$.</li+ ></ul+ ><p+ >These shouldn’t be math:</p+ ><ul+ ><li+ >To get the famous equation, write <code+ >$e = mc^2$</code+ >.</li+ ><li+ >$22,000 is a <em+ >lot</em+ > of money. So is $34,000. (It worked if “lot” is emphasized.)</li+ ><li+ >Escaped <code+ >$</code+ >: $73 <em+ >this should be emphasized</em+ > 23$.</li+ ></ul+ ><p+ >Here’s a LaTeX table:</p+ ><p+ >\begin{tabular}{|l|l|}\hline+Animal & Number \\ \hline+Dog & 2 \\+Cat & 1 \\ \hline+\end{tabular}</p+ ><hr+ /><h1 id="special-characters"+ >Special Characters</h1+ ><p+ >Here is some unicode:</p+ ><ul+ ><li+ >I hat: Î</li+ ><li+ >o umlaut: ö</li+ ><li+ >section: §</li+ ><li+ >set membership: ∈</li+ ><li+ >copyright: ©</li+ ></ul+ ><p+ >AT&T has an ampersand in their name.</p+ ><p+ >AT&T is another way to write it.</p+ ><p+ >This & that.</p+ ><p+ >4 < 5.</p+ ><p+ >6 > 5.</p+ ><p+ >Backslash: \</p+ ><p+ >Backtick: `</p+ ><p+ >Asterisk: *</p+ ><p+ >Underscore: _</p+ ><p+ >Left brace: {</p+ ><p+ >Right brace: }</p+ ><p+ >Left bracket: [</p+ ><p+ >Right bracket: ]</p+ ><p+ >Left paren: (</p+ ><p+ >Right paren: )</p+ ><p+ >Greater-than: ></p+ ><p+ >Hash: #</p+ ><p+ >Period: .</p+ ><p+ >Bang: !</p+ ><p+ >Plus: +</p+ ><p+ >Minus: -</p+ ><hr+ /><h1 id="links"+ >Links</h1+ ><h2 id="explicit"+ >Explicit</h2+ ><p+ >Just a <a href="/url/"+ >URL</a+ >.</p+ ><p+ ><a href="/url/" title="title"+ >URL and title</a+ >.</p+ ><p+ ><a href="/url/" title="title preceded by two spaces"+ >URL and title</a+ >.</p+ ><p+ ><a href="/url/" title="title preceded by a tab"+ >URL and title</a+ >.</p+ ><p+ ><a href="/url/" title="title with "quotes" in it"+ >URL and title</a+ ></p+ ><p+ ><a href="/url/" title="title with single quotes"+ >URL and title</a+ ></p+ ><p+ ><a href="/url/with_underscore"+ >with_underscore</a+ ></p+ ><p+ ><script type="text/javascript"+ >+<!--+h='nowhere.net';a='@';n='nobody';e=n+a+h;+document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'">'+'Email link'+'<\/'+'a'+'>');+// -->+</script+ ><noscript+ >Email link (nobody at nowhere dot net)</noscript+ ></p+ ><p+ ><a href=""+ >Empty</a+ >.</p+ ><h2 id="reference"+ >Reference</h2+ ><p+ >Foo <a href="/url/"+ >bar</a+ >.</p+ ><p+ >Foo <a href="/url/"+ >bar</a+ >.</p+ ><p+ >Foo <a href="/url/"+ >bar</a+ >.</p+ ><p+ >With <a href="/url/"+ >embedded [brackets]</a+ >.</p+ ><p+ ><a href="/url/"+ >b</a+ > by itself should be a link.</p+ ><p+ >Indented <a href="/url"+ >once</a+ >.</p+ ><p+ >Indented <a href="/url"+ >twice</a+ >.</p+ ><p+ >Indented <a href="/url"+ >thrice</a+ >.</p+ ><p+ >This should [not][] be a link.</p+ ><pre+ ><code+ >[not]: /url+</code+ ></pre+ ><p+ >Foo <a href="/url/" title="Title with "quotes" inside"+ >bar</a+ >.</p+ ><p+ >Foo <a href="/url/" title="Title with "quote" inside"+ >biz</a+ >.</p+ ><h2 id="with-ampersands"+ >With ampersands</h2+ ><p+ >Here’s a <a href="http://example.com/?foo=1&bar=2"+ >link with an ampersand in the URL</a+ >.</p+ ><p+ >Here’s a link with an amersand in the link text: <a href="http://att.com/" title="AT&T"+ >AT&T</a+ >.</p+ ><p+ >Here’s an <a href="/script?foo=1&bar=2"+ >inline link</a+ >.</p+ ><p+ >Here’s an <a href="/script?foo=1&bar=2"+ >inline link in pointy braces</a+ >.</p+ ><h2 id="autolinks"+ >Autolinks</h2+ ><p+ >With an ampersand: <a href="http://example.com/?foo=1&bar=2"+ ><code+ >http://example.com/?foo=1&bar=2</code+ ></a+ ></p+ ><ul+ ><li+ >In a list?</li+ ><li+ ><a href="http://example.com/"+ ><code+ >http://example.com/</code+ ></a+ ></li+ ><li+ >It should.</li+ ></ul+ ><p+ >An e-mail address: <script type="text/javascript"+ >+<!--+h='nowhere.net';a='@';n='nobody';e=n+a+h;+document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'">'+'<code>'+e+'</code>'+'<\/'+'a'+'>');+// -->+</script+ ><noscript+ >nobody at nowhere dot net</noscript+ ></p+ ><blockquote+ ><p+ >Blockquoted: <a href="http://example.com/"+ ><code+ >http://example.com/</code+ ></a+ ></p+ ></blockquote+ ><p+ >Auto-links should not occur here: <code+ ><http://example.com/></code+ ></p+ ><pre+ ><code+ >or here: <http://example.com/>+</code+ ></pre+ ><hr+ /><h1 id="images"+ >Images</h1+ ><p+ >From “Voyage dans la Lune” by Georges Melies (1902):</p+ ><p+ ><img src="lalune.jpg" title="Voyage dans la Lune" alt="lalune"+ /></p+ ><p+ >Here is a movie <img src="movie.jpg" title="" alt="movie"+ /> icon.</p+ ><hr+ /><h1 id="footnotes"+ >Footnotes</h1+ ><p+ >Here is a footnote reference,<a href="#fn1" class="footnoteRef" id="fnref1"+ ><sup+ >1</sup+ ></a+ > and another.<a href="#fn2" class="footnoteRef" id="fnref2"+ ><sup+ >2</sup+ ></a+ > This should <em+ >not</em+ > be a footnote reference, because it contains a space.[^my note] Here is an inline note.<a href="#fn3" class="footnoteRef" id="fnref3"+ ><sup+ >3</sup+ ></a+ ></p+ ><blockquote+ ><p+ >Notes can go in quotes.<a href="#fn4" class="footnoteRef" id="fnref4"+ ><sup+ >4</sup+ ></a+ ></p+ ></blockquote+ ><ol class="decimal"+ ><li+ >And in list items.<a href="#fn5" class="footnoteRef" id="fnref5"+ ><sup+ >5</sup+ ></a+ ></li+ ></ol+ ><p+ >This paragraph should not be part of the note, as it is not indented.</p+ ><div class="footnotes"+ ><hr+ /><ol+ ><li id="fn1"+ ><p+ >Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document. <a href="#fnref1" class="footnoteBackLink" title="Jump back to footnote 1">↩</a></p+ ></li+ ><li id="fn2"+ ><p+ >Here’s the long note. This one contains multiple blocks.</p+ ><p+ >Subsequent blocks are indented to show that they belong to the footnote (as with list items).</p+ ><pre+ ><code+ > { <code> }+</code+ ></pre+ ><p+ >If you want, you can indent every line, but you can also be lazy and just indent the first line of each block. <a href="#fnref2" class="footnoteBackLink" title="Jump back to footnote 2">↩</a></p+ ></li+ ><li id="fn3"+ ><p+ >This is <em+ >easier</em+ > to type. Inline notes may contain <a href="http://google.com"+ >links</a+ > and <code+ >]</code+ > verbatim characters, as well as [bracketed text]. <a href="#fnref3" class="footnoteBackLink" title="Jump back to footnote 3">↩</a></p+ ></li+ ><li id="fn4"+ ><p+ >In quote. <a href="#fnref4" class="footnoteBackLink" title="Jump back to footnote 4">↩</a></p+ ></li+ ><li id="fn5"+ ><p+ >In list. <a href="#fnref5" class="footnoteBackLink" title="Jump back to footnote 5">↩</a></p+ ></li+ ></ol+ ></div+ ></body+ ></html+>+
+ tests/writer.latex view
@@ -0,0 +1,690 @@+\documentclass{article}+\usepackage[mathletters]{ucs}+\usepackage[utf8x]{inputenc}+\setlength{\parindent}{0pt}+\setlength{\parskip}{6pt plus 2pt minus 1pt}+\newcommand{\textsubscript}[1]{\ensuremath{_{\scriptsize\textrm{#1}}}}+\usepackage[breaklinks=true]{hyperref}+\usepackage[normalem]{ulem}+\usepackage{enumerate}+\usepackage{fancyvrb}+\usepackage{graphicx}+\setcounter{secnumdepth}{0}+\VerbatimFootnotes % allows verbatim text in footnotes+\title{Pandoc Test Suite}+\author{John MacFarlane\\Anonymous}+\date{July 17, 2006}+\begin{document}+\maketitle++This is a set of tests for pandoc. Most of them are adapted from John Gruber's markdown test suite.++\begin{center}\rule{3in}{0.4pt}\end{center}++\section{Headers}++\subsection{Level 2 with an \href{/url}{embedded link}}++\subsubsection{Level 3 with \emph{emphasis}}++Level 4++Level 5++\section{Level 1}++\subsection{Level 2 with \emph{emphasis}}++\subsubsection{Level 3}++with no blank line++\subsection{Level 2}++with no blank line++\begin{center}\rule{3in}{0.4pt}\end{center}++\section{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.++Here's one with a bullet. * criminey.++There should be a hard line break\\+here.++\begin{center}\rule{3in}{0.4pt}\end{center}++\section{Block Quotes}++E-mail style:++\begin{quote}+This is a block quote. It is pretty short.++\end{quote}+\begin{quote}+Code in a block quote:++\begin{verbatim}+sub status {+ print "working";+}+\end{verbatim}+A list:++\begin{enumerate}[1.]+\item item one+\item item two+\end{enumerate}+Nested block quotes:++\begin{quote}+nested++\end{quote}+\begin{quote}+nested++\end{quote}+\end{quote}+This should not be a block quote: 2 \textgreater{} 1.++Box-style:++\begin{quote}+Example:++\begin{verbatim}+sub status {+ print "working";+}+\end{verbatim}+\end{quote}+\begin{quote}+\begin{enumerate}[1.]+\item do laundry+\item take out the trash+\end{enumerate}+\end{quote}+Here's a nested one:++\begin{quote}+Joe said:++\begin{quote}+Don't quote me.++\end{quote}+\end{quote}+And a following paragraph.++\begin{center}\rule{3in}{0.4pt}\end{center}++\section{Code Blocks}++Code:++\begin{verbatim}+---- (should be four hyphens)++sub status {+ print "working";+}++this code block is indented by one tab+\end{verbatim}+And:++\begin{verbatim}+ this code block is indented by two tabs++These should not be escaped: \$ \\ \> \[ \{+\end{verbatim}+\begin{center}\rule{3in}{0.4pt}\end{center}++\section{Lists}++\subsection{Unordered}++Asterisks tight:++\begin{itemize}+\item asterisk 1+\item asterisk 2+\item asterisk 3+\end{itemize}+Asterisks loose:++\begin{itemize}+\item asterisk 1++\item asterisk 2++\item asterisk 3++\end{itemize}+Pluses tight:++\begin{itemize}+\item Plus 1+\item Plus 2+\item Plus 3+\end{itemize}+Pluses loose:++\begin{itemize}+\item Plus 1++\item Plus 2++\item Plus 3++\end{itemize}+Minuses tight:++\begin{itemize}+\item Minus 1+\item Minus 2+\item Minus 3+\end{itemize}+Minuses loose:++\begin{itemize}+\item Minus 1++\item Minus 2++\item Minus 3++\end{itemize}+\subsection{Ordered}++Tight:++\begin{enumerate}[1.]+\item First+\item Second+\item Third+\end{enumerate}+and:++\begin{enumerate}[1.]+\item One+\item Two+\item Three+\end{enumerate}+Loose using tabs:++\begin{enumerate}[1.]+\item First++\item Second++\item Third++\end{enumerate}+and using spaces:++\begin{enumerate}[1.]+\item One++\item Two++\item Three++\end{enumerate}+Multiple paragraphs:++\begin{enumerate}[1.]+\item Item 1, graf one.++Item 1. graf two. The quick brown fox jumped over the lazy dog's back.++\item Item 2.++\item Item 3.++\end{enumerate}+\subsection{Nested}++\begin{itemize}+\item Tab+\begin{itemize}+\item Tab+\begin{itemize}+\item Tab+\end{itemize}+\end{itemize}+\end{itemize}+Here's another:++\begin{enumerate}[1.]+\item First+\item Second:+\begin{itemize}+\item Fee+\item Fie+\item Foe+\end{itemize}+\item Third+\end{enumerate}+Same thing but with paragraphs:++\begin{enumerate}[1.]+\item First++\item Second:++\begin{itemize}+\item Fee+\item Fie+\item Foe+\end{itemize}+\item Third++\end{enumerate}+\subsection{Tabs and spaces}++\begin{itemize}+\item this is a list item indented with tabs++\item this is a list item indented with spaces++\begin{itemize}+\item this is an example list item indented with tabs++\item this is an example list item indented with spaces++\end{itemize}+\end{itemize}+\subsection{Fancy list markers}++\begin{enumerate}[(1)]+\setcounter{enumi}{1}+\item begins with 2+\item and now 3++with a continuation++\begin{enumerate}[i.]+\setcounter{enumii}{3}+\item sublist with roman numerals, starting with 4+\item more items+\begin{enumerate}[(A)]+\item a subsublist+\item a subsublist+\end{enumerate}+\end{enumerate}+\end{enumerate}+Nesting:++\begin{enumerate}[A.]+\item Upper Alpha+\begin{enumerate}[I.]+\item Upper Roman.+\begin{enumerate}[(1)]+\setcounter{enumiii}{5}+\item Decimal start with 6+\begin{enumerate}[a)]+\setcounter{enumiv}{2}+\item Lower alpha with paren+\end{enumerate}+\end{enumerate}+\end{enumerate}+\end{enumerate}+Autonumbering:++\begin{enumerate}+\item Autonumber.+\item More.+\begin{enumerate}+\item Nested.+\end{enumerate}+\end{enumerate}+\begin{center}\rule{3in}{0.4pt}\end{center}++\section{Definition Lists}++Tight using spaces:++\begin{description}+\item[apple] red fruit+\item[orange] orange fruit+\item[banana] yellow fruit+\end{description}+Tight using tabs:++\begin{description}+\item[apple] red fruit+\item[orange] orange fruit+\item[banana] yellow fruit+\end{description}+Loose:++\begin{description}+\item[apple] red fruit++\item[orange] orange fruit++\item[banana] yellow fruit++\end{description}+Multiple blocks with italics:++\begin{description}+\item[\emph{apple}] red fruit++contains seeds, crisp, pleasant to taste++\item[\emph{orange}] orange fruit++\begin{verbatim}+{ orange code block }+\end{verbatim}+\begin{quote}+orange block quote++\end{quote}+\end{description}+\section{HTML Blocks}++Simple block on one line:++foo+And nested without indentation:++foo+bar+Interpreted markdown in a table:++This is \emph{emphasized}+And this is \textbf{strong}+Here's a simple block:++foo+This should be a code block, though:++\begin{verbatim}+<div>+ foo+</div>+\end{verbatim}+As should this:++\begin{verbatim}+<div>foo</div>+\end{verbatim}+Now, nested:++foo+This should just be an HTML comment:++Multiline:++Code block:++\begin{verbatim}+<!-- Comment -->+\end{verbatim}+Just plain comment, with trailing spaces on the line:++Code:++\begin{verbatim}+<hr />+\end{verbatim}+Hr's:++\begin{center}\rule{3in}{0.4pt}\end{center}++\section{Inline Markup}++This is \emph{emphasized}, and so \emph{is this}.++This is \textbf{strong}, and so \textbf{is this}.++An \emph{\href{/url}{emphasized link}}.++\textbf{\emph{This is strong and em.}}++So is \textbf{\emph{this}} word.++\textbf{\emph{This is strong and em.}}++So is \textbf{\emph{this}} word.++This is code: \verb!>!, \verb!$!, \verb!\!, \verb!\$!, \verb!<html>!.++\sout{This is \emph{strikeout}.}++Superscripts: a\textsuperscript{bc}d a\textsuperscript{\emph{hello}} a\textsuperscript{hello there}.++Subscripts: H\textsubscript{2}O, H\textsubscript{23}O, H\textsubscript{many of them}O.++These should not be superscripts or subscripts, because of the unescaped spaces: a\^{}b c\^{}d, a\ensuremath{\sim}b c\ensuremath{\sim}d.++\begin{center}\rule{3in}{0.4pt}\end{center}++\section{Smart quotes, ellipses, dashes}++``Hello,'' said the spider. ``\,`Shelob' is my name.''++`A', `B', and `C' are letters.++`Oak,' `elm,' and `beech' are names of trees. So is `pine.'++`He said, ``I want to go.''\,' Were you alive in the 70's?++Here is some quoted `\verb!code!' and a ``\href{http://example.com/?foo=1&bar=2}{quoted link}''.++Some dashes: one---two---three---four---five.++Dashes between numbers: 5--7, 255--66, 1987--1999.++Ellipses\ldots{}and\ldots{}and\ldots{}.++\begin{center}\rule{3in}{0.4pt}\end{center}++\section{LaTeX}++\begin{itemize}+\item \cite[22-23]{smith.1899}+\item \doublespacing+\item $2+2=4$+\item $x \in y$+\item $\alpha \wedge \omega$+\item $223$+\item $p$-Tree+\item $\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$+\item Here's one that has a line break in it: $\alpha + \omega \times x^2$.+\end{itemize}+These shouldn't be math:++\begin{itemize}+\item To get the famous equation, write \verb!$e = mc^2$!.+\item \$22,000 is a \emph{lot} of money. So is \$34,000. (It worked if ``lot'' is emphasized.)+\item Escaped \verb!$!: \$73 \emph{this should be emphasized} 23\$.+\end{itemize}+Here's a LaTeX table:++\begin{tabular}{|l|l|}\hline+Animal & Number \\ \hline+Dog & 2 \\+Cat & 1 \\ \hline+\end{tabular}++\begin{center}\rule{3in}{0.4pt}\end{center}++\section{Special Characters}++Here is some unicode:++\begin{itemize}+\item I hat: Î+\item o umlaut: ö+\item section: §+\item set membership: ∈+\item copyright: ©+\end{itemize}+AT\&T has an ampersand in their name.++AT\&T is another way to write it.++This \& that.++4 \textless{} 5.++6 \textgreater{} 5.++Backslash: \textbackslash{}++Backtick: `++Asterisk: *++Underscore: \_++Left brace: \{++Right brace: \}++Left bracket: [++Right bracket: ]++Left paren: (++Right paren: )++Greater-than: \textgreater{}++Hash: \#++Period: .++Bang: !++Plus: +++Minus: -++\begin{center}\rule{3in}{0.4pt}\end{center}++\section{Links}++\subsection{Explicit}++Just a \href{/url/}{URL}.++\href{/url/}{URL and title}.++\href{/url/}{URL and title}.++\href{/url/}{URL and title}.++\href{/url/}{URL and title}++\href{/url/}{URL and title}++\href{/url/with_underscore}{with\_underscore}++\href{mailto:nobody@nowhere.net}{Email link}++\href{}{Empty}.++\subsection{Reference}++Foo \href{/url/}{bar}.++Foo \href{/url/}{bar}.++Foo \href{/url/}{bar}.++With \href{/url/}{embedded [brackets]}.++\href{/url/}{b} by itself should be a link.++Indented \href{/url}{once}.++Indented \href{/url}{twice}.++Indented \href{/url}{thrice}.++This should [not][] be a link.++\begin{verbatim}+[not]: /url+\end{verbatim}+Foo \href{/url/}{bar}.++Foo \href{/url/}{biz}.++\subsection{With ampersands}++Here's a \href{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: \href{http://att.com/}{AT\&T}.++Here's an \href{/script?foo=1&bar=2}{inline link}.++Here's an \href{/script?foo=1&bar=2}{inline link in pointy braces}.++\subsection{Autolinks}++With an ampersand: \url{http://example.com/?foo=1&bar=2}++\begin{itemize}+\item In a list?+\item \url{http://example.com/}+\item It should.+\end{itemize}+An e-mail address: \href{mailto:nobody@nowhere.net}{\texttt{nobody@nowhere.net}}++\begin{quote}+Blockquoted: \url{http://example.com/}++\end{quote}+Auto-links should not occur here: \verb!<http://example.com/>!++\begin{verbatim}+or here: <http://example.com/>+\end{verbatim}+\begin{center}\rule{3in}{0.4pt}\end{center}++\section{Images}++From ``Voyage dans la Lune'' by Georges Melies (1902):++\includegraphics{lalune.jpg}++Here is a movie \includegraphics{movie.jpg} icon.++\begin{center}\rule{3in}{0.4pt}\end{center}++\section{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).++\begin{Verbatim}+ { <code> }+\end{Verbatim}+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 \href{http://google.com}{links} and \verb!]! verbatim characters, as well as [bracketed text].}++\begin{quote}+Notes can go in quotes.\footnote{In quote.}++\end{quote}+\begin{enumerate}[1.]+\item And in list items.\footnote{In list.}+\end{enumerate}+This paragraph should not be part of the note, as it is not indented.+++\end{document}+
+ tests/writer.man view
@@ -0,0 +1,804 @@+.TH Pandoc "" "July 17, 2006" "Test Suite"+.PP+This is a set of tests for pandoc\. Most of them are adapted from+John Gruber's markdown test suite\.+.PP+ * * * * *+.SH Headers+.SS Level 2 with an embedded link (/url)+.SS Level 3 with \f[I]emphasis\f[]+.SS Level 4+.SS Level 5+.SH Level 1+.SS Level 2 with \f[I]emphasis\f[]+.SS Level 3+.PP+with no blank line+.SS Level 2+.PP+with no blank line+.PP+ * * * * *+.SH Paragraphs+.PP+Here's a regular paragraph\.+.PP+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\.+.PP+Here's one with a bullet\. * criminey\.+.PP+There should be a hard line break+.PD 0+.P+.PD+here\.+.PP+ * * * * *+.SH Block Quotes+.PP+E-mail style:+.RS+.PP+This is a block quote\. It is pretty short\.+.RE+.RS+.PP+Code in a block quote:+.PP+\f[CR]+ sub\ status\ {+ \ \ \ \ print\ \"working\";+ }+\f[]+.PP+A list:+.IP "1." 3+item one+.IP "2." 3+item two+.PP+Nested block quotes:+.RS+.PP+nested+.RE+.RS+.PP+nested+.RE+.RE+.PP+This should not be a block quote: 2 > 1\.+.PP+Box-style:+.RS+.PP+Example:+.PP+\f[CR]+ sub\ status\ {+ \ \ \ \ print\ \"working\";+ }+\f[]+.RE+.RS+.IP "1." 3+do laundry+.IP "2." 3+take out the trash+.RE+.PP+Here's a nested one:+.RS+.PP+Joe said:+.RS+.PP+Don't quote me\.+.RE+.RE+.PP+And a following paragraph\.+.PP+ * * * * *+.SH Code Blocks+.PP+Code:+.PP+\f[CR]+ ----\ (should\ be\ four\ hyphens)+ + sub\ status\ {+ \ \ \ \ print\ \"working\";+ }+ + this\ code\ block\ is\ indented\ by\ one\ tab+\f[]+.PP+And:+.PP+\f[CR]+ \ \ \ \ this\ code\ block\ is\ indented\ by\ two\ tabs+ + These\ should\ not\ be\ escaped:\ \ \\$\ \\\\\ \\>\ \\[\ \\{+\f[]+.PP+ * * * * *+.SH Lists+.SS Unordered+.PP+Asterisks tight:+.IP \[bu] 2+asterisk 1+.IP \[bu] 2+asterisk 2+.IP \[bu] 2+asterisk 3+.PP+Asterisks loose:+.IP \[bu] 2+asterisk 1+.IP \[bu] 2+asterisk 2+.IP \[bu] 2+asterisk 3+.PP+Pluses tight:+.IP \[bu] 2+Plus 1+.IP \[bu] 2+Plus 2+.IP \[bu] 2+Plus 3+.PP+Pluses loose:+.IP \[bu] 2+Plus 1+.IP \[bu] 2+Plus 2+.IP \[bu] 2+Plus 3+.PP+Minuses tight:+.IP \[bu] 2+Minus 1+.IP \[bu] 2+Minus 2+.IP \[bu] 2+Minus 3+.PP+Minuses loose:+.IP \[bu] 2+Minus 1+.IP \[bu] 2+Minus 2+.IP \[bu] 2+Minus 3+.SS Ordered+.PP+Tight:+.IP "1." 3+First+.IP "2." 3+Second+.IP "3." 3+Third+.PP+and:+.IP "1." 3+One+.IP "2." 3+Two+.IP "3." 3+Three+.PP+Loose using tabs:+.IP "1." 3+First+.IP "2." 3+Second+.IP "3." 3+Third+.PP+and using spaces:+.IP "1." 3+One+.IP "2." 3+Two+.IP "3." 3+Three+.PP+Multiple paragraphs:+.IP "1." 3+Item 1, graf one\.+.RS 4+.PP+Item 1\. graf two\. The quick brown fox jumped over the lazy dog's+back\.+.RE+.IP "2." 3+Item 2\.+.IP "3." 3+Item 3\.+.SS Nested+.IP \[bu] 2+Tab+.RS 2+.IP \[bu] 2+Tab+.RS 2+.IP \[bu] 2+Tab+.RE+.RE+.PP+Here's another:+.IP "1." 3+First+.IP "2." 3+Second:+.RS 4+.IP \[bu] 2+Fee+.IP \[bu] 2+Fie+.IP \[bu] 2+Foe+.RE+.IP "3." 3+Third+.PP+Same thing but with paragraphs:+.IP "1." 3+First+.IP "2." 3+Second:+.RS 4+.IP \[bu] 2+Fee+.IP \[bu] 2+Fie+.IP \[bu] 2+Foe+.RE+.IP "3." 3+Third+.SS Tabs and spaces+.IP \[bu] 2+this is a list item indented with tabs+.IP \[bu] 2+this is a list item indented with spaces+.RS 2+.IP \[bu] 2+this is an example list item indented with tabs+.IP \[bu] 2+this is an example list item indented with spaces+.RE+.SS Fancy list markers+.IP "(2)" 4+begins with 2+.IP "(3)" 4+and now 3+.RS 4+.PP+with a continuation+.IP "iv." 4+sublist with roman numerals, starting with 4+.IP " v." 4+more items+.RS 4+.IP "(A)" 4+a subsublist+.IP "(B)" 4+a subsublist+.RE+.RE+.PP+Nesting:+.IP "A." 3+Upper Alpha+.RS 4+.IP "I." 3+Upper Roman\.+.RS 4+.IP "(6)" 4+Decimal start with 6+.RS 4+.IP "c)" 3+Lower alpha with paren+.RE+.RE+.RE+.PP+Autonumbering:+.IP "1." 3+Autonumber\.+.IP "2." 3+More\.+.RS 4+.IP "1." 3+Nested\.+.RE+.PP+ * * * * *+.SH Definition Lists+.PP+Tight using spaces:+.TP+.B apple+red fruit+.RS+.RE+.TP+.B orange+orange fruit+.RS+.RE+.TP+.B banana+yellow fruit+.RS+.RE+.PP+Tight using tabs:+.TP+.B apple+red fruit+.RS+.RE+.TP+.B orange+orange fruit+.RS+.RE+.TP+.B banana+yellow fruit+.RS+.RE+.PP+Loose:+.TP+.B apple+red fruit+.RS+.RE+.TP+.B orange+orange fruit+.RS+.RE+.TP+.B banana+yellow fruit+.RS+.RE+.PP+Multiple blocks with italics:+.TP+.B \f[I]apple\f[]+red fruit+.RS+.PP+contains seeds, crisp, pleasant to taste+.RE+.TP+.B \f[I]orange\f[]+orange fruit+.RS+.PP+\f[CR]+ {\ orange\ code\ block\ }+\f[]+.RS+.PP+orange block quote+.RE+.RE+.SH HTML Blocks+.PP+Simple block on one line:+<div>+foo+</div>++.PP+And nested without indentation:+<div>+<div>+<div>+foo+</div>+</div>+<div>+bar+</div>+</div>++.PP+Interpreted markdown in a table:+<table>+<tr>+<td>+This is \f[I]emphasized\f[]+</td>+<td>+And this is \f[B]strong\f[]+</td>+</tr>+</table>++<script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>++.PP+Here's a simple block:+<div>+ +foo+</div>++.PP+This should be a code block, though:+.PP+\f[CR]+ <div>+ \ \ \ \ foo+ </div>+\f[]+.PP+As should this:+.PP+\f[CR]+ <div>foo</div>+\f[]+.PP+Now, nested:+<div>+ <div>+ <div>+ +foo+</div>+ </div>+</div>++.PP+This should just be an HTML comment:+<!-- Comment -->++.PP+Multiline:+<!--+Blah+Blah+-->++<!--+ This is another comment.+-->++.PP+Code block:+.PP+\f[CR]+ <!--\ Comment\ -->+\f[]+.PP+Just plain comment, with trailing spaces on the line:+<!-- foo --> ++.PP+Code:+.PP+\f[CR]+ <hr\ />+\f[]+.PP+Hr's:+<hr>++<hr />++<hr />++<hr> ++<hr /> ++<hr /> ++<hr class="foo" id="bar" />++<hr class="foo" id="bar" />++<hr class="foo" id="bar">++.PP+ * * * * *+.SH Inline Markup+.PP+This is \f[I]emphasized\f[], and so \f[I]is this\f[]\.+.PP+This is \f[B]strong\f[], and so \f[B]is this\f[]\.+.PP+An \f[I]emphasized link (/url)\f[]\.+.PP+\f[B]\f[I]This is strong and em\.\f[]\f[]+.PP+So is \f[B]\f[I]this\f[]\f[] word\.+.PP+\f[B]\f[I]This is strong and em\.\f[]\f[]+.PP+So is \f[B]\f[I]this\f[]\f[] word\.+.PP+This is code: \f[B]>\f[], \f[B]$\f[], \f[B]\\\f[], \f[B]\\$\f[],+\f[B]<html>\f[]\.+.PP+[STRIKEOUT:This is \f[I]strikeout\f[]\.]+.PP+Superscripts: a^bc^d a^\f[I]hello\f[]^ a^hello there^\.+.PP+Subscripts: H~2~O, H~23~O, H~many of them~O\.+.PP+These should not be superscripts or subscripts, because of the+unescaped spaces: a^b c^d, a~b c~d\.+.PP+ * * * * *+.SH Smart quotes, ellipses, dashes+.PP+\[lq]Hello,\[rq] said the spider\. \[lq]`Shelob' is my name\.\[rq]+.PP+`A', `B', and `C' are letters\.+.PP+`Oak,' `elm,' and `beech' are names of trees\. So is `pine\.'+.PP+`He said, \[lq]I want to go\.\[rq]' Were you alive in the 70's?+.PP+Here is some quoted `\f[B]code\f[]' and a+\[lq]quoted link (http://example.com/?foo=1&bar=2)\[rq]\.+.PP+Some dashes: one\[em]two\[em]three\[em]four\[em]five\.+.PP+Dashes between numbers: 5\[en]7, 255\[en]66, 1987\[en]1999\.+.PP+Ellipses\&...and\&...and\&...\.+.PP+ * * * * *+.SH LaTeX+.IP \[bu] 2+\\cite[22-23]{smith\.1899}+.IP \[bu] 2+\\doublespacing+.IP \[bu] 2+$2+2=4$+.IP \[bu] 2+$x\ \\in\ y$+.IP \[bu] 2+$\\alpha\ \\wedge\ \\omega$+.IP \[bu] 2+$223$+.IP \[bu] 2+$p$-Tree+.IP \[bu] 2+$\\frac{d}{dx}f(x)=\\lim_{h\\to\ 0}\\frac{f(x+h)-f(x)}{h}$+.IP \[bu] 2+Here's one that has a line break in it:+$\\alpha\ +\ \\omega\ \\times\ x^2$\.+.PP+These shouldn't be math:+.IP \[bu] 2+To get the famous equation, write \f[B]$e\ =\ mc^2$\f[]\.+.IP \[bu] 2+$22,000 is a \f[I]lot\f[] of money\. So is $34,000\. (It worked if+\[lq]lot\[rq] is emphasized\.)+.IP \[bu] 2+Escaped \f[B]$\f[]: $73 \f[I]this should be emphasized\f[] 23$\.+.PP+Here's a LaTeX table:+.PP+\\begin{tabular}{|l|l|}\\hline+Animal\ &\ Number\ \\\\\ \\hline+Dog\ \ \ \ &\ 2\ \ \ \ \ \ \\\\+Cat\ \ \ \ &\ 1\ \ \ \ \ \ \\\\\ \\hline+\\end{tabular}+.PP+ * * * * *+.SH Special Characters+.PP+Here is some unicode:+.IP \[bu] 2+I hat: Î+.IP \[bu] 2+o umlaut: ö+.IP \[bu] 2+section: §+.IP \[bu] 2+set membership: ∈+.IP \[bu] 2+copyright: ©+.PP+AT&T has an ampersand in their name\.+.PP+AT&T is another way to write it\.+.PP+This & that\.+.PP+4 < 5\.+.PP+6 > 5\.+.PP+Backslash: \\+.PP+Backtick: `+.PP+Asterisk: *+.PP+Underscore: _+.PP+Left brace: {+.PP+Right brace: }+.PP+Left bracket: [+.PP+Right bracket: ]+.PP+Left paren: (+.PP+Right paren: )+.PP+Greater-than: >+.PP+Hash: #+.PP+Period: \.+.PP+Bang: !+.PP+Plus: ++.PP+Minus: -+.PP+ * * * * *+.SH Links+.SS Explicit+.PP+Just a URL (/url/)\.+.PP+URL and title (/url/)\.+.PP+URL and title (/url/)\.+.PP+URL and title (/url/)\.+.PP+URL and title (/url/)+.PP+URL and title (/url/)+.PP+with_underscore (/url/with_underscore)+.PP+Email link (mailto:nobody@nowhere.net)+.PP+Empty ()\.+.SS Reference+.PP+Foo bar (/url/)\.+.PP+Foo bar (/url/)\.+.PP+Foo bar (/url/)\.+.PP+With embedded [brackets] (/url/)\.+.PP+b (/url/) by itself should be a link\.+.PP+Indented once (/url)\.+.PP+Indented twice (/url)\.+.PP+Indented thrice (/url)\.+.PP+This should [not][] be a link\.+.PP+\f[CR]+ [not]:\ /url+\f[]+.PP+Foo bar (/url/)\.+.PP+Foo biz (/url/)\.+.SS With ampersands+.PP+Here's a+link with an ampersand in the URL (http://example.com/?foo=1&bar=2)\.+.PP+Here's a link with an amersand in the link text:+AT&T (http://att.com/)\.+.PP+Here's an inline link (/script?foo=1&bar=2)\.+.PP+Here's an inline link in pointy braces (/script?foo=1&bar=2)\.+.SS Autolinks+.PP+With an ampersand: <http://example.com/?foo=1&bar=2>+.IP \[bu] 2+In a list?+.IP \[bu] 2+<http://example.com/>+.IP \[bu] 2+It should\.+.PP+An e-mail address: <nobody@nowhere.net>+.RS+.PP+Blockquoted: <http://example.com/>+.RE+.PP+Auto-links should not occur here: \f[B]<http://example\.com/>\f[]+.PP+\f[CR]+ or\ here:\ <http://example\.com/>+\f[]+.PP+ * * * * *+.SH Images+.PP+From \[lq]Voyage dans la Lune\[rq] by Georges Melies (1902):+.PP+[IMAGE: lalune (lalune.jpg)]+.PP+Here is a movie [IMAGE: movie (movie.jpg)] icon\.+.PP+ * * * * *+.SH Footnotes+.PP+Here is a footnote reference,[1] and another\.[2] This should+\f[I]not\f[] be a footnote reference, because it contains a+space\.[^my note] Here is an inline note\.[3]+.RS+.PP+Notes can go in quotes\.[4]+.RE+.IP "1." 3+And in list items\.[5]+.PP+This paragraph should not be part of the note, as it is not+indented\.+.SH NOTES++.SS [1]+.PP+Here is the footnote\. It can go anywhere after the footnote+reference\. It need not be placed at the end of the document\.++.SS [2]+.PP+Here's the long note\. This one contains multiple blocks\.+.PP+Subsequent blocks are indented to show that they belong to the+footnote (as with list items)\.+.PP+\f[CR]+ \ \ {\ <code>\ }+\f[]+.PP+If you want, you can indent every line, but you can also be lazy+and just indent the first line of each block\.++.SS [3]+.PP+This is \f[I]easier\f[] to type\. Inline notes may contain+links (http://google.com) and \f[B]]\f[] verbatim characters, as+well as [bracketed text]\.++.SS [4]+.PP+In quote\.++.SS [5]+.PP+In list\.+.SH AUTHORS+John MacFarlane, Anonymous
+ tests/writer.markdown view
@@ -0,0 +1,717 @@+% Pandoc Test Suite+% John MacFarlane, Anonymous+% July 17, 2006++This is a set of tests for pandoc. Most of them are adapted from+John Gruber's markdown test suite.+++* * * * *++# Headers++## Level 2 with an [embedded link](/url)++### Level 3 with *emphasis*++#### Level 4++##### Level 5++# Level 1++## Level 2 with *emphasis*++### Level 3++with no blank line++## Level 2++with no blank line+++* * * * *++# 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.++Here's one with a bullet. \* criminey.++There should be a hard line break +here.+++* * * * *++# Block Quotes++E-mail style:++> This is a block quote. It is pretty short.++> Code in a block quote:+> +> sub status {+> print "working";+> }+> +> A list:+> +> 1. item one+> 2. item two+> +> Nested block quotes:+> +> > nested+> +> > nested++This should not be a block quote: 2 > 1.++Box-style:++> Example:+> +> sub status {+> print "working";+> }++> 1. do laundry+> 2. take out the trash++Here's a nested one:++> Joe said:+> +> > Don't quote me.++And a following paragraph.+++* * * * *++# Code Blocks++Code:++ ---- (should be four hyphens)+ + sub status {+ print "working";+ }+ + this code block is indented by one tab++And:++ this code block is indented by two tabs+ + These should not be escaped: \$ \\ \> \[ \{+++* * * * *++# Lists++## Unordered++Asterisks tight:++- asterisk 1+- asterisk 2+- asterisk 3++Asterisks loose:++- asterisk 1++- asterisk 2++- asterisk 3+++Pluses tight:++- Plus 1+- Plus 2+- Plus 3++Pluses loose:++- Plus 1++- Plus 2++- Plus 3+++Minuses tight:++- Minus 1+- Minus 2+- Minus 3++Minuses loose:++- Minus 1++- Minus 2++- Minus 3+++## Ordered++Tight:++1. First+2. Second+3. Third++and:++1. One+2. Two+3. Three++Loose using tabs:++1. First++2. Second++3. Third+++and using spaces:++1. One++2. Two++3. Three+++Multiple paragraphs:++1. Item 1, graf one.++ Item 1. graf two. The quick brown fox jumped over the lazy dog's+ back.++2. Item 2.++3. Item 3.+++## Nested++- Tab+ - Tab+ - Tab++++Here's another:++1. First+2. Second:+ - Fee+ - Fie+ - Foe++3. Third++Same thing but with paragraphs:++1. First++2. Second:++ - Fee+ - Fie+ - Foe++3. Third+++## Tabs and spaces++- this is a list item indented with tabs++- this is a list item indented with spaces++ - this is an example list item indented with tabs++ - this is an example list item indented with spaces++++## Fancy list markers++(2) begins with 2+(3) and now 3++ with a continuation++ iv. sublist with roman numerals, starting with 4+ v. more items+ (A) a subsublist+ (B) a subsublist++++Nesting:++A. Upper Alpha+ I. Upper Roman.+ (6) Decimal start with 6+ c) Lower alpha with paren+++++Autonumbering:++1. Autonumber.+2. More.+ 1. Nested.++++* * * * *++# Definition Lists++Tight using spaces:++apple+: red fruit+orange+: orange fruit+banana+: yellow fruit++Tight using tabs:++apple+: red fruit+orange+: orange fruit+banana+: yellow fruit++Loose:++apple+: red fruit++orange+: orange fruit++banana+: yellow fruit+++Multiple blocks with italics:++*apple*+: red fruit++: contains seeds, crisp, pleasant to taste++*orange*+: orange fruit++: { orange code block }++: > orange block quote+++# HTML Blocks++Simple block on one line:++<div>+foo+</div>++And nested without indentation:++<div>+<div>+<div>+foo+</div>+</div>+<div>+bar+</div>+</div>++Interpreted markdown in a table:++<table>+<tr>+<td>+This is *emphasized*+</td>+<td>+And this is **strong**+</td>+</tr>+</table>++<script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>++Here's a simple block:++<div>+ +foo+</div>++This should be a code block, though:++ <div>+ foo+ </div>++As should this:++ <div>foo</div>++Now, nested:++<div>+ <div>+ <div>+ +foo+</div>+ </div>+</div>++This should just be an HTML comment:++<!-- Comment -->++Multiline:++<!--+Blah+Blah+-->++<!--+ This is another comment.+-->++Code block:++ <!-- Comment -->++Just plain comment, with trailing spaces on the line:++<!-- foo --> ++Code:++ <hr />++Hr's:++<hr>++<hr />++<hr />++<hr> ++<hr /> ++<hr /> ++<hr class="foo" id="bar" />++<hr class="foo" id="bar" />++<hr class="foo" id="bar">+++* * * * *++# Inline Markup++This is *emphasized*, and so *is this*.++This is **strong**, and so **is this**.++An *[emphasized link](/url)*.++***This is strong and em.***++So is ***this*** word.++***This is strong and em.***++So is ***this*** word.++This is code: `>`, `$`, `\`, `\$`, `<html>`.++~~This is *strikeout*.~~++Superscripts: a^bc^d a^*hello*^ a^hello\ there^.++Subscripts: H~2~O, H~23~O, H~many\ of\ them~O.++These should not be superscripts or subscripts, because of the+unescaped spaces: a\^b c\^d, a\~b c\~d.+++* * * * *++# Smart quotes, ellipses, dashes++"Hello," said the spider. "'Shelob' is my name."++'A', 'B', and 'C' are letters.++'Oak,' 'elm,' and 'beech' are names of trees. So is 'pine.'++'He said, "I want to go."' Were you alive in the 70's?++Here is some quoted '`code`' and a+"[quoted link](http://example.com/?foo=1&bar=2)".++Some dashes: one--two--three--four--five.++Dashes between numbers: 5-7, 255-66, 1987-1999.++Ellipses...and...and....+++* * * * *++# LaTeX++- \cite[22-23]{smith.1899}+- \doublespacing+- $2+2=4$+- $x \in y$+- $\alpha \wedge \omega$+- $223$+- $p$-Tree+- $\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$+- Here's one that has a line break in it:+ $\alpha + \omega \times x^2$.++These shouldn't be math:++- To get the famous equation, write `$e = mc^2$`.+- $22,000 is a *lot* of money. So is $34,000. (It worked if "lot"+ is emphasized.)+- Escaped `$`: $73 *this should be emphasized* 23$.++Here's a LaTeX table:++\begin{tabular}{|l|l|}\hline+Animal & Number \\ \hline+Dog & 2 \\+Cat & 1 \\ \hline+\end{tabular}+++* * * * *++# Special Characters++Here is some unicode:++- I hat: Î+- o umlaut: ö+- section: §+- set membership: ∈+- copyright: ©++AT&T has an ampersand in their name.++AT&T is another way to write it.++This & that.++4 \< 5.++6 > 5.++Backslash: \\++Backtick: \`++Asterisk: \*++Underscore: \_++Left brace: {++Right brace: }++Left bracket: [++Right bracket: ]++Left paren: (++Right paren: )++Greater-than: >++Hash: #++Period: .++Bang: !++Plus: +++Minus: -+++* * * * *++# Links++## Explicit++Just a [URL](/url/).++[URL and title](/url/ "title").++[URL and title](/url/ "title preceded by two spaces").++[URL and title](/url/ "title preceded by a tab").++[URL and title](/url/ "title with "quotes" in it")++[URL and title](/url/ "title with single quotes")++[with\_underscore](/url/with_underscore)++[Email link](mailto:nobody@nowhere.net)++[Empty]().++## Reference++Foo [bar](/url/).++Foo [bar](/url/).++Foo [bar](/url/).++With [embedded [brackets]](/url/).++[b](/url/) by itself should be a link.++Indented [once](/url).++Indented [twice](/url).++Indented [thrice](/url).++This should [not][] be a link.++ [not]: /url++Foo [bar](/url/ "Title with "quotes" inside").++Foo [biz](/url/ "Title with "quote" inside").++## With ampersands++Here's a+[link with an ampersand in the URL](http://example.com/?foo=1&bar=2).++Here's a link with an amersand in the link text:+[AT&T](http://att.com/ "AT&T").++Here's an [inline link](/script?foo=1&bar=2).++Here's an [inline link in pointy braces](/script?foo=1&bar=2).++## Autolinks++With an ampersand: <http://example.com/?foo=1&bar=2>++- In a list?+- <http://example.com/>+- It should.++An e-mail address: <nobody@nowhere.net>++> Blockquoted: <http://example.com/>++Auto-links should not occur here: `<http://example.com/>`++ or here: <http://example.com/>+++* * * * *++# Images++From "Voyage dans la Lune" by Georges Melies (1902):++++Here is a movie  icon.+++* * * * *++# Footnotes++Here is a footnote reference,[^1] and another.[^2] This should+*not* be a footnote reference, because it contains a space.[\^my+note] Here is an inline note.[^3]++> Notes can go in quotes.[^4]++1. And in list items.[^5]++This paragraph should not be part of the note, as it is not+indented.+++[^1]:+ Here is the footnote. It can go anywhere after the footnote+ reference. It need not be placed at the end of the document.++[^2]:+ 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).++ { <code> }++ If you want, you can indent every line, but you can also be lazy+ and just indent the first line of each block.++[^3]:+ This is *easier* to type. Inline notes may contain+ [links](http://google.com) and `]` verbatim characters, as well as+ [bracketed text].++[^4]: In quote.++[^5]: In list.++
+ tests/writer.native view
@@ -0,0 +1,398 @@+Pandoc (Meta [Str "Pandoc",Space,Str "Test",Space,Str "Suite"] ["John MacFarlane","Anonymous"] "July 17, 2006")+[ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc",Str ".",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber",Apostrophe,Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite",Str "."]+, HorizontalRule+, Header 1 [Str "Headers"]+, Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embedded",Space,Str "link"] ("/url","")]+, Header 3 [Str "Level",Space,Str "3",Space,Str "with",Space,Emph [Str "emphasis"]]+, Header 4 [Str "Level",Space,Str "4"]+, Header 5 [Str "Level",Space,Str "5"]+, Header 1 [Str "Level",Space,Str "1"]+, Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Emph [Str "emphasis"]]+, Header 3 [Str "Level",Space,Str "3"]+, Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]+, Header 2 [Str "Level",Space,Str "2"]+, Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]+, HorizontalRule+, Header 1 [Str "Paragraphs"]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph",Str "."]+, Para [Str "In",Space,Str "Markdown",Space,Str "1",Str ".",Str "0",Str ".",Str "0",Space,Str "and",Space,Str "earlier",Str ".",Space,Str "Version",Space,Str "8",Str ".",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item",Str ".",Space,Str "Because",Space,Str "a",Space,Str "hard",Str "-",Str "wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item",Str "."]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet",Str ".",Space,Str "*",Space,Str "criminey",Str "."]+, Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break",LineBreak,Str "here",Str "."]+, HorizontalRule+, Header 1 [Str "Block",Space,Str "Quotes"]+, Para [Str "E",Str "-",Str "mail",Space,Str "style:"]+, BlockQuote+ [ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote",Str ".",Space,Str "It",Space,Str "is",Space,Str "pretty",Space,Str "short",Str "."] ]++, BlockQuote+ [ Para [Str "Code",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote:"]+ , CodeBlock "sub status {\n print \"working\";\n}"+ , Para [Str "A",Space,Str "list:"]+ , OrderedList (1,Decimal,Period)+ [ [ Plain [Str "item",Space,Str "one"] ]+ , [ Plain [Str "item",Space,Str "two"] ] ]+ , Para [Str "Nested",Space,Str "block",Space,Str "quotes:"]+ , BlockQuote+ [ Para [Str "nested"] ]+ + , BlockQuote+ [ Para [Str "nested"] ]+ ]+, Para [Str "This",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "block",Space,Str "quote:",Space,Str "2",Space,Str ">",Space,Str "1",Str "."]+, Para [Str "Box",Str "-",Str "style:"]+, BlockQuote+ [ Para [Str "Example:"]+ , CodeBlock "sub status {\n print \"working\";\n}" ]+, BlockQuote+ [ OrderedList (1,Decimal,Period)+ [ [ Plain [Str "do",Space,Str "laundry"] ]+ , [ Plain [Str "take",Space,Str "out",Space,Str "the",Space,Str "trash"] ] ] ]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "nested",Space,Str "one:"]+, BlockQuote+ [ Para [Str "Joe",Space,Str "said:"]+ , BlockQuote+ [ Para [Str "Don",Apostrophe,Str "t",Space,Str "quote",Space,Str "me",Str "."] ]+ ]+, Para [Str "And",Space,Str "a",Space,Str "following",Space,Str "paragraph",Str "."]+, HorizontalRule+, Header 1 [Str "Code",Space,Str "Blocks"]+, Para [Str "Code:"]+, CodeBlock "---- (should be four hyphens)\n\nsub status {\n print \"working\";\n}\n\nthis code block is indented by one tab"+, Para [Str "And:"]+, CodeBlock " this code block is indented by two tabs\n\nThese should not be escaped: \\$ \\\\ \\> \\[ \\{"+, HorizontalRule+, Header 1 [Str "Lists"]+, Header 2 [Str "Unordered"]+, Para [Str "Asterisks",Space,Str "tight:"]+, BulletList+ [ [ Plain [Str "asterisk",Space,Str "1"] ]+ , [ Plain [Str "asterisk",Space,Str "2"] ]+ , [ Plain [Str "asterisk",Space,Str "3"] ] ]+, Para [Str "Asterisks",Space,Str "loose:"]+, BulletList+ [ [ Para [Str "asterisk",Space,Str "1"] ]+ , [ Para [Str "asterisk",Space,Str "2"] ]+ , [ Para [Str "asterisk",Space,Str "3"] ] ]+, Para [Str "Pluses",Space,Str "tight:"]+, BulletList+ [ [ Plain [Str "Plus",Space,Str "1"] ]+ , [ Plain [Str "Plus",Space,Str "2"] ]+ , [ Plain [Str "Plus",Space,Str "3"] ] ]+, Para [Str "Pluses",Space,Str "loose:"]+, BulletList+ [ [ Para [Str "Plus",Space,Str "1"] ]+ , [ Para [Str "Plus",Space,Str "2"] ]+ , [ Para [Str "Plus",Space,Str "3"] ] ]+, Para [Str "Minuses",Space,Str "tight:"]+, BulletList+ [ [ Plain [Str "Minus",Space,Str "1"] ]+ , [ Plain [Str "Minus",Space,Str "2"] ]+ , [ Plain [Str "Minus",Space,Str "3"] ] ]+, Para [Str "Minuses",Space,Str "loose:"]+, BulletList+ [ [ Para [Str "Minus",Space,Str "1"] ]+ , [ Para [Str "Minus",Space,Str "2"] ]+ , [ Para [Str "Minus",Space,Str "3"] ] ]+, Header 2 [Str "Ordered"]+, Para [Str "Tight:"]+, OrderedList (1,Decimal,Period)+ [ [ Plain [Str "First"] ]+ , [ Plain [Str "Second"] ]+ , [ Plain [Str "Third"] ] ]+, Para [Str "and:"]+, OrderedList (1,Decimal,Period)+ [ [ Plain [Str "One"] ]+ , [ Plain [Str "Two"] ]+ , [ Plain [Str "Three"] ] ]+, Para [Str "Loose",Space,Str "using",Space,Str "tabs:"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "First"] ]+ , [ Para [Str "Second"] ]+ , [ Para [Str "Third"] ] ]+, Para [Str "and",Space,Str "using",Space,Str "spaces:"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "One"] ]+ , [ Para [Str "Two"] ]+ , [ Para [Str "Three"] ] ]+, Para [Str "Multiple",Space,Str "paragraphs:"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "Item",Space,Str "1,",Space,Str "graf",Space,Str "one",Str "."]+ , Para [Str "Item",Space,Str "1",Str ".",Space,Str "graf",Space,Str "two",Str ".",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog",Apostrophe,Str "s",Space,Str "back",Str "."] ], [ Para [Str "Item",Space,Str "2",Str "."] ]+ , [ Para [Str "Item",Space,Str "3",Str "."] ] ]+, Header 2 [Str "Nested"]+, BulletList+ [ [ Plain [Str "Tab"]+ , BulletList+ [ [ Plain [Str "Tab"]+ , BulletList+ [ [ Plain [Str "Tab"] ]+ ] ] ] ] ]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "another:"]+, OrderedList (1,Decimal,Period)+ [ [ Plain [Str "First"] ]+ , [ Plain [Str "Second:"]+ , BulletList+ [ [ Plain [Str "Fee"] ]+ , [ Plain [Str "Fie"] ]+ , [ Plain [Str "Foe"] ] ] ], [ Plain [Str "Third"] ] ]+, Para [Str "Same",Space,Str "thing",Space,Str "but",Space,Str "with",Space,Str "paragraphs:"]+, OrderedList (1,Decimal,Period)+ [ [ Para [Str "First"] ]+ , [ Para [Str "Second:"]+ , BulletList+ [ [ Plain [Str "Fee"] ]+ , [ Plain [Str "Fie"] ]+ , [ Plain [Str "Foe"] ] ] ], [ Para [Str "Third"] ] ]+, Header 2 [Str "Tabs",Space,Str "and",Space,Str "spaces"]+, BulletList+ [ [ Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"] ]+ , [ Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"]+ , BulletList+ [ [ Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"] ]+ , [ Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"] ] ] ] ]+, Header 2 [Str "Fancy",Space,Str "list",Space,Str "markers"]+, OrderedList (2,Decimal,TwoParens)+ [ [ Plain [Str "begins",Space,Str "with",Space,Str "2"] ]+ , [ Para [Str "and",Space,Str "now",Space,Str "3"]+ , Para [Str "with",Space,Str "a",Space,Str "continuation"]+ , OrderedList (4,LowerRoman,Period)+ [ [ Plain [Str "sublist",Space,Str "with",Space,Str "roman",Space,Str "numerals,",Space,Str "starting",Space,Str "with",Space,Str "4"] ]+ , [ Plain [Str "more",Space,Str "items"]+ , OrderedList (1,UpperAlpha,TwoParens)+ [ [ Plain [Str "a",Space,Str "subsublist"] ]+ , [ Plain [Str "a",Space,Str "subsublist"] ] ] ] ] ] ]+, Para [Str "Nesting:"]+, OrderedList (1,UpperAlpha,Period)+ [ [ Plain [Str "Upper",Space,Str "Alpha"]+ , OrderedList (1,UpperRoman,Period)+ [ [ Plain [Str "Upper",Space,Str "Roman",Str "."]+ , OrderedList (6,Decimal,TwoParens)+ [ [ Plain [Str "Decimal",Space,Str "start",Space,Str "with",Space,Str "6"]+ , OrderedList (3,LowerAlpha,OneParen)+ [ [ Plain [Str "Lower",Space,Str "alpha",Space,Str "with",Space,Str "paren"] ]+ ] ] ] ] ] ] ]+, Para [Str "Autonumbering:"]+, OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "Autonumber",Str "."] ]+ , [ Plain [Str "More",Str "."]+ , OrderedList (1,DefaultStyle,DefaultDelim)+ [ [ Plain [Str "Nested",Str "."] ]+ ] ] ]+, HorizontalRule+, Header 1 [Str "Definition",Space,Str "Lists"]+, Para [Str "Tight",Space,Str "using",Space,Str "spaces:"]+, DefinitionList+ [ ([Str "apple"],+ [ Plain [Str "red",Space,Str "fruit"] ]+ ),+ ([Str "orange"],+ [ Plain [Str "orange",Space,Str "fruit"] ]+ ),+ ([Str "banana"],+ [ Plain [Str "yellow",Space,Str "fruit"] ]+ ) ]+, Para [Str "Tight",Space,Str "using",Space,Str "tabs:"]+, DefinitionList+ [ ([Str "apple"],+ [ Plain [Str "red",Space,Str "fruit"] ]+ ),+ ([Str "orange"],+ [ Plain [Str "orange",Space,Str "fruit"] ]+ ),+ ([Str "banana"],+ [ Plain [Str "yellow",Space,Str "fruit"] ]+ ) ]+, Para [Str "Loose:"]+, DefinitionList+ [ ([Str "apple"],+ [ Para [Str "red",Space,Str "fruit"] ]+ ),+ ([Str "orange"],+ [ Para [Str "orange",Space,Str "fruit"] ]+ ),+ ([Str "banana"],+ [ Para [Str "yellow",Space,Str "fruit"] ]+ ) ]+, Para [Str "Multiple",Space,Str "blocks",Space,Str "with",Space,Str "italics:"]+, DefinitionList+ [ ([Emph [Str "apple"]],+ [ Para [Str "red",Space,Str "fruit"]+ , Para [Str "contains",Space,Str "seeds,",Space,Str "crisp,",Space,Str "pleasant",Space,Str "to",Space,Str "taste"] ] ),+ ([Emph [Str "orange"]],+ [ Para [Str "orange",Space,Str "fruit"]+ , CodeBlock "{ orange code block }"+ , BlockQuote+ [ Para [Str "orange",Space,Str "block",Space,Str "quote"] ]+ ] ) ]+, Header 1 [Str "HTML",Space,Str "Blocks"]+, Para [Str "Simple",Space,Str "block",Space,Str "on",Space,Str "one",Space,Str "line:"]+, RawHtml "<div>"+, Plain [Str "foo"]+, RawHtml "</div>\n"+, Para [Str "And",Space,Str "nested",Space,Str "without",Space,Str "indentation:"]+, RawHtml "<div>\n<div>\n<div>"+, Plain [Str "foo"]+, RawHtml "</div>\n</div>\n<div>"+, Plain [Str "bar"]+, RawHtml "</div>\n</div>\n"+, Para [Str "Interpreted",Space,Str "markdown",Space,Str "in",Space,Str "a",Space,Str "table:"]+, RawHtml "<table>\n<tr>\n<td>"+, Plain [Str "This",Space,Str "is",Space,Emph [Str "emphasized"]]+, RawHtml "</td>\n<td>"+, Plain [Str "And",Space,Str "this",Space,Str "is",Space,Strong [Str "strong"]]+, RawHtml "</td>\n</tr>\n</table>\n\n<script type=\"text/javascript\">document.write('This *should not* be interpreted as markdown');</script>\n"+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "simple",Space,Str "block:"]+, RawHtml "<div>\n "+, Plain [Str "foo"]+, RawHtml "</div>\n"+, Para [Str "This",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "code",Space,Str "block,",Space,Str "though:"]+, CodeBlock "<div>\n foo\n</div>"+, Para [Str "As",Space,Str "should",Space,Str "this:"]+, CodeBlock "<div>foo</div>"+, Para [Str "Now,",Space,Str "nested:"]+, RawHtml "<div>\n <div>\n <div>\n "+, Plain [Str "foo"]+, RawHtml "</div>\n </div>\n</div>\n"+, Para [Str "This",Space,Str "should",Space,Str "just",Space,Str "be",Space,Str "an",Space,Str "HTML",Space,Str "comment:"]+, RawHtml "<!-- Comment -->\n"+, Para [Str "Multiline:"]+, RawHtml "<!--\nBlah\nBlah\n-->\n\n<!--\n This is another comment.\n-->\n"+, Para [Str "Code",Space,Str "block:"]+, CodeBlock "<!-- Comment -->"+, Para [Str "Just",Space,Str "plain",Space,Str "comment,",Space,Str "with",Space,Str "trailing",Space,Str "spaces",Space,Str "on",Space,Str "the",Space,Str "line:"]+, RawHtml "<!-- foo --> \n"+, Para [Str "Code:"]+, CodeBlock "<hr />"+, Para [Str "Hr",Apostrophe,Str "s:"]+, RawHtml "<hr>\n\n<hr />\n\n<hr />\n\n<hr> \n\n<hr /> \n\n<hr /> \n\n<hr class=\"foo\" id=\"bar\" />\n\n<hr class=\"foo\" id=\"bar\" />\n\n<hr class=\"foo\" id=\"bar\">\n"+, HorizontalRule+, Header 1 [Str "Inline",Space,Str "Markup"]+, Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ",",Space,Str "and",Space,Str "so",Space,Emph [Str "is",Space,Str "this"],Str "."]+, Para [Str "This",Space,Str "is",Space,Strong [Str "strong"],Str ",",Space,Str "and",Space,Str "so",Space,Strong [Str "is",Space,Str "this"],Str "."]+, Para [Str "An",Space,Emph [Link [Str "emphasized",Space,Str "link"] ("/url","")],Str "."]+, Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em",Str "."]]]+, Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word",Str "."]+, Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em",Str "."]]]+, Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word",Str "."]+, Para [Str "This",Space,Str "is",Space,Str "code:",Space,Code ">",Str ",",Space,Code "$",Str ",",Space,Code "\\",Str ",",Space,Code "\\$",Str ",",Space,Code "<html>",Str "."]+, Para [Strikeout [Str "This",Space,Str "is",Space,Emph [Str "strikeout"],Str "."]]+, Para [Str "Superscripts:",Space,Str "a",Superscript [Str "bc"],Str "d",Space,Str "a",Superscript [Emph [Str "hello"]],Space,Str "a",Superscript [Str "hello",Str " ",Str "there"],Str "."]+, Para [Str "Subscripts:",Space,Str "H",Subscript [Str "2"],Str "O,",Space,Str "H",Subscript [Str "23"],Str "O,",Space,Str "H",Subscript [Str "many",Str " ",Str "of",Str " ",Str "them"],Str "O",Str "."]+, Para [Str "These",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "superscripts",Space,Str "or",Space,Str "subscripts,",Space,Str "because",Space,Str "of",Space,Str "the",Space,Str "unescaped",Space,Str "spaces:",Space,Str "a",Str "^",Str "b",Space,Str "c",Str "^",Str "d,",Space,Str "a",Str "~",Str "b",Space,Str "c",Str "~",Str "d",Str "."]+, HorizontalRule+, Header 1 [Str "Smart",Space,Str "quotes,",Space,Str "ellipses,",Space,Str "dashes"]+, Para [Quoted DoubleQuote [Str "Hello,"],Space,Str "said",Space,Str "the",Space,Str "spider",Str ".",Space,Quoted DoubleQuote [Quoted SingleQuote [Str "Shelob"],Space,Str "is",Space,Str "my",Space,Str "name",Str "."]]+, Para [Quoted SingleQuote [Str "A"],Str ",",Space,Quoted SingleQuote [Str "B"],Str ",",Space,Str "and",Space,Quoted SingleQuote [Str "C"],Space,Str "are",Space,Str "letters",Str "."]+, Para [Quoted SingleQuote [Str "Oak,"],Space,Quoted SingleQuote [Str "elm,"],Space,Str "and",Space,Quoted SingleQuote [Str "beech"],Space,Str "are",Space,Str "names",Space,Str "of",Space,Str "trees",Str ".",Space,Str "So",Space,Str "is",Space,Quoted SingleQuote [Str "pine",Str "."]]+, Para [Quoted SingleQuote [Str "He",Space,Str "said,",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go",Str "."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70",Apostrophe,Str "s?"]+, Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "quoted",Space,Quoted SingleQuote [Code "code"],Space,Str "and",Space,Str "a",Space,Quoted DoubleQuote [Link [Str "quoted",Space,Str "link"] ("http://example.com/?foo=1&bar=2","")],Str "."]+, Para [Str "Some",Space,Str "dashes:",Space,Str "one",EmDash,Str "two",EmDash,Str "three",EmDash,Str "four",EmDash,Str "five",Str "."]+, Para [Str "Dashes",Space,Str "between",Space,Str "numbers:",Space,Str "5",EnDash,Str "7,",Space,Str "255",EnDash,Str "66,",Space,Str "1987",EnDash,Str "1999",Str "."]+, Para [Str "Ellipses",Ellipses,Str "and",Ellipses,Str "and",Ellipses,Str "."]+, HorizontalRule+, Header 1 [Str "LaTeX"]+, BulletList+ [ [ Plain [TeX "\\cite[22-23]{smith.1899}"] ]+ , [ Plain [TeX "\\doublespacing"] ]+ , [ Plain [TeX "$2+2=4$"] ]+ , [ Plain [TeX "$x \\in y$"] ]+ , [ Plain [TeX "$\\alpha \\wedge \\omega$"] ]+ , [ Plain [TeX "$223$"] ]+ , [ Plain [TeX "$p$",Str "-",Str "Tree"] ]+ , [ Plain [TeX "$\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}$"] ]+ , [ Plain [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it:",Space,TeX "$\\alpha + \\omega \\times x^2$",Str "."] ] ]+, Para [Str "These",Space,Str "shouldn",Apostrophe,Str "t",Space,Str "be",Space,Str "math:"]+, BulletList+ [ [ Plain [Str "To",Space,Str "get",Space,Str "the",Space,Str "famous",Space,Str "equation,",Space,Str "write",Space,Code "$e = mc^2$",Str "."] ]+ , [ Plain [Str "$",Str "22,000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money",Str ".",Space,Str "So",Space,Str "is",Space,Str "$",Str "34,000",Str ".",Space,Str "(It",Space,Str "worked",Space,Str "if",Space,Quoted DoubleQuote [Str "lot"],Space,Str "is",Space,Str "emphasized",Str ".",Str ")"] ]+ , [ Plain [Str "Escaped",Space,Code "$",Str ":",Space,Str "$",Str "73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23",Str "$",Str "."] ] ]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]+, Para [TeX "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}"]+, HorizontalRule+, Header 1 [Str "Special",Space,Str "Characters"]+, Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode:"]+, BulletList+ [ [ Plain [Str "I",Space,Str "hat:",Space,Str "\206"] ]+ , [ Plain [Str "o",Space,Str "umlaut:",Space,Str "\246"] ]+ , [ Plain [Str "section:",Space,Str "\167"] ]+ , [ Plain [Str "set",Space,Str "membership:",Space,Str "\8712"] ]+ , [ Plain [Str "copyright:",Space,Str "\169"] ] ]+, Para [Str "AT",Str "&",Str "T",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "their",Space,Str "name",Str "."]+, Para [Str "AT",Str "&",Str "T",Space,Str "is",Space,Str "another",Space,Str "way",Space,Str "to",Space,Str "write",Space,Str "it",Str "."]+, Para [Str "This",Space,Str "&",Space,Str "that",Str "."]+, Para [Str "4",Space,Str "<",Space,Str "5",Str "."]+, Para [Str "6",Space,Str ">",Space,Str "5",Str "."]+, Para [Str "Backslash:",Space,Str "\\"]+, Para [Str "Backtick:",Space,Str "`"]+, Para [Str "Asterisk:",Space,Str "*"]+, Para [Str "Underscore:",Space,Str "_"]+, Para [Str "Left",Space,Str "brace:",Space,Str "{"]+, Para [Str "Right",Space,Str "brace:",Space,Str "}"]+, Para [Str "Left",Space,Str "bracket:",Space,Str "["]+, Para [Str "Right",Space,Str "bracket:",Space,Str "]"]+, Para [Str "Left",Space,Str "paren:",Space,Str "("]+, Para [Str "Right",Space,Str "paren:",Space,Str ")"]+, Para [Str "Greater",Str "-",Str "than:",Space,Str ">"]+, Para [Str "Hash:",Space,Str "#"]+, Para [Str "Period:",Space,Str "."]+, Para [Str "Bang:",Space,Str "!"]+, Para [Str "Plus:",Space,Str "+"]+, Para [Str "Minus:",Space,Str "-"]+, HorizontalRule+, Header 1 [Str "Links"]+, Header 2 [Str "Explicit"]+, Para [Str "Just",Space,Str "a",Space,Link [Str "URL"] ("/url/",""),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title"),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title preceded by two spaces"),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title preceded by a tab"),Str "."]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title with \"quotes\" in it")]+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","title with single quotes")]+, Para [Link [Str "with",Str "_",Str "underscore"] ("/url/with_underscore","")]+, Para [Link [Str "Email",Space,Str "link"] ("mailto:nobody@nowhere.net","")]+, Para [Link [Str "Empty"] ("",""),Str "."]+, Header 2 [Str "Reference"]+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]+, Para [Str "With",Space,Link [Str "embedded",Space,Str "[",Str "brackets",Str "]"] ("/url/",""),Str "."]+, Para [Link [Str "b"] ("/url/",""),Space,Str "by",Space,Str "itself",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "link",Str "."]+, Para [Str "Indented",Space,Link [Str "once"] ("/url",""),Str "."]+, Para [Str "Indented",Space,Link [Str "twice"] ("/url",""),Str "."]+, Para [Str "Indented",Space,Link [Str "thrice"] ("/url",""),Str "."]+, Para [Str "This",Space,Str "should",Space,Str "[",Str "not",Str "]",Str "[",Str "]",Space,Str "be",Space,Str "a",Space,Str "link",Str "."]+, CodeBlock "[not]: /url"+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/","Title with \"quotes\" inside"),Str "."]+, Para [Str "Foo",Space,Link [Str "biz"] ("/url/","Title with \"quote\" inside"),Str "."]+, Header 2 [Str "With",Space,Str "ampersands"]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text:",Space,Link [Str "AT",Str "&",Str "T"] ("http://att.com/","AT&T"),Str "."]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]+, Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]+, Header 2 [Str "Autolinks"]+, Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link [Code "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]+, BulletList+ [ [ Plain [Str "In",Space,Str "a",Space,Str "list?"] ]+ , [ Plain [Link [Code "http://example.com/"] ("http://example.com/","")] ]+ , [ Plain [Str "It",Space,Str "should",Str "."] ] ]+, Para [Str "An",Space,Str "e",Str "-",Str "mail",Space,Str "address:",Space,Link [Code "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]+, BlockQuote+ [ Para [Str "Blockquoted:",Space,Link [Code "http://example.com/"] ("http://example.com/","")] ]++, Para [Str "Auto",Str "-",Str "links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",Space,Code "<http://example.com/>"]+, CodeBlock "or here: <http://example.com/>"+, HorizontalRule+, Header 1 [Str "Images"]+, Para [Str "From",Space,Quoted DoubleQuote [Str "Voyage",Space,Str "dans",Space,Str "la",Space,Str "Lune"],Space,Str "by",Space,Str "Georges",Space,Str "Melies",Space,Str "(1902):"]+, Para [Image [Str "lalune"] ("lalune.jpg","Voyage dans la Lune")]+, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image [Str "movie"] ("movie.jpg",""),Space,Str "icon",Str "."]+, HorizontalRule+, Header 1 [Str "Footnotes"]+, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote",Str ".",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference",Str ".",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document",Str "."]],Space,Str "and",Space,Str "another",Str ".",Note [Para [Str "Here",Apostrophe,Str "s",Space,Str "the",Space,Str "long",Space,Str "note",Str ".",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks",Str "."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "list",Space,Str "items)",Str "."],CodeBlock " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line,",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block",Str "."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space",Str ".",Str "[",Str "^",Str "my",Space,Str "note",Str "]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note",Str ".",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type",Str ".",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code "]",Space,Str "verbatim",Space,Str "characters,",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[",Str "bracketed",Space,Str "text",Str "]",Str "."]]]+, BlockQuote+ [ Para [Str "Notes",Space,Str "can",Space,Str "go",Space,Str "in",Space,Str "quotes",Str ".",Note [Para [Str "In",Space,Str "quote",Str "."]]] ]++, OrderedList (1,Decimal,Period)+ [ [ Plain [Str "And",Space,Str "in",Space,Str "list",Space,Str "items",Str ".",Note [Para [Str "In",Space,Str "list",Str "."]]] ]+ ]+, Para [Str "This",Space,Str "paragraph",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "part",Space,Str "of",Space,Str "the",Space,Str "note,",Space,Str "as",Space,Str "it",Space,Str "is",Space,Str "not",Space,Str "indented",Str "."] ]+
+ tests/writer.rst view
@@ -0,0 +1,871 @@+=================+Pandoc Test Suite+=================++:Author: John MacFarlane+:Author: Anonymous+:Date: July 17, 2006++This is a set of tests for pandoc. Most of them are adapted from+John Gruber's markdown test suite.++--------------++Headers+=======++Level 2 with an `embedded link </url>`_+---------------------------------------++Level 3 with *emphasis*+~~~~~~~~~~~~~~~~~~~~~~~++Level 4+^^^^^^^++Level 5+'''''''++Level 1+=======++Level 2 with *emphasis*+-----------------------++Level 3+~~~~~~~++with no blank line++Level 2+-------++with no blank line++--------------++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.++Here's one with a bullet. \* criminey.++There should be a hard line break+here.++--------------++Block Quotes+============++E-mail style:++ This is a block quote. It is pretty short.+++ Code in a block quote:++ ::++ sub status {+ print "working";+ }++ A list:++ + 1. item one+ 2. item two++ Nested block quotes:++ nested+++ nested++++This should not be a block quote: 2 > 1.++Box-style:++ Example:++ ::++ sub status {+ print "working";+ }+++ + 1. do laundry+ 2. take out the trash+++Here's a nested one:++ Joe said:++ Don't quote me.++++And a following paragraph.++--------------++Code Blocks+===========++Code:++::++ ---- (should be four hyphens)+ + sub status {+ print "working";+ }+ + this code block is indented by one tab++And:++::++ this code block is indented by two tabs+ + These should not be escaped: \$ \\ \> \[ \{++--------------++Lists+=====++Unordered+---------++Asterisks tight:+++- asterisk 1+- asterisk 2+- asterisk 3++Asterisks loose:+++- asterisk 1++- asterisk 2++- asterisk 3+++Pluses tight:+++- Plus 1+- Plus 2+- Plus 3++Pluses loose:+++- Plus 1++- Plus 2++- Plus 3+++Minuses tight:+++- Minus 1+- Minus 2+- Minus 3++Minuses loose:+++- Minus 1++- Minus 2++- Minus 3+++Ordered+-------++Tight:+++1. First+2. Second+3. Third++and:+++1. One+2. Two+3. Three++Loose using tabs:+++1. First++2. Second++3. Third+++and using spaces:+++1. One++2. Two++3. Three+++Multiple paragraphs:+++1. Item 1, graf one.++ Item 1. graf two. The quick brown fox jumped over the lazy dog's+ back.++2. Item 2.++3. Item 3.+++Nested+------+++- Tab+ + - Tab+ + - Tab++++Here's another:+++1. First+2. Second:+ + - Fee+ - Fie+ - Foe++3. Third++Same thing but with paragraphs:+++1. First++2. Second:++ + - Fee+ - Fie+ - Foe++3. Third+++Tabs and spaces+---------------+++- this is a list item indented with tabs++- this is a list item indented with spaces++ + - this is an example list item indented with tabs++ - this is an example list item indented with spaces++++Fancy list markers+------------------+++(2) begins with 2+(3) and now 3++ with a continuation++ + iv. sublist with roman numerals, starting with 4+ v. more items+ + (A) a subsublist+ (B) a subsublist++++Nesting:+++A. Upper Alpha+ + I. Upper Roman.+ + (6) Decimal start with 6+ + c) Lower alpha with paren+++++Autonumbering:+++#. Autonumber.+#. More.+ + #. Nested.+++--------------++Definition Lists+================++Tight using spaces:++apple+ red fruit+orange+ orange fruit+banana+ yellow fruit++Tight using tabs:++apple+ red fruit+orange+ orange fruit+banana+ yellow fruit++Loose:++apple+ red fruit++orange+ orange fruit++banana+ yellow fruit+++Multiple blocks with italics:++*apple*+ red fruit++ contains seeds, crisp, pleasant to taste++*orange*+ orange fruit++ ::++ { orange code block }++ orange block quote++++HTML Blocks+===========++Simple block on one line:+++.. raw:: html++ <div>+ +foo++.. raw:: html++ </div>+ +And nested without indentation:+++.. raw:: html++ <div>+ <div>+ <div>+ +foo++.. raw:: html++ </div>+ </div>+ <div>+ +bar++.. raw:: html++ </div>+ </div>+ +Interpreted markdown in a table:+++.. raw:: html++ <table>+ <tr>+ <td>+ +This is *emphasized*++.. raw:: html++ </td>+ <td>+ +And this is **strong**++.. raw:: html++ </td>+ </tr>+ </table>+ + <script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>+ +Here's a simple block:+++.. raw:: html++ <div>+ + +foo++.. raw:: html++ </div>+ +This should be a code block, though:++::++ <div>+ foo+ </div>++As should this:++::++ <div>foo</div>++Now, nested:+++.. raw:: html++ <div>+ <div>+ <div>+ + +foo++.. raw:: html++ </div>+ </div>+ </div>+ +This should just be an HTML comment:+++.. raw:: html++ <!-- Comment -->+ +Multiline:+++.. raw:: html++ <!--+ Blah+ Blah+ -->+ + <!--+ This is another comment.+ -->+ +Code block:++::++ <!-- Comment -->++Just plain comment, with trailing spaces on the line:+++.. raw:: html++ <!-- foo --> + +Code:++::++ <hr />++Hr's:+++.. raw:: html++ <hr>+ + <hr />+ + <hr />+ + <hr> + + <hr /> + + <hr /> + + <hr class="foo" id="bar" />+ + <hr class="foo" id="bar" />+ + <hr class="foo" id="bar">+ +--------------++Inline Markup+=============++This is *emphasized*, and so *is this*.++This is **strong**, and so **is this**.++An *`emphasized link </url>`_*.++***This is strong and em.***++So is ***this*** word.++***This is strong and em.***++So is ***this*** word.++This is code: ``>``, ``$``, ``\``, ``\$``, ``<html>``.++[STRIKEOUT:This is *strikeout*.]++Superscripts: a\ :sup:`bc`\ d a\ :sup:`*hello*`\ +a\ :sup:`hello there`\ .++Subscripts: H\ :sub:`2`\ O, H\ :sub:`23`\ O,+H\ :sub:`many of them`\ O.++These should not be superscripts or subscripts, because of the+unescaped spaces: a^b c^d, a~b c~d.++--------------++Smart quotes, ellipses, dashes+==============================++"Hello," said the spider. "'Shelob' is my name."++'A', 'B', and 'C' are letters.++'Oak,' 'elm,' and 'beech' are names of trees. So is 'pine.'++'He said, "I want to go."' Were you alive in the 70's?++Here is some quoted '``code``' and a+"`quoted link <http://example.com/?foo=1&bar=2>`_".++Some dashes: one--two--three--four--five.++Dashes between numbers: 5-7, 255-66, 1987-1999.++Ellipses...and...and....++--------------++LaTeX+=====+++- \cite[22-23]{smith.1899}+- \doublespacing+- $2+2=4$+- $x \in y$+- $\alpha \wedge \omega$+- $223$+- $p$-Tree+- $\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$+- Here's one that has a line break in it:+ $\alpha + \omega \times x^2$.++These shouldn't be math:+++- To get the famous equation, write ``$e = mc^2$``.+- $22,000 is a *lot* of money. So is $34,000. (It worked if "lot"+ is emphasized.)+- Escaped ``$``: $73 *this should be emphasized* 23$.++Here's a LaTeX table:+++.. raw:: latex++ \begin{tabular}{|l|l|}\hline+ Animal & Number \\ \hline+ Dog & 2 \\+ Cat & 1 \\ \hline+ \end{tabular}+ +--------------++Special Characters+==================++Here is some unicode:+++- I hat: Î+- o umlaut: ö+- section: §+- set membership: ∈+- copyright: ©++AT&T has an ampersand in their name.++AT&T is another way to write it.++This & that.++4 < 5.++6 > 5.++Backslash: \\++Backtick: \`++Asterisk: \*++Underscore: \_++Left brace: {++Right brace: }++Left bracket: [++Right bracket: ]++Left paren: (++Right paren: )++Greater-than: >++Hash: #++Period: .++Bang: !++Plus: +++Minus: -++--------------++Links+=====++Explicit+--------++Just a `URL </url/>`_.++`URL and title </url/>`_.++`URL and title </url/>`_.++`URL and title </url/>`_.++`URL and title </url/>`_++`URL and title </url/>`_++`with\_underscore </url/with_underscore>`_++`Email link <mailto:nobody@nowhere.net>`_++`Empty <>`_.++Reference+---------++Foo `bar </url/>`_.++Foo `bar </url/>`_.++Foo `bar </url/>`_.++With `embedded [brackets] </url/>`_.++`b </url/>`_ by itself should be a link.++Indented `once </url>`_.++Indented `twice </url>`_.++Indented `thrice </url>`_.++This should [not][] be a link.++::++ [not]: /url++Foo `bar </url/>`_.++Foo `biz </url/>`_.++With ampersands+---------------++Here's a+`link with an ampersand in the URL <http://example.com/?foo=1&bar=2>`_.++Here's a link with an amersand in the link text:+`AT&T <http://att.com/>`_.++Here's an `inline link </script?foo=1&bar=2>`_.++Here's an `inline link in pointy braces </script?foo=1&bar=2>`_.++Autolinks+---------++With an ampersand: http://example.com/?foo=1&bar=2+++- In a list?+- http://example.com/+- It should.++An e-mail address: nobody@nowhere.net++ Blockquoted: http://example.com/+++Auto-links should not occur here: ``<http://example.com/>``++::++ or here: <http://example.com/>++--------------++Images+======++From "Voyage dans la Lune" by Georges Melies (1902):++|lalune|++Here is a movie |movie| icon.++--------------++Footnotes+=========++Here is a footnote reference, [1]_ and another. [2]_ This should+*not* be a footnote reference, because it contains a space.[^my+note] Here is an inline note. [3]_++ Notes can go in quotes. [4]_++++1. And in list items. [5]_++This paragraph should not be part of the note, as it is not+indented.++.. [1] + Here is the footnote. It can go anywhere after the footnote+ reference. It need not be placed at the end of the document.++.. [2] + 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).++ ::++ { <code> }++ If you want, you can indent every line, but you can also be lazy+ and just indent the first line of each block.++.. [3] + This is *easier* to type. Inline notes may contain+ `links <http://google.com>`_ and ``]`` verbatim characters, as well+ as [bracketed text].++.. [4] In quote.++.. [5] In list.+++.. |lalune| image:: lalune.jpg+.. |movie| image:: movie.jpg
+ tests/writer.rtf view
@@ -0,0 +1,442 @@+{\rtf1\ansi\deff0{\fonttbl{\f0 \fswiss Helvetica;}{\f1 Courier;}}+{\colortbl;\red255\green0\blue0;\red0\green0\blue255;}+\widowctrl\hyphauto++{\pard \qc \f0 \sa180 \li0 \fi0 \b \fs36 Pandoc Test Suite\par}+{\pard \qc \f0 \sa180 \li0 \fi0 John MacFarlane\Anonymous\par}+{\pard \qc \f0 \sa180 \li0 \fi0 July 17, 2006\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \par}+{\pard \ql \f0 \sa180 \li0 \fi0 This is a set of tests for pandoc. Most of them are adapted from John Gruber\u8217's markdown test suite.\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Headers\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Level 2 with an {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul+embedded link+}}}+\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 Level 3 with {\i emphasis} \par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs24 Level 4\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs20 Level 5\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Level 1\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Level 2 with {\i emphasis} \par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 Level 3\par}+{\pard \ql \f0 \sa180 \li0 \fi0 with no blank line\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Level 2\par}+{\pard \ql \f0 \sa180 \li0 \fi0 with no blank line\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Paragraphs\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a regular paragraph.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 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.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's one with a bullet. * criminey.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 There should be a hard line break\line here.\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Block Quotes\par}+{\pard \ql \f0 \sa180 \li0 \fi0 E-mail style:\par}+{\pard \ql \f0 \sa180 \li720 \fi0 This is a block quote. It is pretty short.\par}+{\pard \ql \f0 \sa180 \li720 \fi0 Code in a block quote:\par}+{\pard \ql \f0 \sa180 \li720 \fi0 \f1 sub status \{\line+ print "working";\line+\}\par}+{\pard \ql \f0 \sa180 \li720 \fi0 A list:\par}+{\pard \ql \f0 \sa0 \li1080 \fi-360 1.\tx360\tab item one\par}+{\pard \ql \f0 \sa0 \li1080 \fi-360 2.\tx360\tab item two\sa180\par}+{\pard \ql \f0 \sa180 \li720 \fi0 Nested block quotes:\par}+{\pard \ql \f0 \sa180 \li1440 \fi0 nested\par}+{\pard \ql \f0 \sa180 \li1440 \fi0 nested\par}+{\pard \ql \f0 \sa180 \li0 \fi0 This should not be a block quote: 2 > 1.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Box-style:\par}+{\pard \ql \f0 \sa180 \li720 \fi0 Example:\par}+{\pard \ql \f0 \sa180 \li720 \fi0 \f1 sub status \{\line+ print "working";\line+\}\par}+{\pard \ql \f0 \sa0 \li1080 \fi-360 1.\tx360\tab do laundry\par}+{\pard \ql \f0 \sa0 \li1080 \fi-360 2.\tx360\tab take out the trash\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a nested one:\par}+{\pard \ql \f0 \sa180 \li720 \fi0 Joe said:\par}+{\pard \ql \f0 \sa180 \li1440 \fi0 Don\u8217't quote me.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 And a following paragraph.\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Code Blocks\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Code:\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \f1 ---- (should be four hyphens)\line+\line+sub status \{\line+ print "working";\line+\}\line+\line+this code block is indented by one tab\par}+{\pard \ql \f0 \sa180 \li0 \fi0 And:\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \f1 this code block is indented by two tabs\line+\line+These should not be escaped: \\$ \\\\ \\> \\[ \\\{\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Lists\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Unordered\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Asterisks tight:\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab asterisk 1\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab asterisk 2\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab asterisk 3\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Asterisks loose:\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab asterisk 1\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab asterisk 2\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab asterisk 3\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Pluses tight:\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Plus 1\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Plus 2\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Plus 3\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Pluses loose:\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Plus 1\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Plus 2\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Plus 3\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Minuses tight:\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Minus 1\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Minus 2\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Minus 3\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Minuses loose:\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Minus 1\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Minus 2\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Minus 3\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Ordered\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Tight:\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab First\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 2.\tx360\tab Second\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 3.\tx360\tab Third\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 and:\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab One\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 2.\tx360\tab Two\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 3.\tx360\tab Three\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Loose using tabs:\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 1.\tx360\tab First\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 2.\tx360\tab Second\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 3.\tx360\tab Third\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 and using spaces:\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 1.\tx360\tab One\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 2.\tx360\tab Two\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 3.\tx360\tab Three\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Multiple paragraphs:\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 1.\tx360\tab Item 1, graf one.\par}+{\pard \ql \f0 \sa180 \li360 \fi0 Item 1. graf two. The quick brown fox jumped over the lazy dog\u8217's back.\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 2.\tx360\tab Item 2.\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 3.\tx360\tab Item 3.\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Nested\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Tab\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Tab\par}+{\pard \ql \f0 \sa0 \li1080 \fi-360 \bullet \tx360\tab Tab\sa180\sa180\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's another:\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab First\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 2.\tx360\tab Second:\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Fee\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Fie\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Foe\sa180\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 3.\tx360\tab Third\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Same thing but with paragraphs:\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 1.\tx360\tab First\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 2.\tx360\tab Second:\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Fee\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Fie\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Foe\sa180\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 3.\tx360\tab Third\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Tabs and spaces\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab this is a list item indented with tabs\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab this is a list item indented with spaces\par}+{\pard \ql \f0 \sa180 \li720 \fi-360 \endash \tx360\tab this is an example list item indented with tabs\par}+{\pard \ql \f0 \sa180 \li720 \fi-360 \endash \tx360\tab this is an example list item indented with spaces\sa180\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Fancy list markers\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 (2)\tx360\tab begins with 2\par}+{\pard \ql \f0 \sa180 \li360 \fi-360 (3)\tx360\tab and now 3\par}+{\pard \ql \f0 \sa180 \li360 \fi0 with a continuation\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 iv.\tx360\tab sublist with roman numerals, starting with 4\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 v.\tx360\tab more items\par}+{\pard \ql \f0 \sa0 \li1080 \fi-360 (A)\tx360\tab a subsublist\par}+{\pard \ql \f0 \sa0 \li1080 \fi-360 (B)\tx360\tab a subsublist\sa180\sa180\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Nesting:\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 A.\tx360\tab Upper Alpha\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 I.\tx360\tab Upper Roman.\par}+{\pard \ql \f0 \sa0 \li1080 \fi-360 (6)\tx360\tab Decimal start with 6\par}+{\pard \ql \f0 \sa0 \li1440 \fi-360 c)\tx360\tab Lower alpha with paren\sa180\sa180\sa180\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Autonumbering:\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab Autonumber.\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 2.\tx360\tab More.\par}+{\pard \ql \f0 \sa0 \li720 \fi-360 a.\tx360\tab Nested.\sa180\sa180\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Definition Lists\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Tight using spaces:\par}+{\pard \ql \f0 \sa0 \li0 \fi0 apple\par}+{\pard \ql \f0 \sa0 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \sa0 \li0 \fi0 orange\par}+{\pard \ql \f0 \sa0 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \sa0 \li0 \fi0 banana\par}+{\pard \ql \f0 \sa0 \li360 \fi0 yellow fruit\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Tight using tabs:\par}+{\pard \ql \f0 \sa0 \li0 \fi0 apple\par}+{\pard \ql \f0 \sa0 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \sa0 \li0 \fi0 orange\par}+{\pard \ql \f0 \sa0 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \sa0 \li0 \fi0 banana\par}+{\pard \ql \f0 \sa0 \li360 \fi0 yellow fruit\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Loose:\par}+{\pard \ql \f0 \sa0 \li0 \fi0 apple\par}+{\pard \ql \f0 \sa180 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \sa0 \li0 \fi0 orange\par}+{\pard \ql \f0 \sa180 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \sa0 \li0 \fi0 banana\par}+{\pard \ql \f0 \sa180 \li360 \fi0 yellow fruit\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Multiple blocks with italics:\par}+{\pard \ql \f0 \sa0 \li0 \fi0 {\i apple} \par}+{\pard \ql \f0 \sa180 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \sa180 \li360 \fi0 contains seeds, crisp, pleasant to taste\par}+{\pard \ql \f0 \sa0 \li0 \fi0 {\i orange} \par}+{\pard \ql \f0 \sa180 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \sa180 \li360 \fi0 \f1 \{ orange code block \}\par}+{\pard \ql \f0 \sa180 \li1080 \fi0 orange block quote\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 HTML Blocks\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Simple block on one line:\par}+{\pard \ql \f0 \sa0 \li0 \fi0 foo\par}+{\pard \ql \f0 \sa180 \li0 \fi0 And nested without indentation:\par}+{\pard \ql \f0 \sa0 \li0 \fi0 foo\par}+{\pard \ql \f0 \sa0 \li0 \fi0 bar\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Interpreted markdown in a table:\par}+{\pard \ql \f0 \sa0 \li0 \fi0 This is {\i emphasized} \par}+{\pard \ql \f0 \sa0 \li0 \fi0 And this is {\b strong} \par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a simple block:\par}+{\pard \ql \f0 \sa0 \li0 \fi0 foo\par}+{\pard \ql \f0 \sa180 \li0 \fi0 This should be a code block, though:\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \f1 <div>\line+ foo\line+</div>\par}+{\pard \ql \f0 \sa180 \li0 \fi0 As should this:\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \f1 <div>foo</div>\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Now, nested:\par}+{\pard \ql \f0 \sa0 \li0 \fi0 foo\par}+{\pard \ql \f0 \sa180 \li0 \fi0 This should just be an HTML comment:\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Multiline:\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Code block:\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \f1 <!-- Comment -->\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Just plain comment, with trailing spaces on the line:\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Code:\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \f1 <hr />\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Hr\u8217's:\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Inline Markup\par}+{\pard \ql \f0 \sa180 \li0 \fi0 This is {\i emphasized} , and so {\i is this} .\par}+{\pard \ql \f0 \sa180 \li0 \fi0 This is {\b strong} , and so {\b is this} .\par}+{\pard \ql \f0 \sa180 \li0 \fi0 An {\i {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul+emphasized link+}}}+} .\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\b {\i This is strong and em.} } \par}+{\pard \ql \f0 \sa180 \li0 \fi0 So is {\b {\i this} } word.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\b {\i This is strong and em.} } \par}+{\pard \ql \f0 \sa180 \li0 \fi0 So is {\b {\i this} } word.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 This is code: {\f1 >} , {\f1 $} , {\f1 \\} , {\f1 \\$} , {\f1 <html>} .\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\strike This is {\i strikeout} .} \par}+{\pard \ql \f0 \sa180 \li0 \fi0 Superscripts: a{\super bc} d a{\super {\i hello} } a{\super hello there} .\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Subscripts: H{\sub 2} O, H{\sub 23} O, H{\sub many of them} O.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Smart quotes, ellipses, dashes\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \u8220"Hello,\u8221" said the spider. \u8220"\u8216'Shelob\u8217' is my name.\u8221"\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \u8216'A\u8217', \u8216'B\u8217', and \u8216'C\u8217' are letters.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \u8216'Oak,\u8217' \u8216'elm,\u8217' and \u8216'beech\u8217' are names of trees. So is \u8216'pine.\u8217'\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \u8216'He said, \u8220"I want to go.\u8221"\u8217' Were you alive in the 70\u8217's?\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here is some quoted \u8216'{\f1 code} \u8217' and a \u8220"{\field{\*\fldinst{HYPERLINK "http://example.com/?foo=1&bar=2"}}{\fldrslt{\ul+quoted link+}}}+\u8221".\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Some dashes: one\u8212-two\u8212-three\u8212-four\u8212-five.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Dashes between numbers: 5\u8211-7, 255\u8211-66, 1987\u8211-1999.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Ellipses\u8230?and\u8230?and\u8230?.\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 LaTeX\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\cf1 \\cite[22-23]\{smith.1899\}\cf0 } \par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\cf1 \\doublespacing\cf0 } \par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\cf1 $2+2=4$\cf0 } \par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\cf1 $x \\in y$\cf0 } \par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\cf1 $\\alpha \\wedge \\omega$\cf0 } \par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\cf1 $223$\cf0 } \par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\cf1 $p$\cf0 } -Tree\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\cf1 $\\frac\{d\}\{dx\}f(x)=\\lim_\{h\\to 0\}\\frac\{f(x+h)-f(x)\}\{h\}$\cf0 } \par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Here\u8217's one that has a line break in it: {\cf1 $\\alpha + \\omega \\times x^2$\cf0 } .\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 These shouldn\u8217't be math:\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab To get the famous equation, write {\f1 $e = mc^2$} .\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab $22,000 is a {\i lot} of money. So is $34,000. (It worked if \u8220"lot\u8221" is emphasized.)\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Escaped {\f1 $} : $73 {\i this should be emphasized} 23$.\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a LaTeX table:\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\cf1 \\begin\{tabular\}\{|l|l|\}\\hline+Animal & Number \\\\ \\hline+Dog & 2 \\\\+Cat & 1 \\\\ \\hline+\\end\{tabular\}\cf0 } \par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Special Characters\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here is some unicode:\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab I hat: \u206?\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab o umlaut: \u246?\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab section: \u167?\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab set membership: \u8712?\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab copyright: \u169?\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 AT&T has an ampersand in their name.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 AT&T is another way to write it.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 This & that.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 4 < 5.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 6 > 5.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Backslash: \\\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Backtick: `\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Asterisk: *\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Underscore: _\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Left brace: \{\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Right brace: \}\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Left bracket: [\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Right bracket: ]\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Left paren: (\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Right paren: )\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Greater-than: >\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Hash: #\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Period: .\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Bang: !\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Plus: +\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Minus: -\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Links\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Explicit\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Just a {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+URL+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+URL and title+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+URL and title+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+URL and title+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+URL and title+}}}+\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+URL and title+}}}+\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/with_underscore"}}{\fldrslt{\ul+with_underscore+}}}+\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "mailto:nobody@nowhere.net"}}{\fldrslt{\ul+Email link+}}}+\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK ""}}{\fldrslt{\ul+Empty+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Reference\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+bar+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+bar+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+bar+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 With {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+embedded [brackets]+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+b+}}}+ by itself should be a link.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Indented {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul+once+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Indented {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul+twice+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Indented {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul+thrice+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 This should [not][] be a link.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \f1 [not]: /url\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+bar+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+biz+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 With ampersands\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a {\field{\*\fldinst{HYPERLINK "http://example.com/?foo=1&bar=2"}}{\fldrslt{\ul+link with an ampersand in the URL+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a link with an amersand in the link text: {\field{\*\fldinst{HYPERLINK "http://att.com/"}}{\fldrslt{\ul+AT&T+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's an {\field{\*\fldinst{HYPERLINK "/script?foo=1&bar=2"}}{\fldrslt{\ul+inline link+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's an {\field{\*\fldinst{HYPERLINK "/script?foo=1&bar=2"}}{\fldrslt{\ul+inline link in pointy braces+}}}+.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 Autolinks\par}+{\pard \ql \f0 \sa180 \li0 \fi0 With an ampersand: {\field{\*\fldinst{HYPERLINK "http://example.com/?foo=1&bar=2"}}{\fldrslt{\ul+{\f1 http://example.com/?foo=1&bar=2} +}}}+\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab In a list?\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\field{\*\fldinst{HYPERLINK "http://example.com/"}}{\fldrslt{\ul+{\f1 http://example.com/} +}}}+\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab It should.\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 An e-mail address: {\field{\*\fldinst{HYPERLINK "mailto:nobody@nowhere.net"}}{\fldrslt{\ul+{\f1 nobody@nowhere.net} +}}}+\par}+{\pard \ql \f0 \sa180 \li720 \fi0 Blockquoted: {\field{\*\fldinst{HYPERLINK "http://example.com/"}}{\fldrslt{\ul+{\f1 http://example.com/} +}}}+\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Auto-links should not occur here: {\f1 <http://example.com/>} \par}+{\pard \ql \f0 \sa180 \li0 \fi0 \f1 or here: <http://example.com/>\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Images\par}+{\pard \ql \f0 \sa180 \li0 \fi0 From \u8220"Voyage dans la Lune\u8221" by Georges Melies (1902):\par}+{\pard \ql \f0 \sa180 \li0 \fi0 {\cf1 [image: lalune.jpg]\cf0}\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here is a movie {\cf1 [image: movie.jpg]\cf0} icon.\par}+{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs36 Footnotes\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Here is a footnote reference,{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \sa180 \li0 \fi0 Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.\par}+} and another.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's the long note. This one contains multiple blocks.\par}+{\pard \ql \f0 \sa180 \li0 \fi0 Subsequent blocks are indented to show that they belong to the footnote (as with list items).\par}+{\pard \ql \f0 \sa180 \li0 \fi0 \f1 \{ <code> \}\par}+{\pard \ql \f0 \sa180 \li0 \fi0 If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.\par}+} This should {\i not} be a footnote reference, because it contains a space.[^my note] Here is an inline note.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \sa180 \li0 \fi0 This is {\i easier} to type. Inline notes may contain {\field{\*\fldinst{HYPERLINK "http://google.com"}}{\fldrslt{\ul+links+}}}+ and {\f1 ]} verbatim characters, as well as [bracketed text].\par}+}\par}+{\pard \ql \f0 \sa180 \li720 \fi0 Notes can go in quotes.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \sa180 \li0 \fi0 In quote.\par}+}\par}+{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab And in list items.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \sa180 \li0 \fi0 In list.\par}+}\sa180\par}+{\pard \ql \f0 \sa180 \li0 \fi0 This paragraph should not be part of the note, as it is not indented.\par}++}+
+ web/Makefile view
@@ -0,0 +1,37 @@+ALL := index.html osx-notes.html README.html INSTALL.html examples.html pandoc1.html markdown2pdf1.html html2markdown1.html hsmarkdown1.html+PANDOC_PATH ?= $(dir $(shell which pandoc))+MAKEPAGE = $(PANDOC_PATH)/pandoc -s -S -c pandoc.css -A footer.html+all : $(ALL)++.PHONY: clean+clean:+ for file in $(ALL); do rm $$file; done; \+ rm -r example*;++examples.txt : $(PANDOC_DEPS) mkdemos.pl config.xsl S5DEMO README demos+ PATH=$(PANDOC_PATH):$$PATH ./mkdemos.pl demos $@+ perl -pi -e 's!(href="(main|(my)?header|footer|example\d+)\.(html|tex|xml|css))"!\1.html"!g' $@+ for file in $$(ls | egrep '(main|(my)?header|footer|example[0-9]+)\.(html|tex|xml|css)$$'); \+ do highlight -u utf-8 --style emacs $$file > $$file.html; \+ done++index.html : index.txt+ $(MAKEPAGE) --toc $< > $@++README.html : README+ $(MAKEPAGE) --toc $< > $@++INSTALL.html : INSTALL+ $(MAKEPAGE) --toc $< > $@++%.html : %.txt+ $(MAKEPAGE) $< > $@++%1.html : %.1+ groff -man -T html $< > $@++%.html : %+ $(MAKEPAGE) $< > $@++upload : + sitecopy --update macfarlane
+ web/S5DEMO view
@@ -0,0 +1,19 @@+% Eating Habits+% John Doe+% March 22, 2005++# In the morning++- Eat eggs+- Drink coffee++# In the evening++- Eat spaghetti+- Drink wine++# Conclusion++- And the answer is...+- $f(x)=\sum_{n=0}^\infty\frac{f^{(n)}(a)}{n!}(x-a)^n$ +
+ web/config.xsl view
@@ -0,0 +1,9 @@+<?xml version='1.0'?>+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"+ xmlns:fo="http://www.w3.org/1999/XSL/Format"+ version="1.0">+ <xsl:param name="use.id.as.filename" select="'1'"/>+ <xsl:param name="admon.graphics" select="'1'"/>+ <xsl:param name="admon.graphics.path"></xsl:param>+ <xsl:param name="html.stylesheet" select="'../docbook.css'"/>+</xsl:stylesheet>
+ web/demos view
@@ -0,0 +1,71 @@+% Pandoc examples++To see the output created by each of the commands below,+click on the name of the output file:++1. HTML fragment:++@ pandoc README -o example1.html++2. Standalone HTML file:++@ pandoc -s README -o example2.html++3. HTML with smart quotes, table of contents, CSS, and custom footer:++@ pandoc -s -S --toc -c pandoc.css -A footer.html README -o example3.html++4. LaTeX:++@ pandoc -s README -o example4.tex++5. From LaTeX to markdown:++@ pandoc -s example4.tex -o example5.text++6. reStructuredText:++@ pandoc -s -w rst --toc README -o example6.text++7. Rich text format (RTF):++@ pandoc -s README -o example7.rtf ++8. S5 HTML slide show (all in one file):++@ pandoc -s -m -i -w s5 S5DEMO -o example8.html++9. DocBook XML:++@ pandoc -s -S -w docbook README -o example9.db++ Chunked XHTML via DocBook and [xmlto]:++@ xmlto xhtml -m config.xsl example9.db -o example9/++10. Man page:++@ pandoc -s -w man pandoc.1.md -o example10.1++11. ConTeXt:++@ pandoc -s -w context README -o example11.tex++ PDF via pandoc and ConTeXt's `texexec`:++@ texexec --pdf example11.tex --result example11.pdf++12. Converting a web page to markdown:++@ html2markdown http://www.gnu.org/software/make/ -o example12.text++13. From markdown to PDF:++@ markdown2pdf README -o example13.pdf++14. PDF with numbered sections and a custom LaTeX header:++@ markdown2pdf -N -C myheader.tex README -o example14.pdf++[xmlto]: http://cyberelk.net/tim/xmlto/+
+ web/docbook.css view
@@ -0,0 +1,29 @@+body {+ font-family: Verdana, sans-serif;+}++.screen {+ font-family: monospace;+ font-size: 1em;+ display: block;+ padding: 10px;+ border: 1px solid #bbb;+ background-color: #eee;+ color: #000; + overflow: auto;+ border-radius: 2.5px;+ -moz-border-radius: 2.5px;+ margin: 0.5em 2em;+}++a {+ text-decoration: none;+ border-bottom: 1px dotted #000;+}++a:hover {+ background-color: #777;+ color: #fff;+}++
@@ -0,0 +1,4 @@+<div id="footer">+ © 2006-2007 <a href="http://sophos.berkeley.edu/macfarlane/">John MacFarlane</a>+</div>+
+ web/index.txt view
@@ -0,0 +1,166 @@+% Pandoc++# Overview++Pandoc is a [Haskell] library for converting from one markup format+to another, and a command-line tool that uses this library. It can read+[markdown] and (subsets of) [reStructuredText], [HTML], and [LaTeX],+and it can write [markdown], [reStructuredText], [HTML], [LaTeX], [ConTeXt],+[RTF], [DocBook XML], [groff man], and [S5] HTML slide shows. ++Pandoc features++- Modular design, using separate writers and readers for each+ supported format.+- A real markdown parser, not based on regex substitutions.+ [More accurate] and [faster], in many cases, than `Markdown.pl`.+- Also parses (subsets of) reStructuredText, LaTeX, and HTML.+- Multiple output formats: HTML, Docbook XML, LaTeX, ConTeXt,+ reStructuredText, Markdown, RTF, groff man pages, S5 slide shows.+- Unicode support.+- Optional "smart" quotes, dashes, and ellipses.+- Automatically generated tables of contents.+- [ASCIIMathML] support for equations in HTML.+- Extensions to markdown syntax:+ + Document metadata (title, author, date).+ + Footnotes, tables, and definition lists.+ + Superscripts, subscripts, and strikeout.+ + Inline LaTeX math and LaTeX commands.+ + Markdown inside HTML blocks.+ + Enhanced ordered lists: start number and numbering style+ are significant.+ + Compatibility mode to turn off syntax entensions and emulate+ `Markdown.pl`.+- Convenient wrapper scripts:+ + `html2markdown` makes it easy to produce a markdown version+ of any web page.+ + `markdown2pdf` converts markdown to PDF in one step.+ + `hsmarkdown` is a drop-in replacement for `Markdown.pl`.+- Multi-platform: runs on Windows, MacOS X, Linux, Unix.+- Free software, released under the [GPL].++To see what pandoc can do, see the [demonstration page](examples.html).++# Documentation++- [User's Guide](README.html)+- [Demonstrations](examples.html)+- Man pages+ - [`pandoc(1)`](pandoc1.html)+ - [`markdown2pdf(1)`](markdown2pdf1.html)+ - [`html2markdown(1)`](html2markdown1.html)+ - [`hsmarkdown(1)`](hsmarkdown1.html)+- [Library documentation](doc/index.html) (for Haskell programmers)+- [Instructions for installing from source](INSTALL.html)+- [Changelog](changelog)++# Downloads++- [Source tarball].+ To install, unpack the archive and follow the instructions in the+ [INSTALL](INSTALL.html) file. You'll need the [GHC] Haskell compiler,+ version 6.6 or higher.++- [MacOS X binary package].+ To install, just double-click the package icon in the disk+ image. See the [installation notes](osx-notes.html) for important+ information about setting your `PATH`. Note: This package was+ compiled on a G4 Mac; it will also work on an Intel Mac via emulation.++- [Windows binary package].+ The zip file contains the `pandoc.exe` command-line program (which+ you should extract from the zip archive and put somewhere in your+ PATH). See the included file `README.txt` for instructions+ on using the program. Note: If you use [Cygwin], we recommend that+ you compile Pandoc from source. This will give you access to the+ wrapper scripts `markdown2pdf`, `html2markdown`, and `hsmarkdown`,+ which are not included in the Windows binary package.++- [FreeBSD port].++- [Debian linux package] (thanks to Recai Oktaş). This will also work+ on Ubuntu and other Debian derivatives. To install, download the file+ and type:++ sudo dpkg -i pandoc_0.4_i386.deb++# Code repository++Pandoc has a publicly accesible subversion repository at Google+Code (<http://code.google.com/p/pandoc>). To check out the latest,+bleeding-edge source code:++ svn checkout http://pandoc.googlecode.com/svn/trunk/ pandoc++# Reporting bugs++You may view existing bug reports and submit new ones at +<http://code.google.com/p/pandoc/issues/list>.++# Mailing lists++- [pandoc-announce]: Announcements of new releases only.+- [pandoc-discuss]: General discussion of pandoc.++# News++- Version 0.4 released (August 15, 2007).++ For users:++ + New output formats: ConTeXt and groff man.+ + Support for definition lists and tables.+ + Support for superscript, subscript, and strikeout.+ + Support for automatically generated tables of contents.+ + Automatically generated unique identifiers in HTML headers.+ + Enhanced ordered lists (start number and list number style+ are now significant).+ + Markdown links now printed as inline links by default,+ unless `--reference-links` option is specified.+ + Many bugs fixed.++ For programmers:++ + Added a Text.Pandoc module that exports the main functions+ and data structures. Library documentation includes a sample+ program using the library.++ Under the hood:++ + Refactored to avoid reliance on GHC's `Text.Regex`, which+ is slow and does not support unicode.+ + Removed Key and Note block elements and simplified parsers.+ + Improved handling of character entities.+ + HTML output is now generated using `Text.XHtml`.++# Disclaimer++This is an early, "alpha" release. It carries no warranties of any+kind.++[More accurate]: http://code.google.com/p/pandoc/wiki/PandocVsMarkdownPl+[faster]: http://code.google.com/p/pandoc/wiki/Benchmarks+[ASCIIMathML]: http://www1.chapman.edu/~jipsen/mathml/asciimath.html+ +[John MacFarlane]: http://sophos.berkeley.edu/macfarlane/+[markdown]: http://daringfireball.net/projects/markdown/+[reStructuredText]: http://docutils.sourceforge.net/docs/ref/rst/introduction.html+[S5]: http://meyerweb.com/eric/tools/s5/+[HTML]: http://www.w3.org/TR/html40/+[LaTeX]: http://www.latex-project.org/+[ConTeXt]: http://www.pragma-ade.nl/ +[RTF]: http://en.wikipedia.org/wiki/Rich_Text_Format+[DocBook XML]: http://www.docbook.org/+[groff man]: http://developer.apple.com/DOCUMENTATION/Darwin/Reference/ManPages/man7/groff_man.7.html+[Haskell]: http://www.haskell.org/+[GHC]: http://www.haskell.org/ghc/+[GPL]: http://www.gnu.org/copyleft/gpl.html+[Source tarball]: http://code.google.com/p/pandoc/downloads/detail?name=pandoc-0.4.tar.gz "Download source tarball from Pandoc's Google Code site"+[MacOS X binary package]: http://code.google.com/p/pandoc/downloads/detail?name=pandoc-0.4.dmg "Download Mac OS X disk image from Pandoc's Google Code site"+[Windows binary package]: http://code.google.com/p/pandoc/downloads/detail?name=pandoc-0.4.zip "Download Windows zip file from Pandoc's Google Code site"+[Cygwin]: http://www.cygwin.com/ "Cygwin - a linux-like environment for Windows"+[Debian linux package]: pandoc_0.4_i386.deb+[FreeBSD port]: http://www.freshports.org/textproc/pandoc/+[pandoc-announce]: http://groups.google.com/group/pandoc-announce+[pandoc-discuss]: http://groups.google.com/group/pandoc-discuss+
+ web/mkdemos.pl view
@@ -0,0 +1,31 @@+#!/usr/bin/perl -w+# first argument is input filename - a demo template.+# second argument is output filename.++my $infile=$ARGV[0];+my $outfile=$ARGV[1];++open( IN, "< $infile" );+open( OUT, "> $outfile" );++while (<IN>) {++ my $line = $_;+ my $firstchar = substr ($line,0,1);+ if ( $firstchar eq '@' ) {+ my $command = substr ($line,4);+ print STDERR "$command";+ system "$command";+ $line = $command;+ $line =~ s/-/\-/;+ $line =~ s/ ([A-Za-z0-9_:\/]+(\.|\/)[a-zA-Z0-9.\/]*|README|S5DEMO)/ <a href="$1">$1<\/a>/g;+ $line =~ s/-/\\-/g;+ $line =~ s/^(.*)$/ <code>$1<\/code>/g; + if ( $line =~ /(example\d+\.html)<\/a><\/code>/m ) {+ $line .= "\n (View [`$1` as a web page]($1).)\n";+ }+ }+ print OUT $line;++}+
+ web/myheader.tex view
@@ -0,0 +1,5 @@+\documentclass[11pt]{article}+\usepackage{pxfonts}+\usepackage[margin=1.5in]{geometry}+\usepackage{ucs}+\usepackage[utf8x]{inputenc}
+ web/pandoc.css view
@@ -0,0 +1,71 @@+body {+ margin: auto;+ padding-right: 1em;+ padding-left: 1em;+ max-width: 44em; + border-left: 1px solid black;+ border-right: 1px solid black;+ color: black;+ font-family: Verdana, sans-serif;+ font-size: 100%;+ line-height: 140%;+ color: #333; +}+pre {+ border: 1px dotted gray;+ background-color: #ececec;+ color: #1111111;+ padding: 0.5em;+}+code {+ font-family: monospace;+ font-size: 110%;+}+h1, h2, h3, h4, h5 { font-family: verdana;+ font-weight: bold;+ border-bottom: 1px dotted black;+ color: #7a5ada; }+h1 {+ font-size: 130%;+}++h2 {+ font-size: 110%;+}++h3 {+ font-size: 95%;+}++h4 {+ font-size: 90%;+ font-style: italic;+}++h5 {+ font-size: 90%;+ font-style: italic;+}++h1.title {+ font-size: 200%;+ font-weight: bold;+ padding-top: 0.2em;+ padding-bottom: 0.2em;+ text-align: left;+ border: none;+}++dt code {+ font-weight: bold;+}+dd p {+ margin-top: 0;+}++#footer {+ padding-top: 1em;+ font-size: 70%;+ color: gray;+ text-align: center;+}