packages feed

mediawiki2latex (empty) → 7.5

raw patch · 14 files changed

+7137/−0 lines, 14 filesdep +HTTPdep +arraydep +basesetup-changed

Dependencies added: HTTP, array, base, blaze-html, bytestring, containers, directory, directory-tree, file-embed, filepath, happstack-server, highlighting-kate, http-conduit, hxt, hxt-http, mtl, network, parsec, process, split, temporary, text, transformers, url, utf8-string, utility-ht

Files

+ LICENSE view
@@ -0,0 +1,339 @@+                    GNU GENERAL PUBLIC LICENSE+                       Version 2, June 1991++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,+ 51 Franklin Street, 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 Lesser 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 Street, 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 Lesser General+Public License instead of this License.
+ Setup.lhs view
@@ -0,0 +1,4 @@+#!/usr/bin/env runhaskell++> import Distribution.Simple+> main = defaultMain
+ mediawiki2latex.cabal view
@@ -0,0 +1,73 @@+Name:           mediawiki2latex+Version:        7.5+License:        GPL+License-File:   LICENSE+Author:         Dirk Hünniger <hunniger@cip.physik.uni-bonn.de>+Maintainer:     Dirk Hünniger <hunniger@cip.physik.uni-bonn.de>+Homepage:       http://sourceforge.net/projects/wb2pdf/+Category:       Text+Synopsis:       Convert MediaWiki text to LaTeX+Description:+   Wb2pdf converts MediaWiki markup to LaTeX and PDF.+   So it provides and export from MediaWiki to LaTeX.+   It works with any project running MediaWiki, especially Wikipedia and Wikibooks.+Stability:      Experimental+Tested-With:    GHC==6.12.3+Tested-With:    GHC==7.4.1+Cabal-Version:  >=1.6+Build-Type:     Simple++Source-Repository head+  Type: git+  Location: git://git.code.sf.net/p/wb2pdf/git+++Executable mediawiki2latex+  Build-Depends:+    directory-tree,+    bytestring,+    process,+    http-conduit,+    bytestring >= 0.10,+    temporary >1.0,+    file-embed,+    url >=2.1 ,+    hxt-http >=9 ,+    hxt >=8 ,+    utf8-string >=0.3.6 ,+    parsec >=2.1 ,+    HTTP >=4000 ,+    split >=0.1.2.3 ,+    containers >=0.3 ,+    base >=4.1 && < 5,+    highlighting-kate >=0.5,+    utility-ht >=0.0.5 ,+    transformers >=0.3 ,+    directory >=1.0 ,+    blaze-html,+    array,+    filepath,+    text,+    happstack-server,+    mtl,+    network >= 2.3.0.13++  Other-Modules:+    MagicStrings+    MediaWikiParseTree+    Tools+    UrlAnalyse+    LatexRenderer+    MagicStrings+    MediaWikiParser+    MediaWikiParseTree+    MyState+    TableHelper+    WikiHelper+    WikiLinkHelper++  GHC-Options:    -Wall -O2  -rtsopts "-with-rtsopts=-K100M -N" -threaded +  Hs-Source-Dirs: src+  Main-Is: mediawiki2latex.hs++
+ src/LatexRenderer.hs view
@@ -0,0 +1,2731 @@+{-DHUN| This modules converts the parse tree to a latex document DHUN-}+module LatexRenderer+       (treeToLaTeX3, shallowFlatten, prepateTemplate, replace, doUnicode,+        getGalleryNumbers, getTitle, initialState, getJ, urld,+        analyseNetloc, templateMap, getUserTemplateMap, urls, mUrlState,+        initialUrlState, makeLables, templateRegistry, baseUrl,+        deepFlatten)+       where+import Data.String.HT (trim)+import MyState+import Data.List+import qualified Data.Map as Map+import Data.Map (Map)+import Data.Char+import Text.Printf+import FontTool+import MediaWikiParseTree+import MagicStrings+import Tools+import Control.Monad.Trans.State+       (State, state, runState, StateT, runStateT, put, get)+import Control.Monad.Trans.Class (lift)+import Control.Monad (guard, mplus, msum)+import TableHelper+import GHC.Float+import Text.Highlighting.Kate+import WikiLinkHelper+import WikiHelper+import Data.List.Split+import BaseFont+import Data.Maybe+import Data.Tuple (swap)+ +{-DHUN| flattens a part of the parse tree, that is takes the characters found in the tree and turns them into a string dropping all other information in the tree DHUN-}+ +deepFlatten :: [Anything t] -> [Anything t]+deepFlatten ll = concat $ map go ll+  where go (Environment _ _ l) = (deepFlatten l)+        go x = [x]+ +{-DHUN|  the maximum width of lines for preformat and source code DHUN-}+ +linewidth :: Int+linewidth = 80+ +{-DHUN| The user can provide her own translation table for mediawiki templates to latex commands. this is done in the templates.user files. This function takes this file in list representation and converts it to the map representation to be able to look up the names of templates DHUN-}+ +getUserTemplateMap :: [[String]] -> Map String [String]+getUserTemplateMap input+  = Map.fromList (map (\ (x : xs) -> (x, xs)) input)+ +{-DHUN| table may omit tailing columns in a row, but in latex they need to be written out, this function does so DHUN-}+ +rowaddsym :: TableState -> [Char]+rowaddsym st+  = if (currentColumn st) < ((numberOfColumnsInTable st) + 1) then+      (if (currentColumn st) == 1 then+         replicate (((numberOfColumnsInTable st)) - (currentColumn st)) '&'+         else+         replicate (((numberOfColumnsInTable st) + 1) - (currentColumn st))+           '&')+      else []+ +{-DHUN| This function renders the inner parts of a table to latex it does so by calling tableContentToLaTeX and additionally removes superfluous newlines which might cause compilation problems in latex when used inside tables DHUN-}+ +tableContentToLaTeX2 ::+                     [Anything Char] -> (StateT TableState (State MyState) String)+tableContentToLaTeX2 l+  = do r <- tableContentToLaTeX l+       return (killnl2 r)+ +{-DHUN| This function renders the inner parts of a table to latex, please always use tableContentToLaTeX2 since this also removes superfluous newlines DHUN-}+ +tableContentToLaTeX ::+                    [Anything Char] -> (StateT TableState (State MyState) String)+tableContentToLaTeX ((Environment TableRowSep _ _) : [])+  = do st <- get+       let cc = (currentColumn st)+       let c = cc + (multiRowCount cc (multiRowMap st))+       return $+         (headendsym (lastCellWasHeaderCell st)) +++           (multiColumnEndSymbol (lastCellWasMultiColumn st)) +++             (rowaddsym st{currentColumn = c})+tableContentToLaTeX ((Environment TableRowSep _ l) : xs)+  = do sst <- lift get+       st <- get+       let cc = (currentColumn st)+       let c = cc + (multiRowCount cc (multiRowMap st))+       let mycond+             = (not (currentRowIsHeaderRow st)) &&+                 (stillInTableHeader st) &&+                   (lastRowHadEmptyMultiRowMap st) && (not (isFirstRow st))+       put+         (st{rowCounter = 1 + (rowCounter st),+             outputTableHasHeaderRows =+               (outputTableHasHeaderRows st) || (currentRowIsHeaderRow st),+             lastRowHadEmptyMultiRowMap = (myempty (multiRowMap st))})+       st2 <- get+       put+         st2{outputLastRowOfHeader =+               (if mycond then rowCounter st2 else outputLastRowOfHeader st2)}+       st3 <- get+       put+         st3{lastCellWasNotFirstCellOfRow = False,+             lastCellWasMultiColumn = False, currentColumn = 1,+             multiRowMap =+               multiRowDictChange (currentColumn st) (multiRowMap st) l,+             lastCellWasMultiRow = False, isFirstRow = False,+             lastCellWasHeaderCell = False, currentRowIsHeaderRow = False,+             stillInTableHeader =+               if stillInTableHeader st then not mycond else False}+       xx <- tableContentToLaTeX xs+       return $+         if (not (isFirstRow st)) then+           (headendsym (lastCellWasHeaderCell st)) +++             (multiColumnEndSymbol (lastCellWasMultiColumn st)) +++               (multiRowEndSymbol (lastCellWasMultiRow st)) +++                 (multiRowSymbolForRowSep (currentColumn st) (multiRowMap st)+                    (seperatingLinesRequestedForTable st))+                   +++                   (rowaddsym st{currentColumn = c}) +++                     (rowendsymb ((getInTab sst) <= 1)+                        ((rowCounter st) == (inputLastRowOfHeader st) - 2))+                       +++                       (innerHorizontalLine (seperatingLinesRequestedForTable st)+                          (multiRowMap st3)+                          (numberOfColumnsInTable st))+                         ++ " \n" ++ xx+           else xx+tableContentToLaTeX ((Environment TableColSep _ l) : xs)+  = do st <- get+       let cc = (currentColumn st)+       let c = cc + (multiRowCount cc (multiRowMap st))+       put+         st{lastCellWasNotFirstCellOfRow = True,+            lastCellWasMultiColumn =+              ("" /=+                 (multiColumnStartSymbol l (columnsWidthList st) c+                    (seperatingLinesRequestedForTable st)+                    st)),+            currentColumn = (c + (columnMultiplicityForCounting l)),+            multiRowMap =+              multiRowDictChange (currentColumn st) (multiRowMap st) l,+            lastCellWasMultiRow =+              (multiRowStartSymbol l (activeColumn st)) /= "",+            isFirstRow = False, lastCellWasHeaderCell = False}+       xx <- tableContentToLaTeX xxs+       return $+         (headendsym (lastCellWasHeaderCell st)) +++           (multiColumnEndSymbol (lastCellWasMultiColumn st)) +++             (multiRowEndSymbol (lastCellWasMultiRow st)) +++               (columnSeperator (lastCellWasNotFirstCellOfRow st)) +++                 (multiRowSymbol (currentColumn st) (multiRowMap st)+                    (seperatingLinesRequestedForTable st))+                   +++                   (multiColumnStartSymbol l (columnsWidthList st) c+                      (seperatingLinesRequestedForTable st)+                      st)+                     +++                     (multiRowStartSymbol l (activeColumn st)) +++                       (if rig then "\\RaggedLeft{}" else "") +++                         (tablecolorsym l) ++ hypennothing ++ xx+  where rig+          = isInfixOf2+              [Environment Attribute (Attr ("style", "text-align:right")) []]+              l+        xxs+          = if rig then (reverse . removesp . reverse . removesp) xs else xs+        removesp (C ' ' : as) = removesp as+        removesp a = a+tableContentToLaTeX ((Environment TableHeadColSep _ l) : xs)+  = do st <- get+       let cc = currentColumn st+       let c = cc + (multiRowCount cc (multiRowMap st))+       put+         st{lastCellWasNotFirstCellOfRow = True,+            lastCellWasMultiColumn =+              ("" /=+                 (multiColumnStartSymbol l (columnsWidthList st) c+                    (seperatingLinesRequestedForTable st)+                    st)),+            currentColumn = (c + (columnMultiplicityForCounting l)),+            multiRowMap =+              multiRowDictChange (currentColumn st) (multiRowMap st) l,+            lastCellWasMultiRow =+              multiRowStartSymbol l (activeColumn st) /= "",+            isFirstRow = False, lastCellWasHeaderCell = True,+            currentRowIsHeaderRow = True}+       xx <- tableContentToLaTeX xs+       return $+         (headendsym (lastCellWasHeaderCell st)) +++           (multiColumnEndSymbol (lastCellWasMultiColumn st)) +++             (multiRowEndSymbol (lastCellWasMultiRow st)) +++               (columnSeperator (lastCellWasNotFirstCellOfRow st)) +++                 (multiRowSymbol (currentColumn st) (multiRowMap st)+                    (seperatingLinesRequestedForTable st))+                   +++                   (multiColumnStartSymbol l (columnsWidthList st) c+                      (seperatingLinesRequestedForTable st)+                      st)+                     +++                     (multiRowStartSymbol l (activeColumn st)) +++                       headstartsym ++ (tablecolorsym l) ++ hypennothing ++ xx+tableContentToLaTeX (x : xs)+  = do st <- get+       ele <- case (activeColumn st) of+                  Just n | (n /= fromIntegral (currentColumn st)) ||+                             (lastCellWasMultiColumn st)+                           -> return []+                  _ -> lift $ treeToLaTeX2 [x]+       xx <- tableContentToLaTeX xs+       return $ ele ++ xx+tableContentToLaTeX []+  = do st <- get+       return $+         (headendsym (lastCellWasHeaderCell st)) +++           (multiColumnEndSymbol (lastCellWasMultiColumn st)) +++             (multiRowSymbolForTableEnd (currentColumn st) (multiRowMap st)+                (seperatingLinesRequestedForTable st))+               ++ (multiRowEndSymbol (lastCellWasMultiRow st)) ++ (rowaddsym st)+ +{-DHUN| This string has to be added to each new cell in a latex table in order to allow for hyphenation of the first word in this cell DHUN-}+ +hypennothing :: [Char]+hypennothing = "\\hspace*{0pt}\\ignorespaces{}\\hspace*{0pt}"+ +{-DHUN| color cell in latex if HTML attribute bgcolor is present in the parse tree for the cell DHUN-}+ +tablecolorsym :: [Anything Char] -> [Char]+tablecolorsym ll+  = case genLookup "bgcolor" ll of+        Just x -> case x of+                      ('#' : ys) -> let (p, colname, col) = colinfo ('l' : 'l' : ys) in+                                      if p then "\\cellcolor[rgb]" ++ col else+                                        "\\cellcolor{" ++ colname ++ "}"+                      _ -> "\\cellcolor{" ++ x ++ "}"+        Nothing -> ""+ +{-DHUN| the caption of a table is given in |+ or <th> elements, it needs to be reformatted in the parse in oder to be rendered in latex as a multicolumn cell spanning the whole width of the table DHUN-}+ +reformatTableCaption ::+                     Int -> [Anything Char] -> MyState -> [Anything Char]+reformatTableCaption n+  ((Environment TableCap _ l) : ((Environment TableRowSep a b) : xs))+  st+  = if (filter (not . isSpace) (treeToLaTeX l st)) == [] then+      reformatTableCaption n xs st else+      (Environment TableRowSep (Str "") []) :+        ((Environment TableHeadColSep (Str "")+            [Environment Attribute (Attr ("colspan", (show n))) []])+           : l)+          ++ [(Environment TableRowSep a b)] ++ reformatTableCaption n xs st+reformatTableCaption n ((Environment TableCap _ l) : xs) st+  = if (filter (not . isSpace) (treeToLaTeX l st)) == [] then+      reformatTableCaption n xs st else+      (Environment TableRowSep (Str "") []) :+        ((Environment TableHeadColSep (Str "")+            [Environment Attribute (Attr ("colspan", (show n))) []])+           : l)+          +++          [(Environment TableRowSep (Str "") [])] +++            reformatTableCaption n xs st+reformatTableCaption n (x : xs) st+  = x : reformatTableCaption n xs st+reformatTableCaption _ [] _ = []+ +{-DHUN| strips column separators out of a parse tree or part of which DHUN-}+ +stripColSep :: [Anything Char] -> [Anything Char]+stripColSep = filter go+  where go (Environment TableHeadColSep _ _) = False+        go (Environment TableColSep _ _) = False+        go _ = True+ +{-DHUN| predicate to test if an element in the parse tree is a row separator DHUN-}+ +isRowSep :: Anything Char -> Bool+isRowSep (Environment TableRowSep _ _) = True+isRowSep _ = False+ +{-DHUN| strip empty rows out of the parse tree DHUN-}+ +stripempty :: [Anything Char] -> MyState -> [Anything Char]+stripempty [] _ = []+stripempty ((Environment TableRowSep a b) : xs) s+  = (Environment TableRowSep a b) : (stripempty xs s)+stripempty l s+  = if pred2 then (stripempty post2 s) else+      pre ++ (stripempty (post3 post) s)+  where post2+          = case post of+                (x : xs) -> if isRowSep x then xs else post+                [] -> post+        post3 o+          = case o of+                (x : (y : xs)) -> if (isRowSep x) && (isRowSep y) then+                                    post3 (y : xs) else (x : y : xs)+                x -> x+        pred2 = and (map (`elem` [' ', '\r', '\n']) inside)+        pre = takeWhile (not . isRowSep) l+        post = dropWhile (not . isRowSep) l+        inside = (treeToLaTeX (stripColSep pre)) s+ +{-DHUN| In order to determine the maximum width of columns, each table is precompiled with latex several times, with only one column included each time. this function creates the list of the latex sources of these tables, for one table in the parse tree DHUN-}+ +maketablist ::+            [Anything Char] -> TableState -> Int -> MyState -> [[Char]]+maketablist l tst nc mst = map tablo [1 .. (nc + 1)]+  where tablo n+          = "\\begin{tabular}{|" +++              (replicate nc 'l') +++                "|}" +++                  (fst+                     (fst+                        (runState+                           ((runStateT (tableContentToLaTeX2 l))+                              tst{inputLastRowOfHeader = -2, activeColumn = Just n})+                           mst)))+                    ++ "\\end{tabular}"+ +{-DHUN| Takes a map from int to double finds the biggest double and removes the corresponding key value pair from the map. This way wide columns are set to smaller sizes in order to fit the whole table onto the page width DHUN-}+ +removehighest :: Map Int Double -> Map Int Double+removehighest m+  | m /= Map.empty = Map.fromList (hlp (Map.toList m))+  where mx = maximum (Map.elems m)+        hlp ((_, v) : xs) | v == mx = xs+        hlp (x : xs) = x : (hlp xs)+        hlp [] = []+removehighest _ = Map.empty+ +{-DHUN| Returns a list of floats which represents the width of the columns of a table in units of the line width with the proper corrections for use in the a latex documents. If the boolean input parameter is true the table is understood to be written in landscape mode. It also take a map of Int to Double. This is the list of the maximum width of columns determined by  previous runs of latex on the table with only one column included per run DHUN-}+ +wdth3 :: Bool -> Map Int Double -> [Float]+wdth3 ls m+  | m /= Map.empty =+    (map+       ((* (1.0 - (scalefactor (fromIntegral n)))) .+          double2Float . (/ (linew2 ls)))+       (Map.elems mm))+  where n = (maximum (Map.keys m))+        mm = wdth ls n m+wdth3 _ _ = []+ +{-DHUN| Returns a table header which represents the width of the columns of a table in units of the line width with the proper corrections for use in the a latex documents. If the first boolean input parameter is true the table is understood to be written in landscape mode. It also take a map of Int to Double. This is the list of the maximum width of columns determined by  previous runs of latex on the table with only one column included per run. If second boolean parameter is true it is understood the the rule should be printed with the table, otherwise the table should be printed without rules DHUN-}+ +wdth2 :: Bool -> Map Int Double -> Bool -> String+wdth2 ls m b+  | m /= Map.empty =+    tableSpecifier b+      (map+         ((* (1.0 - (scalefactor (fromIntegral n)))) .+            double2Float . (/ (linew2 ls)))+         (Map.elems mm))+  where n = (maximum (Map.keys m))+        mm = wdth ls n m+wdth2 _ _ _ = []+ +{-DHUN| takes the list of maximum column widths created by previous runs of the latex compiler with only one columns included per run as map from Int to Double. Take the total number of columns of the table as Int. The table is understood to be printed in landscape mode if the boolean parameter is true. It returns a map from int to double representing the width of columns of the table to be used in the latex documents. So it takes raw widths. Which are just the width of the column if the width of the paper was infinite and return the width that fit on the finite width of the real paper DHUN-}+ +wdth :: Bool -> Int -> Map Int Double -> Map Int Double+wdth ls n mm+  = case+      (Control.Monad.msum+         (map hlp+            (zip+               (iterate removehighest+                  (Map.mapMaybe+                     (\ x -> Just $ x / (1.0 - (scalefactor (fromIntegral n))))+                     mm))+               [0 .. (length (Map.keys mm))])))+      of+        Just x -> if (sum (Map.elems x)) < (linew2 ls) then+                    Map.map (\ y -> y * ((linew2 ls) / (sum (Map.elems x)))) x else x+        Nothing -> (myfill ((linew2 ls) / (fromIntegral n)) Map.empty)+  where  +        hlp :: (Map Int Double, Int) -> Maybe (Map Int Double)+        hlp (m, i)+          | i /= n =+            let s = ((sum (Map.elems m)) :: Double) in+              if+                ((linew2 ls) / (fromIntegral n)) * (fromIntegral i) ++                  (sum (Map.elems m))+                  < (linew2 ls)+                then+                Just (myfill (((linew2 ls) - s) / ((fromIntegral i) :: Double)) m)+                else Nothing+        hlp _ = Just (myfill ((linew2 ls) / (fromIntegral n)) Map.empty)+         +        myfill :: Double -> Map Int Double -> Map Int Double+        myfill x m = Map.union m (Map.fromList (zip [1 .. n] (repeat x)))+ +{-DHUN| In landscape mode everything has to be multiplied by a factor of two. If the boolean parameter is true it is understood that the table should be printed in landscape mode. This function return the width of the line in latex using the units of latex DHUN-}+ +linew2 :: Bool -> Double+linew2 ls = if ls then linew * 1.414 else linew+ +{-DHUN| The width of the line in A4 paper with DIV margin factor of 13 in latex own units DHUN-}+ +linew :: Double+linew = 455.45742+ +{-DHUN| convert a table form the parse tree to latex. The [Anything Char] parameter it the contend of the table represented as a parse tree. The String parameter contains the HTML attributes of the table element, or in wiki notation the HTML parameters of the line beginning with  {| . This is evaluated in order to find out whether rules should be printed in the table. The return type is Renderer String. Which means that it returns a string but also take a state as additional monadic input parameter and returns a possible changed version of it as additional return parameter monadically DHUN-}+ +tableToLaTeX :: [Anything Char] -> String -> Renderer String+tableToLaTeX l1 s+  = do st <- get+       let modst = st{getF = (getF st) * (tableScale (numberOfColumns l))}+           ((_, oldstate), _)+             = runState ((runStateT (tableContentToLaTeX2 reformed)) tblstate)+                 modst+           ((t1, _), newstate)+             = runState+                 ((runStateT (tableContentToLaTeX2 reformed))+                    tblstate{inputLastRowOfHeader =+                               if outputTableHasHeaderRows oldstate then+                                 outputLastRowOfHeader oldstate else -2})+                 modst{tablist =+                         (maketablist reformed tblstate (numberOfColumns l) modst) :+                           (tablist st)}+           reformed = ((reformatTableCaption (numberOfColumns l) l st))+           l = stripempty l1 st+           spec+             = case Map.lookup tbno (tabmap st) of+                   Nothing -> (if (tableSpecifier sep widths) == "" then+                                 "p{\\linewidth}" else tableSpecifier sep widths)+                   Just t -> wdth2 lsc t sep+           sep = seperatingLinesRequested s+           hline = horizontalLine sep+           widths+             = case Map.lookup tbno (tabmap st) of+                   Nothing -> columnWidths l+                   Just t -> wdth3 lsc t+           env = tableEnvironment (getF st)+           scriptsize = isInfixOf2 "latexfontsize=\"scriptsize\"" s+           sb = if scriptsize then "{\\scriptsize{}" else ""+           se = if scriptsize then "}" else ""+           lsc = (env == "longtable") && ((numberOfColumns l) > 5)+           lsb = if lsc then "\\begin{landscape}\n" else ""+           lse = if lsc then "\n\\end{landscape}" else ""+           tbno = (length (tablist st)) + 1+           tblstate+             = TableState{seperatingLinesRequestedForTable = sep,+                          lastCellWasNotFirstCellOfRow = False,+                          lastCellWasMultiColumn = False, columnsWidthList = widths,+                          currentColumn = 1, multiRowMap = Map.empty,+                          lastCellWasMultiRow = False,+                          numberOfColumnsInTable = (numberOfColumns l), isFirstRow = True,+                          lastCellWasHeaderCell = False, currentRowIsHeaderRow = False,+                          stillInTableHeader = True, rowCounter = 0,+                          outputLastRowOfHeader = 0, inputLastRowOfHeader = 0,+                          lastRowHadEmptyMultiRowMap = True,+                          outputTableHasHeaderRows = False, activeColumn = Nothing}+       put $ newstate{getF = getF st}+       r <- return $+              lsb +++                sb +++                  (if (env /= "tabular") then "\n" else "") +++                    "\\begin{" +++                      env +++                        "}{" +++                          spec +++                            "}" +++                              hline +++                                " \n" +++                                  t1 +++                                    (rowDelimiter sep) ++ " \n\\end{" ++ env ++ "}\n" ++ se ++ lse+       return r+ +{-DHUN| Converts an image from the parse tree to latex. The actual images is only referenced in the wiki source, as well as the parse tree, as well as the latex source. It takes a parse tree representation of the image as only input parameter. The return type is Renderer String. Which means that it returns a string but also take a state as additional monadic input parameter and returns a possible changed version of it as additional return parameter monadically DHUN-}+ +wikiImageToLaTeX :: [Anything Char] -> Renderer String+wikiImageToLaTeX l+  = do st <- get+       mystr <- return $+                  (if not (micro st) then+                     "\n" +++                       (if ((getInTab st) == 0) then "\n" else "") +++                         "\\begin{minipage}{" +++                           (if (msb st) then "1.0" else (mysize st)) +++                             (if (msb st) then "\\linewidth" else "\\textwidth") ++ "}\n"+                     else (if ((getInTab st) == 0) then "\n" else ""))+                    +++                    (if (not (micro st)) then "\\begin{center}\n" else "") +++                      "\\includegraphics[width=" +++                        (if (not (micro st)) then "1.0" else (mysize st)) +++                          (if (msb st) then "\\linewidth" else "\\textwidth") +++                            ",height=6.5in,keepaspectratio]{../images/" +++                              (n st) +++                                "." +++                                  ext +++                                    "}\n" +++                                      (if (not (micro st)) then "\\end{center}\n" else "") +++                                        (if (not (tb st)) && (not (micro st)) then "\\raggedright{}"+                                           else "")+                                          +++                                          (if not (micro st) then+                                             (if (s st) == "" then+                                                "\\myfigurewithoutcaption{" ++ (n st) ++ "}" else+                                                "\\myfigurewithcaption{" +++                                                  (n st) ++ "}{" ++ (s st) ++ "}")+                                             else "")+                                            +++                                            (if not (micro st) then "\n\\end{minipage}" else "") +++                                              (addit st) +++                                                (if not (micro st) then+                                                   (if ((getInTab st) == 0) then "\n" else "") +++                                                     "\n"+                                                   else " ")+       put+         st{getImages = (getImages st) ++ [shallowFlatten l],+            getJ = ((getJ st) + 1)}+       return mystr+  where ext+          = normalizeExtension+              (map toLower+                 (fileNameToExtension (headSplitEq '|' (shallowFlatten l))))+        s st+          = if (trim (s1 st)) `elem` ["verweis=", "alt=", "link="] then ""+              else (s1 st)+        s2 st+          = case Map.lookup "alt" (snd (prepateTemplate l "x")) of+                Just xx -> wikiLinkCaption xx st+                Nothing -> wikiLinkCaption l st+        s1 st+          = if '|' `elem` (shallowFlatten l) then (s2 st) else+              (treeToLaTeX [] st{getJ = ((getJ st) + 1)})+        mysize st = printf "%0.5f" (mysizefloat2 st)+        mysizefloat st = (min (getF st) (imageSize l))+        mysizefloat2 st = if (msb st) then 1.0 else (mysizefloat st)+        msb st = (mysizefloat st) == (getF st)+        micro st = ((mysizefloat st) < 0.17) || ((getInTab st) > 1)+        n st = show (getJ st)+        tb st = ((getInTab st) > 0)+        addit st+          = if (getInTab st) > 0 then "" else+              (if not (micro st) then "\\vspace{0.75cm}" else "")+ +{-DHUN| Returns the caption of a wikilink. Takes a parse tree representation of the wikilink and the current state of the renderer. Return the caption in LaTeX representation as string. A Wikilink is represented as [[FooBar]] in Wiki notation. DHUN-}+ +wikiLinkCaption :: [Anything Char] -> MyState -> String+wikiLinkCaption l st = if isCaption x then rebuild x else ""+  where x = (treeToLaTeX (last (splitOn [C '|'] l)) st)+        rebuild (':' : xs) = xs+        rebuild b = b+ +{-DHUN| Returns the LaTeX representation of a wikilink. Takes a parse tree representation of the wikilink and the current state of the render. A Wikilink is represented as [[FooBar]] in Wiki notation. DHUN-}+ +wikiLinkToLaTeX :: [Anything Char] -> MyState -> String+wikiLinkToLaTeX l st+  = case+      Map.lookup (map toUpper (finalloc st))+        (Map.mapKeys (map toUpper) (urls st))+      of+        Just yy -> "\\my" +++                     addit ++ "lref{" ++ yy ++ "}{" ++ (wikiLinkCaption l st) ++ "}"+        Nothing -> case+                     do hh <- maybeHead . (splitOn "#") . (map toUpper) $ (finalloc st)+                        Map.lookup (Just hh)+                          (Map.mapKeys (maybeHead . (splitOn "#") . (map toUpper)) (urls st))+                     of+                       Just yy -> "\\my" +++                                    addit ++ "lref{" ++ yy ++ "}{" ++ (wikiLinkCaption l st) ++ "}"+                       Nothing -> "\\my" +++                                    addit +++                                      "href{" +++                                        (wikiLinkLocationesc l st) +++                                          "}{" ++ (killnl (wikiLinkCaption l st)) ++ "}"+  where zzz sssst+          = case localWikiLinkLocation (loc) of+                ('#' : xs) -> (currentUrl sssst) ++ ('#' : xs)+                xs -> xs+        finalloc3 sts = replace2 (trim (zzz sts)) " " "_"+        finalloc ssst+          = case reverse (finalloc3 ssst) of+                ('/' : xs) -> reverse xs+                _ -> finalloc3 ssst+        restpath+          = intercalate "/"+              (reverse (drop len (reverse (splitOn "/" (currentUrl st)))))+        loc = if len > 0 then restpath ++ "/" ++ rest else rest+        (len, rest) = doit2 0 (shallowFlatten l)+        doit2 n ('.' : ('.' : ('/' : xs))) = doit2 (n + 1) xs+        doit2 n xs = (n, xs)+        addit+          = if getInFootnote st then "fn" else+              if ((getInTab st) > 1) then "tab" else ""+        killnl ('\n' : ('\n' : xs)) = killnl ('\n' : xs)+        killnl (x : xs) = x : (killnl xs)+        killnl [] = []+ +{-DHUN| If repeated newlines appear in a string directly after each other. Each series of newlines is reduced to exactly one newline DHUN-}+ +killnl2 :: String -> String+killnl2 ('\n' : ('\n' : xs)) = killnl2 ('\n' : xs)+killnl2 ('\n' : xs)+  = if (trim pre) == "" then killnl2 post else pre ++ (killnl2 post)+  where pre = (takeWhile (/= '\n') xs)+        post = (dropWhile (/= '\n') xs)+killnl2 (x : xs) = x : (killnl2 xs)+killnl2 [] = []+ +{-DHUN| returns the caption of a link. A link is represented as [foobar.com mycaption] in wiki notation. It takes the parse tree representation of the link as first input parameter. The second input parameter is the current state of the renderer. The third parameter is the Uri scheme as string (See 'URI scheme' in the English wikipeda) usually this is 'http'. It returns the latex representation of the caption of the link as string DHUN-}+ +linkCaption ::+            [Anything Char] -> MyState -> String -> Bool -> String+linkCaption l st s b+  = case spl of+        (_ : (gg : gs)) -> (treeToLaTeX+                              (concat (map (\ x -> (C ' ') : x) (gg : gs)))+                              st)+        _ -> if b then "" else s ++ (escapelink (linkLocation l))+  where spl = splitOn [C ' '] l+ +{-DHUN| returns the latex representation of a link. A link is represented as [foobar.com mycaption] in wiki notation. It takes the parse tree representation of the link as first input parameter. The second input parameter is the current state of the renderer. The third parameter is the Uri scheme as string (See 'URI scheme' in the English wikipeda) usually this is 'http'. It returns the latex representation of the link as string DHUN-}+ +linkToLaTeX :: [Anything Char] -> MyState -> String -> String+linkToLaTeX l st s+  = if+      (b && cap == "") || (cap == (s ++ (escapelink (linkLocation l))))+      then "\\myplainurl{" ++ s ++ (escapelink (linkLocation l)) ++ "}"+      else+      "\\my" +++        addit +++          "href{" ++ s ++ (escapelink (linkLocation l)) ++ "}{" ++ cap ++ "}"+  where addit = if b then "fn" else ""+        b = getInFootnote st+        cap = (linkCaption l st s b)+ +{-DHUN| takes a list and splits it into sublist of equal length, allowing a possible smaller length for the last list in case the devision does not create an integer result. DHUN-}+ +splitToTuples :: [a] -> [[a]]+splitToTuples x+  = map (take galleryNumberOfColumns) .+      takeWhile (not . null) . iterate (drop galleryNumberOfColumns)+      $ x+ +{-DHUN| the number of column to be used in latex documents for mediawikis gallery (image gallery) (gallery tags) DHUN-}+ +galleryNumberOfColumns :: Int+galleryNumberOfColumns = 1+ +{-DHUN| the width of a column for the table of the latex version of mediawikis gallery (image gallery, gallery tags) DHUN-}+ +galleryTableScale :: Float+galleryTableScale+  = (1.0 / (fromIntegral galleryNumberOfColumns)) - (scalefactor 1.0)+ +{-DHUN| the latex string for a single column in table header in the latex version of mediawikis gallery (image gallery, gallery tag) DHUN-}+ +galleryTableSpecifier :: String+galleryTableSpecifier+  = concat $+      replicate galleryNumberOfColumns+        ">{\\RaggedRight}p{0.5\\linewidth}"+ +{-DHUN| converts the inner parts gallery (image gallery, gallery tag) from parse tree notation to latex, does not write the latex table header and footer. This is only a helper function. Always use galleryToLatex if you want to convert a gallery to latex DHUN-}+ +galleryContentToLatex :: [[Anything Char]] -> Renderer String+galleryContentToLatex (x : xs)+  = do s <- galleryRowToLaTex x+       ss <- galleryContentToLatex xs+       return $ s ++ "\\\\ \n" ++ ss+galleryContentToLatex [] = return []+ +{-DHUN| converts a part of a gallery (image gallery, gallery tag) from parse tree to latex. A part are as many elements as fit into a single row in the resulting latex table DHUN-}+ +galleryRowToLaTex :: [Anything Char] -> Renderer String+galleryRowToLaTex [] = return []+galleryRowToLaTex (x : []) = treeToLaTeX2 [x]+galleryRowToLaTex (x : xs)+  = do s <- treeToLaTeX2 [x]+       g <- galleryRowToLaTex xs+       return $ s ++ "&" ++ g+ +{-DHUN| Converts are gallery (image gallery, gallery tag) from parse tree to latex. Also writes table header and footer. This is the function you should use for converting galleries to latex DHUN-}+ +galleryToLatex :: [Anything Char] -> Renderer String+galleryToLatex x+  = do st <- get+       put st{getF = (getF st) * galleryTableScale}+       s <- (galleryContentToLatex+               [z | z <- splitToTuples [y | y <- x, isWikiLink y],+                trim (treeToLaTeX z st) /= ""])+       st2 <- get+       put st2{getF = (getF st)}+       return+         ("\\begin{longtable}{" +++            galleryTableSpecifier ++ "}  \n" ++ s ++ "\\end{longtable}")+ +{-DHUN| A function to drop all unnecessary elements of an HTML image map, so that it can be converted  to latex by calling treeToLaTeX2 DHUN-}+ +imageMapClean :: [Anything Char] -> [Anything Char]+imageMapClean ((Environment Wikilink s l) : xs)+  = (Environment Wikilink s l) : imageMapClean xs+imageMapClean (_ : xs) = imageMapClean xs+imageMapClean [] = []+ +{-DHUN| Takes the parse tree representation of an image, and returns the its size in unit of the width of a line in latex. Images 400px or wider in wiki notation are understood to use the full width of the line. Smaller one are considered fractionally. That means 100px means 0.25 the width of the line and 200px means 0.5 width of the line DHUN-}+ +imageSize :: [Anything Char] -> Float+imageSize l = if [] == x then 1.0 else (minimum x)+  where x = map readImageSize (imageSizeStrings (shallowFlatten l))+ +{-DHUN| takes a candidate string for the width of an image in the wikis px notation. Returns 1.0 if the candidate could not be parsed, returns the width of the image in units of the width of a line in latex otherwise. Images 400px or wider in wiki notation are understood to use the full width of the line. Smaller one are considered fractionally. That means 100px means 0.25 the width of the line and 200px means 0.5 width of the line DHUN-}+ +readImageSize :: String -> Float+readImageSize y+  = case (reads x) of+        [] -> 1.0+        (h : _) -> fst h / 400.0+  where x = removex y+        removex ('x' : zs) = zs+        removex z = z+ +{-DHUN| takes a flattend version of a parse tree represendtation of an image and retruns a list of substrings which are candidates for representing the width of the image in the wikis px notation DHUN-}+ +imageSizeStrings :: String -> [String]+imageSizeStrings s+  = [take (length (x) - 2) (x) |+     x <- ((splitOn ['|'] s) :: [String]), isSuffixOf "px" x]+ +{-DHUN| converts a mathematical fomula from the wiki to latex notation DHUN-}+ +mathToLatex :: [Anything Char] -> String+mathToLatex l+  = if isInfixOf2 "\\begin{alignat}" (shallowFlatten l) then+      mathTransform l else "{$" ++ (mathTransform l) ++ "$}"+ +{-DHUN| a predicate that returns true if and only if the input is a parse tree that contains only spaces but no other structures DHUN-}+ +onlySpaces :: [Anything Char] -> Bool+onlySpaces ((C ' ') : xs) = onlySpaces xs+onlySpaces [] = True+onlySpaces _ = False+ +{-DHUN| in the wiki notation pipe (|)inside temples are escaped as {!} and double pipes as {!!}}. this function undoes this escaping in a parse tree DHUN-}+ +prepateParameter :: [Anything Char] -> [Anything Char]+prepateParameter ((Environment Template _ [C '!']) : xs)+  = (C '|') : prepateParameter xs+prepateParameter ((Environment Template _ [C '!', C '!']) : xs)+  = (C '|') : (C '|') : prepateParameter xs+prepateParameter (x : xs) = x : prepateParameter xs+prepateParameter [] = []+ +{-DHUN| this function prepares a template as parse by the parser in the parse tree notation into a other notation that can be further processes by the latex renderer and the function templateToLatex in particular. The first input parameter is the parse tree notation of the template. The second is the name of the template as string. It returns a tuple, the first element of this tuple is the name of the template (stripped of heading an tailing white space) and the second element of the tuple is a map from strings to parse trees. The strings are the names of the parameters of the template. These might be just numbers represented as string but also any other strings DHUN-}+ +prepateTemplate ::+                [Anything Char] -> String -> (String, Map String [Anything Char])+prepateTemplate ll x = (trim x, enum ll 1 (Map.fromList []))+  where  +        enum ::+             [Anything Char] ->+               Integer -> Map String [Anything Char] -> Map String [Anything Char]+        enum ((Environment TemplateInside (Str "") l) : zs) i d+          = enum zs (i + 1) (Map.insert (show i) (prepateParameter l) d)+        enum ((Environment TemplateInside (Str z) l) : zs) i d+          = enum zs i (Map.insert (trim z) (prepateParameter l) d)+        enum [] _ d = d+        enum (_ : zs) i d = enum zs i d+ +{-DHUN| converts a template from the wiki to latex. The first parameter is the parse tree representation of the template as generated by the parse the second is the name of the template. It returns a Renderer String. That is it returns the latex representation of the template, but also takes a state as an additional monadic input parameter and returns a possible changed version of it as additional return parameter monadically DHUN-}+ +templateToLatex :: [Anything Char] -> String -> Renderer String+templateToLatex l s+  = state $+      \ st ->+        case l of+            ((C 'w') : ((C '|') : xs)) -> (wikiLinkToLaTeX+                                             ((C 'w') : (C ':') : xs)+                                             st,+                                           st)+            ((C 'W') : ((C '|') : xs)) -> (wikiLinkToLaTeX+                                             ((C 'w') : (C ':') : xs)+                                             st,+                                           st)+            ((C 'B') : ((C '|') : xs)) -> (wikiLinkToLaTeX xs st, st)+            _ -> swap $ templateProcessor st (prepateTemplate l s)+ +{-DHUN| function to converts wikipedias citearticle template to latex DHUN-}+ +citearticle :: Map String [Anything Char] -> Renderer String+citearticle ll+  = state $+      \ st ->+        ((treeToLaTeX (Map.findWithDefault [] "author" ll) st) +++           (treeToLaTeX (Map.findWithDefault [] "first" ll) st) +++             (if Map.member "first" ll then " " else "") +++               (treeToLaTeX (Map.findWithDefault [] "last" ll) st) +++                 ". " +++                   (treeToLaTeX (Map.findWithDefault [] "title" ll) st) +++                     (if Map.member "url" ll then+                        "\\my" +++                          (if getInFootnote st then "fn" else "") +++                            "href{" +++                              (treeToLaTeX (deepFlatten (Map.findWithDefault [] "url" ll)) st) +++                                "}{" ++ (treeToLaTeX (Map.findWithDefault [] "title" ll) st) ++ "}"+                        else (treeToLaTeX (Map.findWithDefault [] "title" ll) st))+                       +++                       ". " +++                         "\\textit{{}" +++                           (treeToLaTeX (Map.findWithDefault [] "journal" ll) st) +++                             "}, " +++                               (if Map.member "volume" ll then+                                  "{{\\bfseries " +++                                    (treeToLaTeX (Map.findWithDefault [] "volume" ll) st) ++ "}}"+                                  else "")+                                 +++                                 (if Map.member "publisher" ll then+                                    "(" +++                                      (treeToLaTeX (Map.findWithDefault [] "publisher" ll) st) +++                                        ")"+                                    else "")+                                   +++                                   (if Map.member "number" ll then+                                      "(" +++                                        (treeToLaTeX (Map.findWithDefault [] "number" ll) st) ++ ")"+                                      else "")+                                     +++                                     (if Map.member "pages" ll then+                                        ":" ++ (treeToLaTeX (Map.findWithDefault [] "pages" ll) st)+                                        else "")+                                       +++                                       (if Map.member "month" ll then+                                          (treeToLaTeX (Map.findWithDefault [] "month" ll) st) else+                                          "")+                                         +++                                         (treeToLaTeX (Map.findWithDefault [] "year" ll) st) +++                                           "\n",+         st)+ +{-DHUN| removes source structures from a parse tree, keeping the source inside the source structure in the parse tree, so flattens out the source structure. You need this if some parse tree contains source code but you don't know whether or not it is inside a source tag DHUN-}+ +flattensource :: [Anything Char] -> [Anything Char]+flattensource ((Environment Source (TagAttr _ _) l) : xs)+  = l ++ (flattensource xs)+flattensource (x : xs) = x : (flattensource xs)+flattensource [] = []+ +{-DHUN| prepare code for printing in latex. takes the current state of the renderer as first parameter. takes the map version of the template containing the code as second parameter. returns the latex representation as string DHUN-}+ +trilex :: MyState -> Map String [Anything Char] -> String+trilex st ll = trilexgen st ll "code"+ +{-DHUN| prepare code for printing in latex. Takes the map version of the template containing the code as first parameter. returns the latex representation as string. It returns a Render String so that it can access the current state of the renderer as additional monadic input parameter DHUN-}+ +trilex2 :: Map String [Anything Char] -> Renderer String+trilex2 ll+  = do st <- get+       return $ trilexgen st ll "code"+ +{-DHUN| prepare code for printing in latex. takes the current state of the renderer as first parameter. takes the map version of the template containing the code as second parameter. takes the name of the parameter containing the actual source in the map as third parameter. returns the latex representation as string DHUN-}+ +trilexgen ::+          MyState -> Map String [Anything Char] -> String -> String+trilexgen st ll code+  = if Map.member code ll then+      (treeToLaTeX+         (breakLines3 73+            (killnewline (flattensource (Map.findWithDefault [] code ll))))+         st)+      else ""+  where  +        killnewline :: [Anything Char] -> [Anything Char]+        killnewline ((C '\n') : xs) = killnewline xs+        killnewline x = x+ +{-DHUN| analyzes a color in HTML notation. It returns a triple. The first element is a boolean. If it is true the color has got rgb hex notation and the third parameter contains the rgb latex notation. If it is false, the color is not rgb and hopefully a HTML color name, which is returned a second element of the tuple DHUN-}+ +colinfo :: String -> (Bool, String, String)+colinfo colcode+  = case col of+        Just colo -> (True, map toLower colname, colo)+        Nothing -> (False, map toLower colname,+                    case colnamehelper of+                        Just x -> x+                        Nothing -> colcode)+  where col = (makecol colnamehelper)+        colnamehelper+          = case colcode of+                (_ : (_ : gs)) -> Just gs+                _ -> Nothing+        colname+          = case+              do n <- colnamehelper+                 guard $ mypred n+                 return ("rgb" ++ n)+              of+                Just x -> x+                Nothing -> colcode+         +        ss :: String -> [Integer]+        ss (a : (b : xs)) = (maybeToList . unhex $ [a, b]) ++ (ss xs)+        ss _ = []+         +        ss3 :: String -> [Integer]+        ss3 (a : xs) = (maybeToList . unhex $ [a, a]) ++ (ss3 xs)+        ss3 _ = []+         +        ss2 :: [Integer] -> [Float]+        ss2 (x : xs) = ((fromInteger x) / 255.0) : ss2 xs+        ss2 [] = []+        ss4 x = if (((length . ss) x) == 3) then ss x else ss3 x+         +        prettyp2 :: [String] -> String+        prettyp2 (x : []) = x+        prettyp2 (x : xs) = x ++ "," ++ (prettyp2 xs)+        prettyp2 [] = []+         +        prettyp :: [String] -> String+        prettyp x = "{" ++ (prettyp2 x) ++ "}"+         +        makecol :: Maybe String -> Maybe String+        makecol x+          = do xx <- x+               guard $ mypred xx+               return $+                 prettyp ((map (printf "%0.5f") ((ss2 . ss4) xx)) :: [String])+        mypred x = (((length . ss) x) == 3) || (((length . ss3) x) == 3)+ +{-DHUN| and adapter to convert between the monadic and non monadic version of render. A function returning renderer string means that it returns a string but takes a state as additional monadic input parameter and returns the a possibly modified version of it as an additional monadic output parameter. This function takes a monadic return value. That is renderer String and returns its non monadic version. DHUN-}+ +tempProcAdapter ::+                Renderer String -> (MyState -> (MyState, String))+tempProcAdapter = (swap .) . runState+ +{-DHUN| function for key strokes templates in the blender wikibook DHUN-}+ +key :: [Char] -> [Char]+key "AKEY" = "A"+key "BKEY" = "B"+key "CKEY" = "C"+key "DKEY" = "D"+key "EKEY" = "E"+key "FKEY" = "F"+key "GKEY" = "G"+key "HKEY" = "H"+key "IKEY" = "I"+key "JKEY" = "J"+key "KKEY" = "K"+key "LKEY" = "L"+key "MKEY" = "M"+key "NKEY" = "N"+key "OKEY" = "O"+key "PKEY" = "P"+key "QKEY" = "Q"+key "RKEY" = "R"+key "SKEY" = "S"+key "TKEY" = "T"+key "UKEY" = "U"+key "VKEY" = "V"+key "WKEY" = "W"+key "XKEY" = "X"+key "YKEY" = "Y"+key "ZKEY" = "Z"+key "-KEY" = "-{}"+key "SEMICOLON" = ";"+key "NUM-" = "NUM-{}"+key x = x+ +{-DHUN| converts a template to latex. Takes the current state of the render as first input parameter. The second input parameter is a tuple. Its first element is the name of the template as string. Its second element is a map, mapping the names of the parameters of the template to their parse tree representations, it returns a tuple. The First element is the possible change state of the renderer the second one is the latex representation of the template DHUN-}+ +templateProcessor ::+                  MyState ->+                    (String, Map String [Anything Char]) -> (MyState, String)+templateProcessor st ("main", ll)+  = (st,+     "Main Page: " +++       (wikiLinkToLaTeX (Map.findWithDefault [] "1" ll) st))+templateProcessor st ("!", _) = (st, "|")+templateProcessor st ("!!", _) = (st, "||")+templateProcessor st+  ("Mathe f\252r Nicht-Freaks: Vorlage:Frage", ll) = (st2, r)+  where j1 x = (Map.findWithDefault [] x ll)+        (r, st2)+          = runState+              (do a <- treeToLaTeX2 (j1 "typ")+                  b <- treeToLaTeX2 (j1 "frage")+                  c <- treeToLaTeX2 (j1 "antwort")+                  return $+                    if Map.member "typ" ll then+                      "\\NFFrage{" ++ a ++ "}{" ++ b ++ "}{" ++ c ++ "}" else+                      "\\NFFrageB{" ++ b ++ "}{" ++ c ++ "}")+              st+templateProcessor st ("Aufgabensammlung: Vorlage:Frage", ll)+  = (st2, r)+  where j1 x = (Map.findWithDefault [] x ll)+        (r, st2)+          = runState+              (do a <- treeToLaTeX2 (j1 "typ")+                  b <- treeToLaTeX2 (j1 "frage")+                  c <- treeToLaTeX2 (j1 "antwort")+                  return $+                    if Map.member "typ" ll then+                      "\\NFFrage{" ++ a ++ "}{" ++ b ++ "}{" ++ c ++ "}" else+                      "\\NFFrageB{" ++ b ++ "}{" ++ c ++ "}")+              st+templateProcessor st+  ("Mathe f\252r Nicht-Freaks: Vorlage:Mind Map", ll)+  = (st2,+     "\\section*{Mind Map}\\begin{landscape}" +++       r ++ "\\end{landscape}")+  where (r, st2)+          = runState+              (wikiImageToLaTeX+                 ((C 'F') :+                    (C 'i') :+                      (C 'l') : (C 'e') : (C ':') : (Map.findWithDefault [] "1" ll)))+              st+templateProcessor st+  ("C++-Programmierung/ Vorlage:Buchinterner Link", ll)+  = (st,+     wikiLinkToLaTeX+       (if+          ("" /=+             (if length (splitOn "/" (currentUrl st)) > 2 then+                (id ((splitOn "/" (currentUrl st)) !! 2)) else []))+          then+          if Map.member "\220berschrift" ll then+            (map (C) "C++-Programmierung/ ") +++              (Map.findWithDefault [] "Abschnitt" ll) +++                [C '/', C ' '] +++                  (Map.findWithDefault [] "Kapitel" ll) +++                    [C '#'] +++                      (Map.findWithDefault [] "\220berschrift" ll) +++                        (if Map.member "Kapitelzusatz" ll then+                           ((C) '_') : (Map.findWithDefault [] "Kapitelzusatz" ll) else [])+            else+            (if Map.member "Kapitel" ll then+               (map (C) "C++-Programmierung/ ") +++                 (Map.findWithDefault [] "Abschnitt" ll) +++                   [C '/', C ' '] ++ (Map.findWithDefault [] "Kapitel" ll)+               else+               (map (C) "C++-Programmierung/ Inhaltsverzeichnis#Anker:") +++                 (Map.findWithDefault [] "Abschnitt" ll))+              +++              [C '|'] +++                (Map.findWithDefault+                   (Map.findWithDefault+                      (Map.findWithDefault (Map.findWithDefault [] "Abschnitt" ll)+                         "Kapitel"+                         ll)+                      "\220berschrift"+                      ll)+                   "Text"+                   ll)+          else+          if Map.member "\220berschrift" ll then+            (map (C) "C++-Programmierung/ ") +++              (Map.findWithDefault [] "Abschnitt" ll) +++                [C '#'] +++                  (Map.findWithDefault [] "\220berschrift" ll) +++                    (if Map.member "Abschnittszusatz" ll then+                       ((C) '_') : (Map.findWithDefault [] "Abschnittszusatz" ll) else [])+            else+            (if Map.member "Kapitel" ll then+               (map (C) "C++-Programmierung/ ") +++                 (Map.findWithDefault [] "Abschnitt" ll) +++                   [C '#'] ++ (Map.findWithDefault [] "Kapitel" ll)+               else+               (map (C) "C++-Programmierung/ ") +++                 (Map.findWithDefault [] "Abschnitt" ll))+              +++              [C '|'] +++                (Map.findWithDefault+                   (Map.findWithDefault+                      (Map.findWithDefault (Map.findWithDefault [] "Abschnitt" ll)+                         "Kapitel"+                         ll)+                      "\220berschrift"+                      ll)+                   "Text"+                   ll))+       st)+templateProcessor st ("B3D:N2P/Do", ll)+  = (st,+     intercalate "+"+       (filter (/= "\\keystroke{}")+          (map+             (\ x ->+                "\\keystroke{" +++                  (key . (map toUpper))+                    (treeToLaTeX (Map.findWithDefault [] (show x) ll) st)+                    ++ "}")+             ([1, 2, 3, 4] :: [Integer]))))+templateProcessor st ("HaskellGHCiExample", ll)+  = (st,+     ("\\LaTeXDoubleBoxTemplate{Example:}{" +++        (treeToLaTeX (Map.findWithDefault [] "1" ll) st) +++          "\\newline " ++ trilexgen st ll "2" ++ "}\n"))+templateProcessor st ("Latex Index", ll)+  = (st,+     ("\\index{" ++ (concatMap go+        (deepFlatten (Map.findWithDefault [] "1" ll))) ++"}"))+ where +   go (C x) = [x]+   go _ = []+templateProcessor st ("HaskellExample", ll)+  = (st,+     ("\\LaTeXDoubleBoxTemplate{Example:}{" +++        (treeToLaTeX (Map.findWithDefault [] "1" ll) st) +++          (treeToLaTeX (Map.findWithDefault [] "2" ll) st) ++ "}\n"))+templateProcessor st ("Ada/95/RM", ll)+  = (st,+     (linkToLaTeX+        ((map C+            "http://www.adaic.org/resources/add_content/standards/95lrm/ARM_HTML/RM-")+           +++           one +++             (if has then [C '-'] else []) +++               two +++                 (map C ".html") +++                   [C ' '] +++                     (if has then one ++ [C '.'] ++ two else+                        (map C "Annex ") ++ one ++ [C ':'])+                       ++ [C ' '] ++ (Map.findWithDefault [] "title" ll))+        st+        ""))+  where one = (Map.findWithDefault [] "1" ll)+        two = (Map.findWithDefault [] "2" ll)+        has = Map.member "2" ll+templateProcessor st ("Ada/2005/RM", ll)+  = (st,+     (linkToLaTeX+        ((map C+            "http://www.adaic.org/resources/add_content/standards/05rm/html/RM-2-")+           +++           one +++             (if has then [C '-'] else []) +++               two +++                 (map C ".html") +++                   [C ' '] +++                     (if has then one ++ [C '.'] ++ two else+                        (map C "Annex ") ++ one ++ [C ':'])+                       ++ [C ' '] ++ (Map.findWithDefault [] "title" ll))+        st+        ""))+  where one = (Map.findWithDefault [] "1" ll)+        two = (Map.findWithDefault [] "2" ll)+        has = Map.member "2" ll+templateProcessor st ("Ada/2012/RM", ll)+  = (st,+     (linkToLaTeX+        ((map C "http://www.ada-auth.org/standards/12rm/html/RM-") +++           one +++             (if has then [C '-'] else []) +++               two +++                 (map C ".html") +++                   [C ' '] +++                     (if has then one ++ [C '.'] ++ two else+                        (map C "Annex ") ++ one ++ [C ':'])+                       ++ [C ' '] ++ (Map.findWithDefault [] "title" ll))+        st+        ""))+  where one = (Map.findWithDefault [] "1" ll)+        two = (Map.findWithDefault [] "2" ll)+        has = Map.member "2" ll+templateProcessor st ("Fortran:Vorlage: Pre1", ll)+  = (st,+     "{\\ttfamily {\\scriptsize " +++       "\\newline{}" +++         s1 +++           "\\newline{}" +++             s2 +++               "\\newline{}" +++                 (treeToLaTeX (Map.findWithDefault [] "1" ll) st) +++                   "\\newline{}" +++                     s2 ++ "\\newline{}" ++ s1 ++ "\\newline{}" ++ "}}\n")+  where s1+          = "0${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}.${\\ttfamily }${}|${\\ttfamily }${}${\\ttfamily }${}1${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}.${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}2${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}.${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}3${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}.${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}4${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}.${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}5${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}.${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}6${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}.${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}7${\\ttfamily }${}|${\\ttfamily }${}${\\ttfamily }${}.${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}${\\ttfamily }${}8"+        s2+          = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"+templateProcessor st ("Fortran:Vorlage: Pre2", ll)+  = (st,+     "{\\bfseries Fortran 90/95-Code (free source form) }\\newline" +++       "{\\ttfamily {\\scriptsize " +++         (treeToLaTeX (Map.findWithDefault [] "1" ll) st) ++ "}}\n")+templateProcessor st ("Fortran:Vorlage: Pre3", ll)+  = (st,+     "{\\bfseries Programmcode} \\newline" +++       "{\\ttfamily {\\scriptsize " +++         (treeToLaTeX (Map.findWithDefault [] "1" ll) st) ++ "}}\n")+templateProcessor st ("Fortran:Vorlage: Pre4", ll)+  = (st,+     "{\\bfseries Fortran 2003-Code} \\newline" +++       "{\\ttfamily {\\scriptsize " +++         (treeToLaTeX (Map.findWithDefault [] "1" ll) st) ++ "}}\n")+templateProcessor st ("Fortran:Vorlage: Intrinsic", ll)+  = (st,+     "\\newline{}\n" +++       (treeToLaTeX (Map.findWithDefault [] "1" ll) st) +++         " = {\\bfseries " +++           (treeToLaTeX (Map.findWithDefault [] "2" ll) st) +++             "} ( " +++               (treeToLaTeX (Map.findWithDefault [] "3" ll) st) +++                 " )\\newline{}\n")+templateProcessor st ("Fortran:Vorlage: IntrinsicS", ll)+  = (st,+     "\\newline{}\n {\\bfseries " +++       (treeToLaTeX (Map.findWithDefault [] "1" ll) st) +++         "} ( " +++           (treeToLaTeX (Map.findWithDefault [] "2" ll) st) +++             " )\\newline{}\n")+templateProcessor st ("Fortran:Vorlage: Isocbinding", ll)+  = (st,+     "Beispiel funktioniert mit Compiler\n" +++       "\\begin{myitemize}\n" +++         "\\item g95 (0.91!) May 10 2007: " +++           (treeToLaTeX (Map.findWithDefault [] "1" ll) st) +++             "\n" +++               "\\item gfortran 4.3.0 20070723 (experimental): " +++                 (treeToLaTeX (Map.findWithDefault [] "2" ll) st) +++                   "\n" +++                     "\\item Intel Fortran Compiler 10.0: " +++                       (treeToLaTeX (Map.findWithDefault [] "3" ll) st) +++                         "\n" +++                           "\\item Sun Studio Express - June 2007: " +++                             (treeToLaTeX (Map.findWithDefault [] "4" ll) st) +++                               "\n" +++                                 "\\end{myitemize}\n" +++                                   "Anmerkungen:\\newline{}\n" +++                                     (treeToLaTeX (Map.findWithDefault [] "5" ll) st) ++ "\n")+templateProcessor st ("C++-Programmierung/ Vorlage:Aufgabe", ll)+  = (st,+     ("{\\bfseries Aufgabe " +++        (treeToLaTeX (Map.findWithDefault [] "Nummer" ll) st) +++          "} \n" +++            (treeToLaTeX (Map.findWithDefault [] "Aufgabe" ll) st) +++              "\n {\\bfseries Musterl\246sung} \n" +++                (treeToLaTeX (Map.findWithDefault [] "L\246sung" ll) st) ++ " \n"))+templateProcessor st ("-", _) = (st, "\\newline{}")+templateProcessor st ("Haskell speaker 2", ll) = (st, param "1")+  where param n = (treeToLaTeX (Map.findWithDefault [] n ll) st)+templateProcessor st ("Vorlage:LaTeX Mehrspaltig Anfang", ll)+  = (st, "\\begin{multicols}{" ++ (param "1") ++ "}")+  where param n = (treeToLaTeX (Map.findWithDefault [] n ll) st)+templateProcessor st ("Vorlage:LaTeX Mehrspaltig Ende", _)+  = (st, "\\end{multicols}")+templateProcessor st ("Vorlage:Referenzbox IntraBuch", ll)+  = (st,+     "{\\bfseries Querverweise:} Siehe auch " +++       (treeToLaTeX (Map.findWithDefault [] "1" ll) st))+templateProcessor st ("unicode", ll)+  = (st, (treeToLaTeX (Map.findWithDefault [] "1" ll) st))+templateProcessor st+  ("Praktikum Anorganische Chemie/ Vorlage:Infobox Nachweisreaktion",+   ll)+  = (st,+     "\\begin{tabular}{|p{0.3\\linewidth}|p{0.7\\linewidth}|}\\hline\n"+       +++       "\\multicolumn{2}{|p{1.0\\linewidth}|}{{\\bfseries Nachweisreaktion}} \\\\ \\hline\n"+         +++         "Reaktionstyp & " +++           (treeToLaTeX (Map.findWithDefault [] "Typ" ll) st) +++             " \\\\ \\hline\n" +++               "pH & " +++                 (treeToLaTeX (Map.findWithDefault [] "pH" ll) st) +++                   "\\\\ \\hline\n" +++                     "Indikation & " +++                       (treeToLaTeX (Map.findWithDefault [] "Indikation" ll) st) +++                         "\\\\ \\hline \n\\end{tabular}\n")+templateProcessor st+  ("Praktikum Anorganische Chemie/ Vorlage:Gift", _)+  = (st, "{\\bfseries Gefahrstoffwarnung! $\\skull$ }")+templateProcessor st ("Wikibooks", ll)+  = (st, wikiLinkToLaTeX ((Map.findWithDefault [] "1" ll)) st)+templateProcessor st ("See also", ll)+  = (st,+     "See also: " +++       (wikiLinkToLaTeX ((Map.findWithDefault [] "1" ll)) st))+templateProcessor st ("info", ll)+  = (st,+     "\\begin{TemplateInfo}{}{}" +++       (treeToLaTeX ((Map.findWithDefault [] "1" ll)) st) +++         "\\end{TemplateInfo}")+templateProcessor st ("Java:statement1", _)+  = (st, "statement{$_{\\textrm{\\scriptsize 1}}$}")+templateProcessor st ("Java:statement2", _)+  = (st, "statement{$_{\\textrm{\\scriptsize 2}}$}")+templateProcessor st ("Java:boolean-condition", _)+  = (st, "boolean-condition")+templateProcessor st ("Java:ch", ll)+  = (st,+     "'" ++ (treeToLaTeX ((Map.findWithDefault [] "1" ll)) st) ++ "'")+templateProcessor st ("Ubung", _) = (st, "\\ubung")+templateProcessor st ("TickYes", _) = (st, "\\TickYes")+templateProcessor st ("Achtung", ll)+  = (st,+     "\\begin{TemplateInfo}{\\danger}{Achtung}" +++       (treeToLaTeX ((Map.findWithDefault [] "1" ll)) st) +++         "\\end{TemplateInfo}")+templateProcessor st ("Warning", ll)+  = (st,+     "\\begin{TemplateInfo}{\\danger}{Warning}" +++       (treeToLaTeX ((Map.findWithDefault [] "1" ll)) st) +++         "\\end{TemplateInfo}")+templateProcessor st ("warning", ll)+  = (st,+     "\\begin{TemplateInfo}{\\danger}{Warning}" +++       (treeToLaTeX ((Map.findWithDefault [] "1" ll)) st) +++         "\\end{TemplateInfo}")+templateProcessor st ("Notiz", ll)+  = (st,+     "\\begin{TemplateInfo}{}{Notiz}" +++       (treeToLaTeX ((Map.findWithDefault [] "1" ll)) st) +++         "\\end{TemplateInfo}")+templateProcessor st ("Vorlage:Zitat3", ll)+  = (st,+     "\\begin{longtable}{|p{\\linewidth}|}\\hline\n \\uline{" +++       (treeToLaTeX ((Map.findWithDefault [] "autor" ll)) st) +++         "}\\\\\\textit{\n" +++           (treeToLaTeX ((Map.findWithDefault [] "zitat" ll)) st) +++             "}\\scriptsize \\\\ \\RaggedLeft \\scriptsize \n" +++               (treeToLaTeX ((Map.findWithDefault [] "quelle" ll)) st) +++                 "\\\\ \\hline \n\\end{longtable}\n")+templateProcessor st ("C++-Programmierung/ Vorlage:Frage", ll)+  = (st,+     if Map.member "Aufgabe" ll then+       ("\\begin{longtable}{|p{\\linewidth}|}\\hline\n {\\bfseries Aufgabe "+          +++          (treeToLaTeX (Map.findWithDefault [] "Nummer" ll) st) +++            "} \\\\ \\hline\n" +++              (treeToLaTeX (Map.findWithDefault [] "Aufgabe" ll) st) +++                "\\\\ \\hline\n {\\bfseries Musterl\246sung} \\\\ \\hline\n" +++                  (treeToLaTeX (Map.findWithDefault [] "L\246sung" ll) st) +++                    "\\\\ \\hline \n\\end{longtable}\n")+       else+       ("\\begin{longtable}{|p{\\linewidth}|}\\hline\n {\\bfseries Frage "+          +++          (treeToLaTeX (Map.findWithDefault [] "Nummer" ll) st) +++            "} \\\\ \\hline\n" +++              (treeToLaTeX (Map.findWithDefault [] "Frage" ll) st) +++                "\\\\ \\hline\n {\\bfseries Antwort} \\\\ \\hline\n" +++                  (treeToLaTeX (Map.findWithDefault [] "Antwort" ll) st) +++                    "\\\\ \\hline \n\\end{longtable}\n"))+templateProcessor st ("merke", ll)+  = (st,+     "\\begin{TemplateInfo}{}{" +++       heading +++         "}" +++           (treeToLaTeX ((Map.findWithDefault [] "1" ll)) st) +++             "\\end{TemplateInfo}")+  where heading+          = if Map.member "info" ll then+              treeToLaTeX (Map.findWithDefault [] "info" ll) st else "Hinweis"+templateProcessor st ("Merke", ll)+  = (st,+     "\\begin{TemplateInfo}{}{" +++       heading +++         "}" +++           (treeToLaTeX ((Map.findWithDefault [] "1" ll)) st) +++             "\\end{TemplateInfo}")+  where heading+          = if Map.member "info" ll then+              treeToLaTeX (Map.findWithDefault [] "info" ll) st else "Hinweis"+templateProcessor st ("Zitat", ll)+  = (st,+     "\\begin{longtable}{|p{\\linewidth}|}\\hline\n" +++       (if Map.member "beschreibung" ll then+          (treeToLaTeX ((Map.findWithDefault [] "beschreibung" ll)) st) +++            "\\\\ \\hline"+          else "")+         +++         " \\uline{" +++           (treeToLaTeX ((Map.findWithDefault [] "autor" ll)) st) +++             "}\\\\\\textit{\n" +++               (treeToLaTeX ((Map.findWithDefault [] "zitat" ll)) st) +++                 "}\\scriptsize \\\\ \\RaggedLeft \\scriptsize \n" +++                   (treeToLaTeX ((Map.findWithDefault [] "quelle" ll)) st) +++                     "\\\\ \\hline \n\\end{longtable}\n")+templateProcessor st ("java web api", ll)+  = (st,+     "\\myhref{http://java.sun.com/javase/6/docs/api/" +++       loc ++ "}{" ++ cap ++ "}")+  where  +        loc :: String+        loc = (shallowFlatten (Map.findWithDefault [] "1" ll))+         +        cap :: String+        cap+          = "Java API: " ++ (treeToLaTeX (Map.findWithDefault [] "2" ll) st)+templateProcessor st+  ("Python_unter_Linux: Vorlagen:VorlageAusgabe", ll)+  = (st,+     ("\n{\\bfseries Ausgabe}\\\\\n{\\ttfamily \\scriptsize \n" +++        ("user\\@localhost:\\~\\$" +++           (treeToLaTeX+              (breakLines3 linewidth (Map.findWithDefault [] "1" ll))+              st)+             +++             "\\newline " +++               (treeToLaTeX+                  (id+                     (filter+                        (\ x ->+                           case x of+                               C '\n' -> False+                               (Environment Tag (TagAttr "br" _) _) -> True+                               _ -> True)+                        (Map.findWithDefault [] "2" ll)))+                  st))+          ++ "}\n"))+templateProcessor st ("Python_unter_Linux: Vorlagen:VorlageQZ", ll)+  = (st,+     ("{\\ttfamily \\uline{" +++        (treeToLaTeX (breakLines3 100 (Map.findWithDefault [] "1" ll)) st)+          ++ "}}"))+templateProcessor st+  ("Python_unter_Linux:  Vorlagen:VorlageQZ", ll)+  = (st,+     ("{\\ttfamily \\uline{" +++        (treeToLaTeX (breakLines3 100 (Map.findWithDefault [] "1" ll)) st)+          ++ "}}"))+templateProcessor st ("Python unter Linux: Vorlagen:VorlageQZ", ll)+  = (st,+     ("{\\ttfamily \\uline{" +++        (treeToLaTeX (breakLines3 100 (Map.findWithDefault [] "1" ll)) st)+          ++ "}}"))+templateProcessor st ("C++-Programmierung/ Vorlage:Syntax", ll)+  = (st,+     "{\\ttfamily {\\scriptsize " +++       (treeToLaTeX (breakLines3 96 (Map.findWithDefault [] "code" ll))+          st)+         ++ "}}\n")+templateProcessor st+  ("C++-Programmierung/ Vorlage:Kapitelanhang", ll)+  = (st,+     ((if Map.member "Zusammenfassung" ll then+         "\n {\\bfseries \\large Zusammenfassung} \n " +++           (treeToLaTeX (Map.findWithDefault [] "Zusammenfassung" ll) st)+         else "")+        +++        (if Map.member "Fragen" ll then+           "\n  {\\bfseries \\large Fragen} \n " +++             (treeToLaTeX (Map.findWithDefault [] "Fragen" ll) st)+           else "")+          +++          (if Map.member "Aufgaben" ll then+             "\n  {\\bfseries \\large Aufgaben} \n " +++               (treeToLaTeX (Map.findWithDefault [] "Aufgaben" ll) st)+             else "")+            ++ " \n"))+templateProcessor st ("C++-Programmierung/ Vorlage:Code", ll)+  = (st,+     ("{\\ttfamily {\\scriptsize" +++        ((formatLaTeXBlock defaultFormatOpts)+           (highlightAs "c++"+              (shallowFlatten+                 (map renormalize+                    (breakLines3 96 (Map.findWithDefault [] "code" ll))))))+          +++          "}}\n" +++            (if (Map.member "output" ll) then+               "{\\bfseries Ausgabe}\n{\\ttfamily {\\scriptsize" +++                 (treeToLaTeX (breakLines3 96 (Map.findWithDefault [] "output" ll))+                    st)+                   ++ "}}"+               else "")))+templateProcessor st ("cite web", ll) = (st, mainer)+  where mainer+          = "\\myhref{" +++              url +++                "}{" +++                  title ++ "}. " ++ publisher ++ ". Retrieved " ++ accessdate ++ " "+        url = shallowFlatten (Map.findWithDefault [] "url" ll)+        publisher = treeToLaTeX (Map.findWithDefault [] "publisher" ll) st+        title = treeToLaTeX (Map.findWithDefault [] "title" ll) st+        accessdate+          = treeToLaTeX (Map.findWithDefault [] "accessdate" ll) st+templateProcessor st ("code", ll) = (st, mainer)+  where  +        mainer :: String+        mainer+          = "\\TemplateCode{" +++              header +++                "}{" ++ "}{" ++ "}{" ++ "}{" ++ lang ++ "}{" ++ code ++ "}{}{}{}"+         +        header :: String+        header+          = if Map.member "header" ll then+              (treeToLaTeX (Map.findWithDefault [] "header" ll)+                 st{getInCode = True})+              else ""+         +        lang :: String+        lang+          = if Map.member "lang" ll then+              (treeToLaTeX (Map.findWithDefault [] "lang" ll)+                 st{getInCode = True})+                ++ " Source"+              else ""+         +        code :: String+        code = trilexgen st{getInCode = True} ll "source"+templateProcessor st ("Java_Code_File", ll) = (st, mainer)+  where  +        mainer :: String+        mainer+          = "\\TemplateCode{" +++              header +++                "}{" ++ "}{" ++ "}{" ++ "}{" ++ lang ++ "}{" ++ code ++ "}{}{}{}"+         +        header :: String+        header+          = if Map.member "header" ll then+              (treeToLaTeX (Map.findWithDefault [] "header" ll)+                 st{getInCode = True})+              else ""+         +        lang :: String+        lang = if Map.member "lang" ll then "Java Source" else ""+         +        code :: String+        code = trilexgen st{getInCode = True} ll "source"+templateProcessor st ("Syntax", ll) = (st, mainer)+  where  +        mainer :: String+        mainer+          = "\\begin{TemplateCodeInside}{}{\\baselineskip}{\\baselineskip}{}{}{}\n"+              ++ code ++ "\n\\end{TemplateCodeInside}\n"+         +        code :: String+        code = trilex st{getInCode = True} ll+templateProcessor st ("HaskellGHCi", ll) = (st, mainer)+  where  +        mainer :: String+        mainer+          = "\\begin{TemplateCodeInside}{}{\\baselineskip}{\\baselineskip}{}{}{}\n"+              ++ code ++ "\n\\end{TemplateCodeInside}\n"+         +        code :: String+        code = trilexgen st{getInCode = True} ll "1"+templateProcessor st ("Java://", ll) = (st, mainer)+  where  +        mainer :: String+        mainer+          = "\\begin{TemplateCodeInside}{}{\\baselineskip}{\\baselineskip}{}{}{}\n"+              ++ code ++ "\n\\end{TemplateCodeInside}\n"+         +        code :: String+        code = trilexgen st{getInCode = True} ll "1"+templateProcessor st ("LaTeX/Usage", ll)+  = (st2,+     if (getInTab st > 0) then "\\TemplateSource{" ++ (rtrim x) ++ "}\n"+       else g)+  where f = shallowFlatten+              (map renormalize+                 (breakLines3 linewidth (Map.findWithDefault [] "code" ll)))+        g = (formatLaTeXBlock defaultFormatOpts) (highlightAs "Latex" f)+        (x, st2)+          = runState (treeToLaTeX2 (breakLines3 linewidth (map C f))) st+templateProcessor st ("LaTeX/Example", ll)+  = (st2,+     "\\begin{longtable}{p{1.0\\linewidth}}\n" +++       g ++ "\\\\\n" ++ x ++ "\n\\end{longtable}")+  where f = shallowFlatten+              (map renormalize+                 (breakLines3 linewidth (Map.findWithDefault [] "code" ll)))+        g = (formatLaTeXBlock defaultFormatOpts) (highlightAs "Latex" f)+        (x, st2)+          = runState (treeToLaTeX2 (Map.findWithDefault [] "render" ll)) st+templateProcessor st ("java://", ll) = (st, mainer)+  where  +        mainer :: String+        mainer+          = "\\begin{TemplateCodeInside}{}{\\baselineskip}{\\baselineskip}{}{}{}\n"+              ++ code ++ "\n\\end{TemplateCodeInside}\n"+         +        code :: String+        code = trilexgen st{getInCode = True} ll "1"+templateProcessor st ("java", ll) = (st, mainer)+  where  +        mainer :: String+        mainer+          = "\\begin{TemplateCodeInside}{}{\\baselineskip}{\\baselineskip}{}{}{}\n"+              ++ code ++ "\n\\end{TemplateCodeInside}\n"+         +        code :: String+        code = trilex st{getInCode = True} ll+templateProcessor st ("DOI", ll)+  = (st,+     "DOI:\\myhref{http://dx.doi.org/" ++ tl ++ "}{" ++ tx ++ "}")+  where tx = (treeToLaTeX (Map.findWithDefault [] "1" ll) st)+        tl = (shallowFlatten (Map.findWithDefault [] "1" ll))+templateProcessor st ("ISSN", ll)+  = (st,+     "\\myhref{http://dispatch.opac.d-nb.de/DB=1.1/CMD?ACT=SRCHA&IKT=8&TRM="+       ++ tl ++ "}{ISSN: " ++ tl ++ "}")+  where tl = (shallowFlatten (Map.findWithDefault [] "1" ll))+templateProcessor st ("cpp", ll)+  = (st,+     ("{\\ttfamily " +++        (treeToLaTeX (breakLines3 96 (Map.findWithDefault [] "1" ll)) st)+          ++ "}"))+templateProcessor st ("Schach: Vorlage:Schachbrett", _)+  = (st{getC = ((getC st) + 1)},+     "\n\n\\parbox[t]{" +++       mysize +++         "\\linewidth}{\n\\begin{center}\n" +++           "\\includegraphics[width=" +++             mysize +++               "\\linewidth,height=6.5in,keepaspectratio]{../images/chess" +++                 n +++                   ".pdf}\\end{center}\n" +++                     "Stellung " ++ n ++ "}\\vspace{0.75cm}\n\n")+  where mysize = printf "%0.5f" (getF st)+        n = show (getC st)+templateProcessor st ("Farblegende", ll)+  = (st,+     if p then "\\legendColorBox" ++ col ++ "{" ++ param2 ++ "}\n" else+       "\\legendNamedColorBox{" ++ colname ++ "}{" ++ param2 ++ "}\n")+  where (p, colname, col)+          = colinfo (treeToLaTeX (Map.findWithDefault [] "1" ll) st)+        param2 = (treeToLaTeX (Map.findWithDefault [] "2" ll) st)+templateProcessor st ("Farbe", ll) = (st, defineall ++ inside)+  where (pred1, colname1, col1) = colinfo (param "1")+        (pred2, colname2, col2) = colinfo (param "2")+        param n = (treeToLaTeX (Map.findWithDefault [] n ll) st)+        trans = ((param "2") == "transparent")+        define p colname col+          = (if p then "\\definecolor{" ++ colname ++ "}{rgb}" ++ col else+               "")+        defineall+          = (define pred1 colname1 col1) ++ (define pred2 colname2 col2)+        inside+          = if trans then+              "\\textcolor{" ++ colname1 ++ "}{" ++ (param "3") ++ "}" else+              "\\fcolorbox{" +++                colname2 +++                  "}{" +++                    colname2 +++                      "}{\\textcolor{" ++ colname1 ++ "}{" ++ (param "3") ++ "}}"+templateProcessor st ("cite paper", ll)+  = (st,+     (if Map.member "editor" ll then+        (treeToLaTeX (Map.findWithDefault [] "editor" ll) st) else+        (treeToLaTeX (Map.findWithDefault [] "author" ll) st))+       +++       (if Map.member "coauthor" ll then+          "; " ++ (treeToLaTeX (Map.findWithDefault [] "coauthor" ll) st)+          else "")+         +++         " " +++           (treeToLaTeX (Map.findWithDefault [] "date" ll) st) +++             ". " +++               (treeToLaTeX (Map.findWithDefault [] "title" ll) st) +++                 "- " +++                   (treeToLaTeX (Map.findWithDefault [] "publisher" ll) st) +++                     ". pp.  " +++                       (treeToLaTeX (Map.findWithDefault [] "pages" ll) st) ++ "\n")+templateProcessor st ("Cite book", ll)+  = (st,+     (if Map.member "editor" ll then+        (treeToLaTeX (Map.findWithDefault [] "editor" ll) st) else+        (treeToLaTeX (Map.findWithDefault [] "author" ll) st))+       +++       " " +++         (treeToLaTeX (Map.findWithDefault [] "title" ll) st) +++           ". " +++             (treeToLaTeX (Map.findWithDefault [] "publisher" ll) st) +++               ", " +++                 (treeToLaTeX (Map.findWithDefault [] "address" ll) st) +++                   ", " +++                     (treeToLaTeX (Map.findWithDefault [] "year" ll) st) ++ "\n")+templateProcessor st ("cite book", ll)+  = (st,+     (if Map.member "editor" ll then+        (treeToLaTeX (Map.findWithDefault [] "editor" ll) st) else+        (treeToLaTeX (Map.findWithDefault [] "author" ll) st))+       +++       " " +++         (treeToLaTeX (Map.findWithDefault [] "title" ll) st) +++           ". " +++             (treeToLaTeX (Map.findWithDefault [] "publisher" ll) st) +++               ", " +++                 (treeToLaTeX (Map.findWithDefault [] "address" ll) st) +++                   ", " +++                     (treeToLaTeX (Map.findWithDefault [] "year" ll) st) ++ "\n")+templateProcessor st ("Cite article", ll)+  = (tempProcAdapter $ citearticle ll) st+templateProcessor st ("cite journal", ll)+  = (tempProcAdapter $ citearticle ll) st+templateProcessor st ("citation", ll)+  = (tempProcAdapter $ citearticle ll) st+templateProcessor st ("cite newsgroup", ll)+  = (tempProcAdapter $ citearticle ll) st+templateProcessor st ("Ada/95/cite AI", ll)+  = (tempProcAdapter $ citearticle ll) st+templateProcessor st ("Ada/Cite cla", ll)+  = (tempProcAdapter $ citearticle ll) st+templateProcessor st ("cite", ll)+  = (tempProcAdapter $ citearticle ll) st+templateProcessor st ("Druckversionsnotiz", _) = (st, "")+templateProcessor st ("Wikipedia", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'w') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("Wikipedia2", ll)+  = (st,+     (wikiLinkToLaTeX+       ((C 'w') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+      +++     (wikiLinkToLaTeX+       ((C 'w') : (C ':') : (Map.findWithDefault [] "2" ll))+       st)+     )+templateProcessor st ("GLSL Programming Unity SectionRef", ll)+  = (st,+     wikiLinkToLaTeX ((map (C) xx) ++ (Map.findWithDefault [] "1" ll))+       st)+  where xx+          = if+              shallowFlatten (Map.findWithDefault [] "1" ll) `elem`+                ["OpenGL ES 2.0 Pipeline", "Vertex Transformations",+                 "Vector and Matrix Operations", "Applying Matrix Transformations",+                 "Rasterization", "Per-Fragment Operations"]+              then "GLSL Programming/" else "GLSL Programming/Unity/"+templateProcessor st ("S", ll)+  = (st,+     wikiLinkToLaTeX+       (((C 's') : (C ':') : (Map.findWithDefault [] "1" ll)) +++          [C '|'] ++ (Map.findWithDefault [] "2" ll))+       st)+templateProcessor st ("wikipedia", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'w') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("Wikiversity", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'v') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("wikiquote", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'q') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("W", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'w') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("wp", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'w') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("B", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'b') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("Wikipedia-inline", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'w') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("B3D:N2P/VTT1", ll) = (st2, r)+  where (r, st2)+          = runState+              (wikiImageToLaTeX+                 ((C 'F') :+                    (C 'i') :+                      (C 'l') :+                        (C 'e') :+                          (C ':') :+                            (Map.findWithDefault [] "image" ll) +++                              [C '|'] +++                                (Map.findWithDefault [] "imageWidth" ll) +++                                  [C '|'] ++ (Map.findWithDefault [] "text3" ll)))+              st+templateProcessor st ("Template:B3D:N2P/VTT1", ll) = (st2, r)+  where (r, st2)+          = runState+              (wikiImageToLaTeX+                 ((C 'F') :+                    (C 'i') :+                      (C 'l') :+                        (C 'e') :+                          (C ':') :+                            (Map.findWithDefault [] "image" ll) +++                              [C '|'] +++                                (Map.findWithDefault [] "imageWidth" ll) +++                                  [C '|'] ++ (Map.findWithDefault [] "text3" ll)))+              st+templateProcessor st ("Vorlage:Referenzen Zitat", ll) = (st, r)+  where r = (wikiLinkToLaTeX+               ((Map.findWithDefault [] "1" ll) +++                  [C '|', C '['] ++ (Map.findWithDefault [] "2" ll) ++ [C ']'])+               st)+templateProcessor st ("Referenzen Zitat", ll) = (st, r)+  where r = (wikiLinkToLaTeX+               ((Map.findWithDefault [] "1" ll) +++                  [C '|', C '['] ++ (Map.findWithDefault [] "2" ll) ++ [C ']'])+               st)+templateProcessor st ("wikipediapar", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'w') :+          (C ':') :+            (Map.findWithDefault [] (if Map.member "2" ll then "2" else "1")+               ll))+       st)+templateProcessor st ("Wikipediapar", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'w') :+          (C ':') :+            (Map.findWithDefault [] (if Map.member "2" ll then "2" else "1")+               ll))+       st)+templateProcessor st ("Druckversion Titeleintrag", ll)+  = (st,+     "\\pagebreak{}\\begin{longtable}{|p{0.3\\linewidth}|p{0.7\\linewidth}|}\\hline\n"+       +++       "\\multicolumn{2}{|p{1.0\\linewidth}|}{\\bfseries Standardtiteleintrag}"+         +++         (if (Map.member "URL" ll) then+            "\\\\ \\hline\n \\fetchurlcaption & \\url{" +++              (treeToLaTeX (Map.findWithDefault [] "URL" ll) st) ++ "}"+            else "")+           +++           (if (Map.member "Buch" ll) then+              "\\\\ \\hline\n \\bookcaption & \\url{http://de.wikibooks.org/wiki/"+                +++                replace2 (treeToLaTeX (Map.findWithDefault [] "Buch" ll) st) " "+                  "_"+                  ++ "}"+              else "")+             +++             (if (Map.member "Sachgruppen" ll) then+                "\\\\ \\hline\n \\functionalgroupcaption & " +++                  (treeToLaTeX (Map.findWithDefault [] "Sachgruppen" ll) st)+                else "")+               +++               (if (Map.member "WeitereThemen" ll) then+                  "\\\\ \\hline\n \\futhertopicscaption & " +++                    (treeToLaTeX (Map.findWithDefault [] "WeitereThemen" ll) st)+                  else "")+                 +++                 (if (Map.member "Hauptautoren" ll) then+                    "\\\\ \\hline\n \\mainauthorscaption  & " +++                      (treeToLaTeX (Map.findWithDefault [] "Hauptautoren" ll) st)+                    else "")+                   +++                   (if (Map.member "Betreuer" ll) then+                      "\\\\ \\hline\n \\projecttexniciancaption & " +++                        (treeToLaTeX (Map.findWithDefault [] "Betreuer" ll) st)+                      else "")+                     +++                     "\\\\ \\hline\n \\organizationscaptions & Wikibooks" +++                       (if (Map.member "Erscheinungsdatum" ll) then+                          "\\\\ \\hline\n \\datecaption & " +++                            (treeToLaTeX (Map.findWithDefault [] "Erscheinungsdatum" ll) st)+                          else "")+                         +++                         (if (Map.member "Standardnummer" ll) then+                            "\\\\ \\hline\n \\standardcodecaption & " +++                              (treeToLaTeX (Map.findWithDefault [] "Standardnummer" ll) st)+                            else "")+                           +++                           (if (Map.member "Buch" ll) then+                              "\\\\ \\hline\n \\maintitlecaption & " +++                                (treeToLaTeX (Map.findWithDefault [] "Buch" ll) st)+                              else "")+                             +++                             (if (Map.member "Verleger" ll) then+                                "\\\\ \\hline\n \\publishercaption & " +++                                  (treeToLaTeX (Map.findWithDefault [] "Verleger" ll) st)+                                else "")+                               +++                               (if (Map.member "Verlagsort" ll) then+                                  "\\\\ \\hline\n \\publishercitycaption & " +++                                    (treeToLaTeX (Map.findWithDefault [] "Verlagsort" ll) st)+                                  else "")+                                 +++                                 (if (Map.member "Regal" ll) then+                                    "\\\\ \\hline\n \\shelfcaption & " +++                                      (treeToLaTeX (Map.findWithDefault [] "Regal" ll) st)+                                    else "")+                                   +++                                   (if (Map.member "Umfang" ll) then+                                      "\\\\ \\hline\n \\sizecaption & " +++                                        (treeToLaTeX (Map.findWithDefault [] "Umfang" ll) st)+                                      else "")+                                     ++ "\\\\ \\hline \n\\end{longtable}\n")+templateProcessor st ("Druckversion Titelseite", ll)+  = (st{getTitle = s}, s)+  where s = (if (Map.member "Haupttitel" ll) then+               "\\mymaintitle{" +++                 (treeToLaTeX (Map.findWithDefault [] "Haupttitel" ll)+                    st{getInCenter = True})+                   ++ "}"+               else "")+              +++              (if (Map.member "Untertitel" ll) then+                 "\\mysubtitle{" +++                   (treeToLaTeX (Map.findWithDefault [] "Untertitel" ll)+                      st{getInCenter = True})+                     ++ "}"+                 else "")+                +++                (if (Map.member "Autor" ll) then+                   "\\myauthor{" +++                     (treeToLaTeX (Map.findWithDefault [] "Autor" ll)+                        st{getInCenter = True})+                       ++ "}"+                   else "")+templateProcessor st ('j' : ('a' : ('v' : ('a' : (':' : xs)))), ll)+  = (tempProcAdapter $ javakeyword xs ll "java:") st+templateProcessor st ('J' : ('a' : ('v' : ('a' : (':' : xs)))), ll)+  = (tempProcAdapter $ javakeyword xs ll "Java:") st+templateProcessor st ("Haskell lib", ll)+  = (st, linkToLaTeX link st "")+  where  +        param :: String -> Maybe [Anything Char]+        param name = Map.lookup name ll+        package+          = fromMaybe (map (C) "base") $ param "p" `mplus` param "package"+        version+          = fromMaybe (map (C) "4.1.0.0") $ param "v" `mplus` param "version"+         +        unnamed :: Integer -> [Anything Char]+        unnamed i = fromMaybe [] $ param (show i)+        unnPars = takeWhile (not . null) $ map unnamed [1 ..]+        location+          = (map (C) "http://hackage.haskell.org/packages/archive/") +++              package +++                [C '/'] +++                  version +++                    (map (C) "/doc/html/") +++                      (intercalate [C '-'] unnPars) ++ (map (C) ".html")+        caption = intercalate [C '.'] unnPars+        link = location ++ [C ' '] ++ caption+templateProcessor st ("V", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'v') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("wikisource", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 's') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("M", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'm') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("C", ll)+  = (st,+     "\\myhref{http://commons.wikimedia.org/wiki/" +++       loc ++ "}{" ++ cap ++ "}")+  where loc = (shallowFlatten (Map.findWithDefault [] "1" ll))+         +        cap :: String+        cap+          = if (Map.member "2" ll) then+              (treeToLaTeX (Map.findWithDefault [] "2" ll) st) else+              (treeToLaTeX (Map.findWithDefault [] "1" ll) st)+templateProcessor st ("commons", ll)+  = (st,+     "\\myhref{http://commons.wikimedia.org/wiki/" +++       loc ++ "}{" ++ cap ++ "}")+  where loc = (shallowFlatten (Map.findWithDefault [] "1" ll))+         +        cap :: String+        cap+          = if (Map.member "2" ll) then+              (treeToLaTeX (Map.findWithDefault [] "2" ll) st) else+              (treeToLaTeX (Map.findWithDefault [] "1" ll) st)+templateProcessor st ("Commonscat", ll)+  = (st,+     "\\myhref{http://commons.wikimedia.org/wiki/Category:" +++       loc ++ "}{" ++ cap ++ "}")+  where loc = (shallowFlatten (Map.findWithDefault [] "1" ll))+         +        cap :: String+        cap+          = if (Map.member "2" ll) then+              (treeToLaTeX (Map.findWithDefault [] "2" ll) st) else+              (treeToLaTeX (Map.findWithDefault [] "1" ll) st)+templateProcessor st ("Commons", ll)+  = (st,+     "\\myhref{http://commons.wikimedia.org/wiki/" +++       loc ++ "}{" ++ cap ++ "}")+  where loc = (shallowFlatten (Map.findWithDefault [] "1" ll))+         +        cap :: String+        cap+          = if (Map.member "2" ll) then+              (treeToLaTeX (Map.findWithDefault [] "2" ll) st) else+              (treeToLaTeX (Map.findWithDefault [] "1" ll) st)+templateProcessor st ("b", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'b') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("Wikiquote", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 'q') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("Wikisource", ll)+  = (st,+     wikiLinkToLaTeX+       ((C 's') : (C ':') : (Map.findWithDefault [] "1" ll))+       st)+templateProcessor st ("Reaktion", ll)+  = (st, edukte ++ " $\\rightarrow$ " ++ produkte)+  where  +        reput :: [String] -> [[Anything Char]] -> [[Anything Char]]+        reput (k : ks) out+          = if Map.member k ll then+              reput ks ((Map.findWithDefault [] k ll) : out) else reput ks out+        reput [] out = out+         +        myjoin :: [[Anything Char]] -> String -> String+        myjoin (x : xs) acu+          = if xs == [] then+              (if acu == "" then (treeToLaTeX x st) else+                 acu ++ "+" ++ (treeToLaTeX x st))+              else+              (if acu == "" then myjoin xs (treeToLaTeX x st) else+                 myjoin xs acu ++ "+" ++ (treeToLaTeX x st))+        myjoin [] acu = acu+        edukte+          = myjoin (reput ["Edukt", "Edukt1", "Edukt2", "Edukt3"] []) ""+        produkte+          = myjoin (reput ["Produkt", "Produkt1", "Produkt2", "Produkt3"] [])+              ""+templateProcessor st ("Visual Basic .NET: Vorlage:Code", ll)+  = templateProcessor st ("C++-Programmierung/ Vorlage:Code", ll)+templateProcessor st ("Regal:Programmierung: Vorlage:Code", ll)+  = (st, mainer)+  where  +        mainer :: String+        mainer+          = "\\TemplateCode{" +++              header +++                "}{" +++                  footer +++                    "}{" +++                      marker +++                        "}{}{" ++ output ++ "}{" ++ lang ++ "}{" ++ code ++ "}{}{}{}"+         +        marker :: String+        marker+          = if Map.member "error" ll then "e" else+              if Map.member "valid" ll then "valid" else ""+         +        header :: String+        header+          = if Map.member "kopf" ll then+              (treeToLaTeX (Map.findWithDefault [] "kopf" ll)+                 st{getInCode = True})+              else ""+         +        lang :: String+        lang+          = if Map.member "lang" ll then+              (treeToLaTeX (Map.findWithDefault [] "lang" ll)+                 st{getInCode = True})+                ++ " Quelltext"+              else ""+         +        code :: String+        code = trilex st{getInCode = True} ll+         +        output :: String+        output+          = if Map.member "output" ll then+              (treeToLaTeX (killnbsp (Map.findWithDefault [] "output" ll))+                 st{getInCode = True})+              else ""+         +        footer :: String+        footer+          = if Map.member "fuss" ll then+              (treeToLaTeX (Map.findWithDefault [] "fuss" ll)+                 st{getInCode = True})+              else ""+        killnbsp ((Environment HtmlChar (Str "nbsp") _) : xs) = xs+        killnbsp x = x+templateProcessor st (x, ll)+  = (tempProcAdapter $ unknownTemplate x ll) st+ +{-DHUN| This function is currently nearly unused, it is essentially the same as templateProcessor. But with this way of writing it down you can find out for which templates handler functions are registered. DHUN-}+ +templateRegistry ::+                 [(String, Map String [Anything Char] -> Renderer String)]+templateRegistry+  = [("Regal:Programmierung: Vorlage:Code",+      \ ll ->+        let  +            marker :: String+            marker+              = if Map.member "error" ll then "e" else+                  if Map.member "valid" ll then "valid" else ""+            killnbsp ((Environment HtmlChar (Str "nbsp") _) : xs) = xs+            killnbsp x = x+            withdef x f+              = if Map.member x ll then+                  (treeToLaTeX2 (f (Map.findWithDefault [] x ll))) else return ""+          in+          do st <- get+             put $ st{getInCode = True}+             code <- trilex2 ll+             footer <- withdef "fuss" id+             header <- withdef "kopf" id+             lang <- do x <- (withdef "lang" id)+                        return $ if x == "" then "" else x ++ " Quelltext"+             output <- withdef "output" killnbsp+             st2 <- get+             put $ st2{getInCode = False}+             return $+               "\\TemplateCode{" +++                 header +++                   "}{" +++                     footer +++                       "}{" +++                         marker +++                           "}{" ++ output ++ "}{" ++ lang ++ "}{" ++ code ++ "}{}{}{}")]+ +{-DHUN| processing of Java keywords for the English wikibook on Java, each Java keyword got its own template there DHUN-}+ +javakeyword ::+            [Char] -> Map String [Anything Char] -> [Char] -> Renderer String+javakeyword xs ll j+  = if (xs `elem` keywords) then+      state $ \ st -> ("{\\bfseries " ++ xs ++ "}", st) else+      unknownTemplate (j ++ xs) ll+  where keywords+          = (["private", "int", "return", "void", "new", "class",+              "interface", "String", "null", "Object", "byte", "char", "short",+              "long", "double", "boolean", "if", "true", "static", "public",+              "protected", "extends", "throw", "catch", "throws", "try",+              "abstract", "false", "else", "switch", "continue", "import",+              "final", "break", "implements", "finally", "while", "string",+              "float", "do", "for", "case", "default", "package", "this"])+ +{-DHUN| Handler for the unknown template. That is the ones that no handler was registered for DHUN-}+ +unknownTemplate ::+                String -> Map String [Anything Char] -> Renderer String+unknownTemplate xx ll2+  = do st <- get+       let x = trim xx+           ll = Map.fromList (trimall (Map.toList ll2))+           trimall ((a, b) : xs) = ((trim a), b) : (trimall xs)+           trimall [] = []+           tm = (templateMap st)+           step_ttl y = treeToLaTeX2 (Map.findWithDefault [] y ll)+           maybe_known_sf+             = do lis <- Map.lookup x tm+                  guard (not $ null lis)+                  let (latexname : transparams) = lis+                  guard (latexname /= "")+                  return $+                    do out <- mapM step_ttl transparams+                       return $+                         "\\" +++                           latexname ++ "{" ++ (intercalate "}{" (map trim out)) ++ "}"+           unknown_sf+             = do uparams <- mapM step_ttl $ Map.keys ll+                  return $+                    "\n\nUNKNOWN TEMPLATE  \n" +++                      (drop 1 . nullinit $ show x) +++                        "\n\n" ++ "{" ++ (intercalate "}{" uparams) ++ "}" ++ "\n\n"+         in fromMaybe unknown_sf maybe_known_sf+ +{-DHUN| helper function to generate image numbers for image in image galleries (gallery tag in mediawiki) the fist input parameter is the start number, the second the end number. A list of all numbers between start and end is returned DHUN-}+ +generateGINsHelper :: Int -> Int -> [Int]+generateGINsHelper b e+  = if b == e then [] else b : (generateGINsHelper (b + 1) e)+ +{-DHUN| function to generate image numbers for image in image galleries (gallery tag in mediawiki). The renderer start before the start of the gallery is given as first parameter. The state of the renderer after the end of the gallery is given as second parameter. A list containing the numbers of the images in the gallery is returned DHUN-}+ +generateGalleryImageNumbers :: MyState -> MyState -> [Int]+generateGalleryImageNumbers oldst newst+  = generateGINsHelper (getJ oldst) (getJ newst)+ +{-DHUN| strips center tags of the parse tree keeping the data inside the center tags in the parse tree, so just flattens out the center tags DHUN-}+ +uncenter :: [Anything t] -> [Anything t]+uncenter ((Environment Tag (TagAttr "center" _) l) : xs)+  = l ++ (uncenter xs)+uncenter ((Environment e s l) : xs)+  = (Environment e s (uncenter l)) : (uncenter xs)+uncenter (x : xs) = x : (uncenter xs)+uncenter [] = []+ +{-DHUN| converts a parse tree to latex. Takes the parse tree as first parameter. Takes the current state of the renderer as second input parameter. Returns the latex representation of the tree as return value. This function should only be used internally in latex renderer since it does not generate the table of names references for the ref tags. DHUN-}+ +treeToLaTeX :: [Anything Char] -> MyState -> String+treeToLaTeX l states = fst $ runState (treeToLaTeX2 l) states+ +{-DHUN| converts a parse tree to latex. Takes the parse tree as first parameter. Takes the current state of the renderer as second input parameter. Returns a tuple. the first element is the latex representation of the tree. The second is the new state of the renders. Does one run before the actual run, in order to generate a table of names references for the ref tags in mediawiki. This function should be called by the main program after the parser. DHUN-}+ +treeToLaTeX3 :: [Anything Char] -> MyState -> (String, MyState)+treeToLaTeX3 l st = runState ttl2twice st+  where ttl2twice+          = do _ <- treeToLaTeX2 l+               b <- get+               put st{fndict = fndict b}+               treeToLaTeX2 l+ +{-DHUN| converts a parse tree to latex. Takes the parse tree as first parameter. Takes the current state of the renderer as second input parameter. Returns the latex representation of the tree as Renderer String. So it actually takes the current state of the renderer as additional monadic input parameter and returns a possible modified version of it as additional monadic return parameter. This function should only be used internally in latex renderer since it does not generate the table of names references for the ref tags. DHUN-}+ +treeToLaTeX2 :: [Anything Char] -> Renderer String+treeToLaTeX2 ll+  = do x <- allinfo+       return $ concat x+  where  +        allinfo :: Renderer [String]+        allinfo = mapM nodeToLaTeX (removeBr ll)+         +        walk :: String -> [Anything Char] -> String -> Renderer String+        walk prefix l postfix+          = do d <- treeToLaTeX2 l+               return $ prefix ++ d ++ postfix+         +        walktrim :: String -> [Anything Char] -> String -> Renderer String+        walktrim prefix l postfix+          = do st <- get+               put $ st{getInHeading = True}+               d <- treeToLaTeX2 l+               st2 <- get+               put $ st2{getInHeading = getInHeading st}+               return $ prefix ++ (trim d) ++ postfix+         +        walkbf :: [Anything Char] -> Renderer String+        walkbf l+          = do st <- get+               put $+                 st{fontStack =+                      ((fromMaybe+                          FontStyle{stylebase = Normal, bold = True, italic = False}+                          (maybeHead (fontStack st))){bold = True}+                         : (fontStack st))}+               d <- treeToLaTeX2 l+               st2 <- get+               put $ st2{fontStack = drop 1 (fontStack st2)}+               return $ "{\\bfseries " ++ (trim d) ++ "}"+         +        walkit :: [Anything Char] -> Renderer String+        walkit l+          = do st <- get+               put $+                 st{fontStack =+                      ((fromMaybe+                          FontStyle{stylebase = Normal, bold = False, italic = True}+                          (maybeHead (fontStack st))){italic = True}+                         : (fontStack st))}+               d <- treeToLaTeX2 l+               st2 <- get+               put $ st2{fontStack = drop 1 (fontStack st2)}+               return $ "{\\itshape " ++ (trim d) ++ "}"+         +        walktt :: [Anything Char] -> Renderer String+        walktt l+          = do st <- get+               put $+                 st{fontStack =+                      ((fromMaybe+                          FontStyle{stylebase = Mono, bold = False, italic = False}+                          (maybeHead (fontStack st))){stylebase = Mono}+                         : (fontStack st))}+               d <- treeToLaTeX2 l+               st2 <- get+               put $ st2{fontStack = drop 1 (fontStack st2)}+               return $ "{\\ttfamily " ++ (trim d) ++ "}"+         +        walkfn :: String -> [Anything Char] -> String -> Renderer String+        walkfn prefix l postfix+          = do st <- get+               put $ st{getInFootnote = True}+               d <- treeToLaTeX2 l+               st2 <- get+               put $ st2{getInFootnote = (getInFootnote st)}+               return $ prefix ++ d ++ postfix+         +        nodeToLaTeX :: Anything Char -> Renderer String+        nodeToLaTeX (C c)+          = do st <- get+               case (fontStack st) of+                   (x : _) -> if (getFont x c) == (font st) then return (chartrans c)+                                else+                                do put st{font = (getFont x c)}+                                   return+                                     ((fontsetter (getFont x c)) ++ (fontstyler x) ++ (chartrans c))+                   _ -> return (chartrans c)+        nodeToLaTeX (Environment ForbiddenTag (Str s) _)+          = return $ s >>= chartrans+        nodeToLaTeX (Environment Wikitable (Str s) l)+          = do st <- get+               put $ st{getInTab = (getInTab st) + 1}+               d <- tableToLaTeX l s+               st2 <- get+               put $ st2{getInTab = (getInTab st)}+               return d+        nodeToLaTeX (Environment Wikitable (TagAttr _ a) l)+          = do st <- get+               put $ st{getInTab = (getInTab st) + 1}+               d <- tableToLaTeX l+                      (if+                         (Map.lookup "class" a) `elem`+                           (map Just ["prettytable", "wikitable"])+                         then "class=\"wikitable\"" else "")+               st2 <- get+               put $ st2{getInTab = (getInTab st)}+               return d+        nodeToLaTeX (Environment Wikilink _ l)+          = do st <- get+               if getInHeading st then return $ wikiLinkCaption l st else+                 if (isImage (shallowFlatten l)) then wikiImageToLaTeX l else+                   return $ wikiLinkToLaTeX l st+        nodeToLaTeX (Environment Link (Str s) l)+          = do st <- get+               if getInHeading st then+                 return $ linkCaption l st s (getInFootnote st) else+                 return $ linkToLaTeX l st s+        nodeToLaTeX (Environment Link2 (Str s) l)+          = nodeToLaTeX (Environment Link (Str s) l)+        nodeToLaTeX (Environment ItemEnv (Str _) [Item _]) = return []+        nodeToLaTeX (Environment ItemEnv (Str s) l)+          = do st <- get+               d <- if s == ";" then do fulllist else+                      do ff <- treeToLaTeX2+                                 (if+                                    (s == ":") &&+                                      ([] ==+                                         [x | x <- l,+                                          not+                                            ((case x of+                                                  Environment Math _ _ -> True+                                                  Item _ -> True+                                                  _ -> False)+                                               || (x `elem` (map (C) "\n\t \r;,.")))])+                                    then+                                    (shallowEnlargeMath+                                       [x | x <- l, not (x `elem` (map (C) "\n\t \r;,.:!?"))])+                                    else l)+                         return [(ff, "")]+               if s /= ";" then+                 return $+                   "\n\\begin{" +++                     (itemEnvironmentName s (getF st)) +++                       "}" +++                         (itemEnvironmentParameters s (getF st)) +++                           (mmm2 d) +++                             "\n\\end{" ++ (itemEnvironmentName s (getF st)) ++ "}\n"+                 else return $ (prolist d st)+          where mmm2 d+                  = case d of+                        (x : _) -> fst x+                        _ -> []+                texit v+                  = do prep <- treeToLaTeX2 . prepart $ v+                       post <- treeToLaTeX2 . postpart $ v+                       return (prep, post)+                 +                fulllist :: Renderer [(String, String)]+                fulllist = mapM texit vv+                 +                vv :: [[Anything Char]]+                vv = [x | x <- splitOn [Item ';'] l, x /= []]+                prepart v = takeWhile ((/=) (C ':')) v+                postpart v+                  = case dropWhile ((/=) (C ':')) v of+                        (_ : xs) -> xs+                        x -> x+                 +                prolist :: [(String, String)] -> MyState -> String+                prolist lis st+                  = do (prd, pod) <- lis+                       if pod == [] then (singlepart prd st) else (doublepart prd pod st)+                doublepart pre po st+                  = "{\\bfseries" +++                      "\n\\begin{" +++                        (itemEnvironmentName s (getF st)) +++                          "}" +++                            (itemEnvironmentParameters s (getF st)) +++                              pre +++                                "\n\\end{" +++                                  (itemEnvironmentName s (getF st)) +++                                    "}\n" +++                                      "}" +++                                        "\n\\begin{" +++                                          (itemEnvironmentName ":" (getF st)) +++                                            "}" +++                                              (itemEnvironmentParameters s (getF st)) +++                                                (itemEnvironmentParameters s (getF st)) +++                                                  (itemSeperator2 s) +++                                                    po +++                                                      "\n\\end{" +++                                                        (itemEnvironmentName ":" (getF st)) ++ "}\n"+                singlepart pre st+                  = "{\\bfseries" +++                      "\n\\begin{" +++                        (itemEnvironmentName s (getF st)) +++                          "}" +++                            (itemEnvironmentParameters s (getF st)) +++                              pre +++                                "\n\\end{" ++ (itemEnvironmentName s (getF st)) ++ "}\n" ++ "}\n"+        nodeToLaTeX (Item c) = return $ "\n" ++ (itemSeperator c) ++ " "+        nodeToLaTeX (Environment Itemgroup _ l) = walk "" l ""+        nodeToLaTeX (Environment Wikiheading (Str s) l)+          = walktrim ("\\" ++ (getsec s) ++ "{") (uncenter l)+              ("}\n" ++ (getsecpost s))+        nodeToLaTeX (Environment Tag (TagAttr ('h' : (x : [])) _) l)+          = if x `elem` "123456" then+              case reads [x] of+                  [] -> walk "" l ""+                  ((y, _) : _) -> let s = replicate y '=' in+                                    walktrim ("\\" ++ (getsec s) ++ "{") (uncenter l)+                                      ("}\n" ++ (getsecpost s))+              else walk "" l ""+        nodeToLaTeX (Environment Bold _ l) = walkbf l+        nodeToLaTeX (Environment Italic _ l) = walkit l+        nodeToLaTeX (Environment Chapter _ l)+          = do d <- treeToLaTeX2 l+               return $ "\\chapter{" ++ (chapterTransform d) ++ "}\n\\myminitoc\n"+        nodeToLaTeX (Environment Tag (TagAttr "sup" _) l)+          = do st<-get+               walk ((fontsetter (font st))++"\\textsuperscript{") l "}"+        nodeToLaTeX (Environment Tag (TagAttr "li" _) l)+          = walk "\\item{}" l ""+        nodeToLaTeX (Environment Tag (TagAttr "a" d) l)+          = do st <- get+               if getInHeading st then treeToLaTeX2 l else+                 case Map.lookup "href" d of+                     Just g -> return $+                                 linkToLaTeX+                                   ((map (C)+                                       (case g of+                                            '/' : _ -> wikiUrlDataToString (urld st) g+                                            _ -> g))+                                      ++ [C ' '] ++ l)+                                   st+                                   ""+                     Nothing -> treeToLaTeX2 l+        nodeToLaTeX (Environment Tag (TagAttr "ol" _) l)+          = do st <- get+               walk+                 ("\n\\begin{" +++                    (itemEnvironmentName "#" (getF st)) +++                      "}" ++ (itemEnvironmentParameters "#" (getF st)))+                 l+                 ("\n\\end{" ++ (itemEnvironmentName "#" (getF st)) ++ "}\n")+        nodeToLaTeX (Environment Tag (TagAttr "dd" _) l)+          = do st <- get+               walk+                 ("\n\\begin{" +++                    (itemEnvironmentName ":" (getF st)) +++                      "}" ++ (itemEnvironmentParameters ":" (getF st)) ++ "\n\\item{}")+                 l+                 ("\n\\end{" ++ (itemEnvironmentName ":" (getF st)) ++ "}\n")+        nodeToLaTeX (Environment Tag (TagAttr "ul" _) l)+          = do st <- get+               walk+                 ("\n\\begin{" +++                    (itemEnvironmentName "*" (getF st)) +++                      "}" ++ (itemEnvironmentParameters "*" (getF st)))+                 l+                 ("\n\\end{" ++ (itemEnvironmentName "*" (getF st)) ++ "}\n")+        nodeToLaTeX (Environment Tag (TagAttr "dir" _) l)+          = do st <- get+               walk+                 ("\n\\begin{" +++                    (itemEnvironmentName "*" (getF st)) +++                      "}" ++ (itemEnvironmentParameters "*" (getF st)))+                 l+                 ("\n\\end{" ++ (itemEnvironmentName "*" (getF st)) ++ "}\n")+        nodeToLaTeX (Environment Tag (TagAttr "strong" _) l) = walkbf l+        nodeToLaTeX (Environment Tag (TagAttr "dfn" _) l) = walkit l+        nodeToLaTeX (Environment Tag (TagAttr "var" _) l) = walkit l+        nodeToLaTeX (Environment Tag (TagAttr "q" _) l) = walkit l+        nodeToLaTeX (Environment Tag (TagAttr "sub" _) l)+          = do st<-get+               walk ((fontsetter (font st))++"\\textsubscript{") l "}"+        nodeToLaTeX (Environment Tag (TagAttr "cite" _) l)+          = walk "\\newline\n \\quad {\\scshape " l "}"+        nodeToLaTeX (Environment Sup (Str s) _)+          = return $ "{$^{\\textrm{\\scriptsize " ++ s ++ "}}$}"+        nodeToLaTeX (Environment Sub (Str s) _)+          = return $ "{$_{\\textrm{\\scriptsize " ++ s ++ "}}$}"+        nodeToLaTeX (Environment Tag (TagAttr "u" _) l)+          = walk "\\uline{" l "}"+        nodeToLaTeX (Environment Tag (TagAttr "ins" _) l)+          = walk "\\uline{" l "}"+        nodeToLaTeX (Environment Tag (TagAttr "del" _) l)+          = walk "\\sout{" l "}"+        nodeToLaTeX (Environment Tag (TagAttr "strike" _) l)+          = walk "\\sout{" l "}"+        nodeToLaTeX (Environment Tag (TagAttr "b" _) l) = walkbf l+        nodeToLaTeX (Environment Tag (TagAttr "script" _) _)+          = walk "" [] ""+        nodeToLaTeX (Environment Tag (TagAttr "style" _) _) = walk "" [] ""+        nodeToLaTeX (Environment Tag (TagAttr "dt" _) l) = walkbf l+        nodeToLaTeX (Environment Tag (TagAttr "i" _) l) = walkit l+        nodeToLaTeX (Environment Tag (TagAttr "em" _) l) = walkit l+        nodeToLaTeX (Environment Tag (TagAttr "s" _) l)+          = walk "\\sout{" l "}"+        nodeToLaTeX (Environment Tag (TagAttr "small" _) l)+          = do st <- get+               if getInHeading st then walk "" l "" else walk "{\\small " l "}"+        nodeToLaTeX (Environment Tag (TagAttr "center" _) l)+          = do d <- treeToLaTeX2 (shallowEnlargeMath l)+               return $ "\n\\begin{center}\n" ++ d ++ "\n\\end{center}\n"+        nodeToLaTeX (Environment Tag (TagAttr "ref" a) l)+          = do st <- get+               case Map.lookup "name" a of+                   Just n -> case Map.lookup n (fndict st) of+                                 Just lll -> go st lll+                                 Nothing -> if not (and (map (`elem` (map (C) " \r\n\t")) l)) then+                                              do put st{fndict = Map.insert n l (fndict st)}+                                                 st2 <- get+                                                 go st2 l+                                              else go st l+                   Nothing -> go st l+          where go ss xx+                  = if getInFootnote ss then walk "\\^{}\\{" xx "\\}" else+                      walkfn "\\myfootnote{" xx "}"+        nodeToLaTeX (Environment Tag (TagAttr "includeonly" _) l)+          = walk "" l ""+        nodeToLaTeX (Environment Tag (TagAttr "blockquote" _) l)+          = walk "\\begin{myblockquote}\n\\item{}" l "\n\\end{myblockquote}"+        nodeToLaTeX (Environment Tag (TagAttr "code" _) l) = walktt l+        nodeToLaTeX (Environment Tag (TagAttr "kbd" _) l) = walktt l+        nodeToLaTeX (Environment Tag (TagAttr "samp" _) l) = walktt l+        nodeToLaTeX (Environment Tag (TagAttr "tt" _) l) = walktt l+        nodeToLaTeX (Environment Tag (TagAttr "big" _) l)+          = do st <- get+               if getInHeading st then walk "" l "" else walk "{\\large " l "}"+        nodeToLaTeX (Environment Tag (TagAttr "div" a) l)+          = let co+                  = case Map.lookup "style" a of+                        Nothing -> Nothing+                        Just x -> case splitOn "background-color:" x of+                                      (_ : (y2 : [])) -> case splitOn ";" y2 of+                                                             (z1 : _) -> case (trim z1) of+                                                                             ('#' : gs) -> let (p,+                                                                                                _,+                                                                                                col)+                                                                                                 = colinfo+                                                                                                     ('l'+                                                                                                        :+                                                                                                        'l'+                                                                                                          :+                                                                                                          gs)+                                                                                             in+                                                                                             Just $+                                                                                               if p+                                                                                                 then+                                                                                                 "\\definecolor{shadecolor}{rgb}"+                                                                                                   +++                                                                                                   col+                                                                                                 else+                                                                                                 "\\colorlet{shadecolor}{"+                                                                                                   +++                                                                                                   z1+                                                                                                     +++                                                                                                     "}"+                                                                             _ -> Just $+                                                                                    "\\colorlet{shadecolor}{"+                                                                                      ++ z1 ++ "}"+                                                             _ -> Nothing+                                      _ -> Nothing+                beg+                  = case co of+                        Nothing -> ""+                        Just x -> "\\LaTeXShadedColorBoxTemplate{" ++ x ++ "}{"+                en+                  = case co of+                        Nothing -> ""+                        Just _ -> "}"+              in+              if (Map.member "class" a) then+                if (Map.findWithDefault [] "class" a) `elem` ["noprint", "topicon"]+                  then return $ beg ++ en else walk beg l en+                else walk beg l en+        nodeToLaTeX (Environment Tag (TagAttr "span" a) l)+          = if (Map.member "class" a) then+              if+                ((Map.findWithDefault [] "class" a) `elem`+                   ["noprint", "latitude", "longitude", "elevation"])+                  || ((Map.findWithDefault [] "id" a) `elem` ["coordinates"])+                then return "" else walk "" l ""+              else walk "" l ""+        nodeToLaTeX (Environment Tag (TagAttr "br" _) _)+          = do st <- get+               return $+                 if (getInCenter st) then "\\\\" else+                   if (getInTab st) > 0 then "\\newline{}" else+                     "$\\text{ }$\\newline{}\n"+        nodeToLaTeX (Environment Source (TagAttr _ a) l)+          = do let g = case reverse l of+                           [] -> []+                           (x : xs) -> if x == (C '\n') then reverse xs else l+               let f = shallowFlatten (map renormalize (breakLines3 linewidth l))+               d <- treeToLaTeX2 (breakLines3 linewidth g)+               st <- get+               return $+                 case+                   do aa <- Map.lookup "lang" a+                      guard (not (getInFootnote st))+                      guard (not ((getInTab st) > 0))+                      return aa+                   of+                     Just j -> '\n' :+                                 replace2+                                   (replace2+                                      (replace2+                                         (replace2+                                            (replace2+                                               (replace2+                                                  (replace2+                                                     (replace2+                                                        (replace2+                                                           (replace2+                                                              ((formatLaTeXBlock defaultFormatOpts)+                                                                 (highlightAs j f))+                                                              "'"+                                                              "\\textquotesingle{}")+                                                           "\n"+                                                           "\\newline\n")+                                                        "{Shaded}\\newline\n"+                                                        "{Shaded}\n")+                                                     "{Highlighting}[]\\newline\n\\newline\n"+                                                     "{Highlighting}[]\n\n")+                                                  "{Highlighting}\\newline\n"+                                                  "{Highlighting}\n")+                                               " "+                                               "\\ensuremath{\\text{ }}")+                                            "%"+                                            "\\%")+                                         "$"+                                         "\\$")+                                      "{Highlighting}[]\\newline\n"+                                      "{Highlighting}[]\n\n")+                                   "&"+                                   "\\&"+                     Nothing -> "\\TemplateSource{" ++ (rtrim d) ++ "}\n"+        nodeToLaTeX (Environment Tag (TagAttr "font" a) l)+          = if Map.member "style" a then+              if+                ((Map.findWithDefault [] "style" a) == "text-decoration:overline")+                then walk "\\myoverline{" l "}" else walk "" l ""+              else walk "" l ""+        nodeToLaTeX (Environment Tag _ l) = walk "" l ""+        nodeToLaTeX (Environment Preformat (TagAttr _ _) l)+          = do d <- treeToLaTeX2 (breakLines3 linewidth l)+               return $ "\\TemplatePreformat{" ++ d ++ "}"+        nodeToLaTeX (Environment DhunUrl _ l)+          = do st <- get+               put st{currentUrl = shallowFlatten l}+               return ""+        nodeToLaTeX (Environment NoWiki _ l) = walk "" l ""+        nodeToLaTeX (Environment HDevLine _ l) = walk "" l ""+        nodeToLaTeX (Environment PageBreak _ _) = return "\\pagebreak "+        nodeToLaTeX (Quad) = return "$\\text{ }${}"+        nodeToLaTeX (Environment TableCap _ l) = walk "" l ""+        nodeToLaTeX (Tab)+          = return $ concat (take tabwidth (repeat "${\\text{ }}${}"))+        nodeToLaTeX (Environment SpaceIndent _ l)+          = if onlySpaces l then return "\n" else+              do st <- get+                 z <- treeToLaTeX2 l+                 put st+                 if (all (\ x -> x `elem` "\r\n\t ") z) then return "" else+                   do d <- treeToLaTeX2 (breakLines3 linewidth l)+                      return $ (preput st) ++ "\\TemplateSpaceIndent{" ++ d ++ "}\n"+          where preput i = if getInCode i then "" else "\\\\\n\n"+        nodeToLaTeX (Environment Math _ l) = return $ mathToLatex l+        nodeToLaTeX (Environment BigMath _ l)+          = return $+              "\\begin{equation*}" ++ (mathTransform l) ++ "\\end{equation*}"+        nodeToLaTeX (Environment Greek (Str s) _)+          = return $ "{\\mbox{$\\" ++ s ++ "$}}"+        nodeToLaTeX (Environment P302 (Str s) _)+          = return $ "\\^{" ++ s ++ "}"+        nodeToLaTeX (Environment HtmlChar (Str s) _)+          = return $ getHtmlChar s+        nodeToLaTeX (Environment NumHtml (Str s) _)+          = return $+              case reads s of+                  [] -> case+                          do z <- case s of+                                      ('x' : xs) -> Just xs+                                      ('X' : xs) -> Just xs+                                      _ -> Nothing+                             g <- unhex z+                             return g+                          of+                            Just x -> chartrans . chr . fromIntegral $ x+                            Nothing -> ("&#" ++ s ++ ";") >>= chartrans+                  (x : _) -> chartrans . chr . fst $ x+        nodeToLaTeX (Environment Gallery _ l)+          = do st <- get+               put st{getInGallery = True}+               d <- galleryToLatex l+               st2 <- get+               put $ (newst st2){getInGallery = (getInGallery st)}+               return d+          where midst i = i{getInGallery = False}+                gins i = generateGalleryImageNumbers i (midst i)+                newst i+                  = (midst i){getGalleryNumbers =+                                (getGalleryNumbers (midst i)) ++ (map toInteger (gins i))}+        nodeToLaTeX (Environment ImageMap _ l)+          = treeToLaTeX2 (imageMapClean l)+        nodeToLaTeX (Environment Reserved (Str "&middot;") _)+          = return "{\\mbox{$\\cdot$}}"+        nodeToLaTeX (Environment Template (Str s) l) = templateToLatex l s+        nodeToLaTeX (Environment Label (Str s) _)+          = return $ "\\label{" ++ s ++ "}"+        nodeToLaTeX _ = return []+ +{-DHUN| Unicode escaping for latex strings DHUN-}+ +doUnicode :: String -> String+doUnicode ('\206' : ('\178' : xs))+  = "\\ensuremath{\\beta}" ++ doUnicode xs+doUnicode (x : xs) = x : doUnicode xs+doUnicode [] = []
+ src/MagicStrings.hs view
@@ -0,0 +1,596 @@+{-DHUN| This module provides string constants DHUN-}+module MagicStrings where+import Data.Char+import Network.URI+import Data.List.Split+import qualified Data.Map as Map+ +{-DHUN| Wikimedia project prefixes so 'de' from de.wikipedia.org DHUN-}+ +foreignPrefixes :: [String]+foreignPrefixes+  = ["af", "als", "an", "roa-rup", "ast", "gn", "av", "ay", "az",+     "id", "ms", "bm", "zh-min-nan", "jv", "map-bms", "su", "bug", "bi",+     "bar", "bs", "br", "ca", "cbk-zam", "ch", "cs", "ny", "sn", "tum",+     "ve", "co", "za", "cy", "da", "pdc", "de", "nv", "na", "lad", "et",+     "ang", "en", "es", "eo", "ext", "eu", "to", "fo", "fr", "frp",+     "fy", "ff", "fur", "ga", "gv", "sm", "gd", "gl", "got", "hak",+     "haw", "hsb", "hr", "io", "ilo", "ig", "ia", "ie", "ik", "xh",+     "zu", "is", "it", "mh", "kl", "pam", "csb", "kw", "kg", "ki", "rw",+     "ky", "rn", "sw", "ht", "ku", "ksh", "la", "lv", "lb", "lt", "lij",+     "li", "ln", "jbo", "lg", "lmo", "hu", "mg", "mt", "mi", "cdo",+     "my", "nah", "fj", "nl", "cr", "ne", "nap", "pih", "no", "nn",+     "nrm", "oc", "om", "ng", "pag", "pi", "pap", "pms", "nds", "pl",+     "pt", "ty", "ro", "rmy", "rm", "qu", "se", "sg", "sc", "sco", "st",+     "tn", "sq", "scn", "simple", "ceb", "ss", "sk", "sl", "so", "sh",+     "fi", "sv", "tl", "tt", "tet", "vi", "tpi", "chy", "tr", "tk",+     "tw", "vec", "vo", "fiu-vro", "wa", "vls", "war", "wo", "ts", "yo",+     "bat-smg", "el", "ab", "ba", "be", "bg", "bxr", "cu", "os", "kk",+     "kv", "mk", "mn", "ce", "ru", "sr", "tg", "udm", "uk", "uz", "xal",+     "cv", "hy", "ka", "he", "yi", "ar", "fa", "ha", "ps", "sd", "ur",+     "ug", "arc", "dv", "as", "bh", "bn", "bo", "bpy", "dz", "gu", "hi",+     "kn", "ks", "ml", "mr", "ne", "new", "or", "pa", "sa", "si", "ta",+     "te", "km", "lo", "th", "am", "ti", "iu", "chr", "ko", "ja", "zh",+     "wuu", "lzh", "yue"]+ +{-DHUN| Wikimedia projects for interwiki links [[w:Foobar]] means en.wikipedia.org/wiki/Foobar DHUN-}+ +multilangwikis :: [(String, String)]+multilangwikis+  = ([("w", "wikipedia"), ("wikipedia", "wikipedia"),+      ("wikt", "wiktionary"), ("wiktionary", "wiktionary")]+       +++       [("n", "wikinews"), ("wikinews", "wikinews"), ("b", "wikibooks"),+        ("wikibooks", "wikibooks"), ("q", "wikiquote")]+         +++         [("wikiquote", "wikiquote"), ("s", "wikisource"),+          ("wikisource", "wikisource"), ("species", "wikispecies")]+           +++           [("wikispecies", "wikispecies"), ("v", "wikiversity"),+            ("wikiversity", "wikiversity")])+ +{-DHUN| Wikimedia projects for interwiki links to wikis which only have got a single language version DHUN-}+ +singlelangwikis :: [(String, String)]+singlelangwikis+  = [("wikimedia", "wikimediafoundation"),+     ("foundation", "wikimediafoundation"),+     ("wmf", "wikimediafoundation"), ("mw", "mediawiki")]+ +{-DHUN| Wikimedia projects for interwiki links to wikis which only have got a single language version DHUN-}+ +wikimediasingellangwikis :: [(String, String)]+wikimediasingellangwikis+  = [("commons", "commons"), ("metawikipedia", "meta"),+     ("meta", "meta"), ("m", "meta"), ("incubator", "incubator"),+     ("strategy", "strategy")]+ +{-DHUN| All Wikis DHUN-}+ +allwikis :: [(String, String)]+allwikis+  = multilangwikis ++ singlelangwikis ++ wikimediasingellangwikis+ +{-DHUN| Prefixes for including images in wikis DHUN-}+ +imgtags :: [[Char]]+imgtags+  = [map toLower x |+     x <- ["\1589\1608\1585\1577", "Billede", "Im\225gen", "Image",+           "Immagine", "Bild", "Afbeelding", "Imagine", "\3619\3641\3611",+           "\22270\20687", "\1605\1604\1601", "Fil", "Archivo", "File",+           "Datei", "Bestand", "Fisier", "\3652\3615\3621\3660",+           "\25991\20214", "Fichier", "\1605\1604\1601", "Archiv",+           "\1060\1072\1081\1083", "\2458\2495\2468\2509\2480", "Datoteka",+           "Fitxer", "Image", "So", "Delwedd", "Fil", "Datei",+           "\913\961\967\949\943\959", "Dosiero", "Archivo", "Pilt",+           "\1662\1585\1608\1606\1583\1607", "Tiedosto", "Fichier",+           "\205omh\225", "\1511\1493\1489\1509", "Datoteka", ": ", "Berkas",+           "Video", "\12501\12449\12452\12523", "Gambar",+           "\4324\4304\4312\4314\4312", "\6063\6016\6047\6070\6042",+           "\54028\51068", "Fascic", "Fichier", "Plaetje", "\3758\3769\3738",+           "Vaizdas", "Att\275ls", "Image", "Sary",+           "\1055\1086\1076\1072\1090\1086\1090\1077\1082\1072", "Fi\351ier",+           "Fail", "Bestand", "Fil", "Fil", "Fichi\232r", "Plik", "Imagem",+           "Fi\351ier", ": ", "S\250bor", "Slika",+           "\1057\1083\1080\1082\1072", "Bild", "\3652\3615\3621\3660",+           "Talaksan", "Dosya", "\1496\1506\1511\1506", "\22294\20687",+           "\22294\20687"]]+ +{-DHUN| lower Greek letter for HTML entity to latex so &delta; to \\delta DHUN-}+ +lowergreek :: [[Char]]+lowergreek+  = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta",+     "theta", "iota", "kappa", "lambda", "mu", "nu", "xi", "pi", "rho",+     "sigma", "tau", "upsilon", "phi", "chi", "psi", "omega"]+ +{-DHUN| not Greek but to be processed like the Greeks above DHUN-}+ +notsogreek :: [[Char]]+notsogreek = ["cap", "cup", "sim"]+ +{-DHUN| Full list of characters with Greek like processing explained above DHUN-}+ +greek :: [[Char]]+greek+  = concat+      (do g <- lowergreek+          case g of+              (x : xs) -> return [(toUpper x) : xs]+              [] -> return [])+      ++ lowergreek ++ notsogreek+ +{-DHUN| HTML entities to latex DHUN-}+ +htmlchars :: [([Char], [Char])]+htmlchars+  = [("thetasym", "{\\mbox{$\\vartheta$}}"),+     ("Upsilon", "{\\mbox{$\\Upsilon$}}"),+     ("epsilon", "{\\mbox{$\\varepsilon$}}"),+     ("upsilon", "{\\mbox{$\\upsilon$}}"),+     ("Epsilon", "{\\mbox{$\\Epsilon$}}"),+     ("Omicron", "{\\mbox{$\\text{O}$}}"),+     ("omicron", "{\\mbox{$\\text{o}$}}"),+     ("forall", "{\\mbox{$\\forall$}}"),+     ("lowast", "{\\mbox{$\\ast$}}"),+     ("there4", "{\\mbox{$\\therefore$}}"),+     ("otimes", "{\\mbox{$\\otimes$}}"),+     ("Lambda", "{\\mbox{$\\Lambda$}}"),+     ("lambda", "{\\mbox{$\\lambda$}}"),+     ("sigmaf", "{\\mbox{$\\varsigma$}}"),+     ("dagger", "{\\mbox{$\\dagger$}}"),+     ("Dagger", "{\\mbox{$\\ddagger$}}"),+     ("hellip", "{\\mbox{$\\ldots$}}"),+     ("lfloor", "{\\mbox{$\\lfloor$}}"),+     ("rfloor", "{\\mbox{$\\rfloor$}}"),+     ("spades", "{\\mbox{$\\spadesuit$}}"),+     ("hearts", "{\\mbox{$\\varheartsuit$}}"),+     ("plusmn", "{\\mbox{$\\pm$}}"), ("divide", "{\\mbox{$\\div$}}"),+     ("Scaron", "{\\mbox{$\\text{\\v{S}}$}}"),+     ("scaron", "{\\mbox{$\\text{\\v{s}}$}}"),+     ("thinsp", "{\\mbox{$\\,$}}"),+     ("permil", "{\\mbox{$\\text{\\textperthousand}$}}"),+     ("lsaquo", "{\\mbox{$\\text{\\guilsinglleft}$}}"),+     ("rsaquo", "{\\mbox{$\\text{\\guilsinglright}$}}"),+     ("curren", "{\\mbox{$\\text{\\currency}$}}"),+     ("brvbar", "{\\mbox{$\\text{\\textbrokenbar}$}}"),+     ("middot", "{\\mbox{$\\cdot$}}"),+     ("frac14", "{\\mbox{$\\frac{1}{4}$}}"),+     ("frac12", "{\\mbox{$\\frac{1}{2}$}}"),+     ("frac34", "{\\mbox{$\\frac{3}{4}$}}"),+     ("iquest", "{\\mbox{$\\text{\\textquestiondown}$}}"),+     ("Agrave", "{\\mbox{$\\text{\\`A}$}}"),+     ("Aacute", "{\\mbox{$\\text{\\'A}$}}"),+     ("Atilde", "{\\mbox{$\\text{\\~A}$}}"),+     ("Ccedil", "{\\mbox{$\\text{\\c{C}}$}}"),+     ("Egrave", "{\\mbox{$\\text{\\`E}$}}"),+     ("Eacute", "{\\mbox{$\\text{\\'E}$}}"),+     ("Igrave", "{\\mbox{$\\text{\\`I}$}}"),+     ("Iacute", "{\\mbox{$\\text{\\'I}$}}"),+     ("Ntilde", "{\\mbox{$\\text{\\~N}$}}"),+     ("Ograve", "{\\mbox{$\\text{\\`O}$}}"),+     ("Oacute", "{\\mbox{$\\text{\\'O}$}}"),+     ("Otilde", "{\\mbox{$\\text{\\~O}$}}"),+     ("Oslash", "{\\mbox{$\\O$}}"),+     ("Ugrave", "{\\mbox{$\\text{\\`U}$}}"),+     ("Uacute", "{\\mbox{$\\text{\\'U}$}}"),+     ("Yacute", "{\\mbox{$\\text{\\'Y}$}}"),+     ("agrave", "{\\mbox{$\\text{\\`a}$}}"),+     ("aacute", "{\\mbox{$\\text{\\'a}$}}"),+     ("atilde", "{\\mbox{$\\text{\\~a}$}}"),+     ("ccedil", "{\\mbox{$\\text{\\c{c}}$}}"),+     ("egrave", "{\\mbox{$\\text{\\`e}$}}"),+     ("eacute", "{\\mbox{$\\text{\\'e}$}}"),+     ("igrave", "{\\mbox{$\\text{\\`i}$}}"),+     ("iacute", "{\\mbox{$\\text{\\'i}$}}"),+     ("ntilde", "{\\mbox{$\\text{\\~n}$}}"),+     ("ograve", "{\\mbox{$\\text{\\`o}$}}"),+     ("oacute", "{\\mbox{$\\text{\\'o}$}}"),+     ("otilde", "{\\mbox{$\\text{\\~o}$}}"),+     ("oslash", "{\\mbox{$\\o$}}"),+     ("ugrave", "{\\mbox{$\\text{\\`u}$}}"),+     ("uacute", "{\\mbox{$\\text{\\'u}$}}"),+     ("yacute", "{\\mbox{$\\text{\\'y}$}}"), ("#x202f", "{\\,}"),+     ("#8704", "{\\mbox{$\\forall$}}"),+     ("#8706", "{\\mbox{$\\partial$}}"),+     ("#8707", "{\\mbox{$\\exists$}}"),+     ("exist", "{\\mbox{$\\exists$}}"),+     ("#8709", "{\\mbox{$\\varnothing$}}"),+     ("empty", "{\\mbox{$\\varnothing$}}"),+     ("#8711", "{\\mbox{$\\nabla$}}"), ("nabla", "{\\mbox{$\\nabla$}}"),+     ("#8712", "{\\mbox{$\\in$}}"), ("#8713", "{\\mbox{$\\notin$}}"),+     ("notin", "{\\mbox{$\\notin$}}"), ("#8715", "{\\mbox{$\\ni$}}"),+     ("#8719", "{\\mbox{$\\prod$}}"), ("#8721", "{\\mbox{$\\sum$}}"),+     ("#8722", "{\\mbox{$-$}}"), ("minus", "{\\mbox{$-$}}"),+     ("#8727", "{\\mbox{$\\ast$}}"), ("#8730", "{\\mbox{$\\sqrt$}}"),+     ("radic", "{\\mbox{$\\sqrt$}}"), ("#8733", "{\\mbox{$\\propto$}}"),+     ("#8734", "{\\mbox{$\\infty$}}"), ("infin", "{\\mbox{$\\infty$}}"),+     ("#8736", "{\\mbox{$\\angle$}}"), ("#8743", "{\\mbox{$\\wedge$}}"),+     ("#8744", "{\\mbox{$\\vee$}}"), ("#8745", "{\\mbox{$\\cap$}}"),+     ("#8746", "{\\mbox{$\\cup$}}"), ("#8747", "{\\mbox{$\\int$}}"),+     ("#8756", "{\\mbox{$\\therefore$}}"),+     ("#8764", "{\\mbox{$\\sim$}}"), ("#8773", "{\\mbox{$\\cong$}}"),+     ("#8776", "{\\mbox{$\\approx$}}"),+     ("asymp", "{\\mbox{$\\approx$}}"), ("#8800", "{\\mbox{$\\neq$}}"),+     ("#8801", "{\\mbox{$\\equiv$}}"), ("equiv", "{\\mbox{$\\equiv$}}"),+     ("#8804", "{\\mbox{$\\leq$}}"), ("#8805", "{\\mbox{$\\geq$}}"),+     ("#8834", "{\\mbox{$\\subset$}}"),+     ("#8835", "{\\mbox{$\\supset$}}"),+     ("#8836", "{\\mbox{$\\nsubset$}}"),+     ("#8838", "{\\mbox{$\\subseteq$}}"),+     ("#8839", "{\\mbox{$\\supseteq$}}"),+     ("#8853", "{\\mbox{$\\oplus$}}"), ("oplus", "{\\mbox{$\\oplus$}}"),+     ("#8855", "{\\mbox{$\\otimes$}}"), ("#8869", "{\\mbox{$\\bot$}}"),+     ("#8901", "{\\mbox{$\\cdot$}}"), ("Gamma", "{\\mbox{$\\Gamma$}}"),+     ("Delta", "{\\mbox{$\\Delta$}}"), ("Theta", "{\\mbox{$\\Theta$}}"),+     ("Sigma", "{\\mbox{$\\Sigma$}}"), ("Omega", "{\\mbox{$\\Omega$}}"),+     ("alpha", "{\\mbox{$\\alpha$}}"), ("gamma", "{\\mbox{$\\gamma$}}"),+     ("delta", "{\\mbox{$\\delta$}}"), ("theta", "{\\mbox{$\\theta$}}"),+     ("kappa", "{\\mbox{$\\kappa$}}"), ("sigma", "{\\mbox{$\\sigma$}}"),+     ("omega", "{\\mbox{$\\omega$}}"),+     ("#8224", "{\\mbox{$\\dagger$}}"),+     ("#8225", "{\\mbox{$\\ddagger$}}"),+     ("#8230", "{\\mbox{$\\ldots$}}"), ("#8242", "{\\mbox{$\\prime$}}"),+     ("prime", "{\\mbox{$\\prime$}}"),+     ("#8243", "{\\mbox{$\\second$}}"),+     ("Prime", "{\\mbox{$\\second$}}"),+     ("#8592", "{\\mbox{$\\leftarrow$}}"),+     ("#8593", "{\\mbox{$\\uparrow$}}"),+     ("#8594", "{\\mbox{$\\rightarrow$}}"),+     ("#8595", "{\\mbox{$\\downarrow$}}"),+     ("#8596", "{\\mbox{$\\leftrightarrow$}}"),+     ("#8968", "{\\mbox{$\\lceil$}}"), ("lceil", "{\\mbox{$\\lceil$}}"),+     ("#8969", "{\\mbox{$\\rceil$}}"), ("rceil", "{\\mbox{$\\rceil$}}"),+     ("#8970", "{\\mbox{$\\lfloor$}}"),+     ("#8971", "{\\mbox{$\\rfloor$}}"),+     ("#9674", "{\\mbox{$\\lozenge$}}"),+     ("#9824", "{\\mbox{$\\spadesuit$}}"),+     ("#9827", "{\\mbox{$\\clubsuit$}}"),+     ("clubs", "{\\mbox{$\\clubsuit$}}"),+     ("#9829", "{\\mbox{$\\varheartsuit$}}"),+     ("#9830", "{\\mbox{$\\vardiamondsuit$}}"),+     ("diams", "{\\mbox{$\\vardiamondsuit$}}"),+     ("pound", "{\\mbox{$\\pounds$}}"),+     ("micro", "{\\mbox{$\\Micro$}}"), ("times", "{\\mbox{$\\times$}}"),+     ("Alpha", "{\\mbox{$\\Alpha$}}"), ("Kappa", "{\\mbox{$\\Kappa$}}"),+     ("upsih", "{\\mbox{$\\Upsilon$}}"),+     ("OElig", "{\\mbox{$\\text{\\OE}$}}"),+     ("oelig", "{\\mbox{$\\text{\\oe}$}}"),+     ("tilde", "{\\mbox{$\\text{\\~{}}$}}"),+     ("#8194", "{\\mbox{$\\text{ }$}}"),+     ("#8195", "{\\mbox{$\\text{\\hspace*{1em}}$}}"),+     ("#8201", "{\\mbox{$\\,$}}"), ("#8211", "{\\mbox{$-$}}"),+     ("ndash", "{\\mbox{$-$}}"), ("#8212", "{\\mbox{$\\text{---}$}}"),+     ("mdash", "{\\mbox{$\\text{---}$}}"),+     ("#8216", "{\\mbox{$\\text{\\textquoteleft}$}}"),+     ("lsquo", "{\\mbox{$\\text{\\textquoteleft}$}}"),+     ("#8217", "{\\mbox{$\\text{\\textquoteright}$}}"),+     ("rsquo", "{\\mbox{$\\text{\\textquoteright}$}}"),+     ("#8218", "{\\mbox{$\\text{\\quotesinglbase}$}}"),+     ("sbquo", "{\\mbox{$\\text{\\quotesinglbase}$}}"),+     ("#8220", "{\\mbox{$\\text{\\textquotedblleft}$}}"),+     ("ldquo", "{\\mbox{$\\text{\\textquotedblleft}$}}"),+     ("#8221", "{\\mbox{$\\text{\\textquotedblright}$}}"),+     ("rdquo", "{\\mbox{$\\text{\\textquotedblright}$}}"),+     ("#8222", "{\\mbox{$\\text{\\quotedblbase}$}}"),+     ("bdquo", "{\\mbox{$\\text{\\quotedblbase}$}}"),+     ("#8226", "{\\mbox{$\\bullet$}}"),+     ("#8240", "{\\mbox{$\\text{\\textperthousand}$}}"),+     ("#8249", "{\\mbox{$\\text{\\guilsinglleft}$}}"),+     ("#8250", "{\\mbox{$\\text{\\guilsinglright}$}}"),+     ("#8254", "{\\mbox{$\\text{\\textasciimacron}$}}"),+     ("oline", "{\\mbox{$\\text{\\textasciimacron}$}}"),+     ("#8364", "{\\mbox{$\\text{\\EUR}$}}"),+     ("#8482", "{\\mbox{$\\text{\\texttrademark}$}}"),+     ("trade", "{\\mbox{$\\text{\\texttrademark}$}}"),+     ("#8629", "{\\mbox{$\\hookleftarrow$}}"),+     ("crarr", "{\\mbox{$\\hookleftarrow$}}"),+     ("iexcl", "{\\mbox{$\\text{\\textexclamdown}$}}"),+     ("laquo", "{\\mbox{$\\text{\\guillemotleft}$}}"),+     ("acute", "{\\mbox{$\\text{\\'{}}$}}"),+     ("cedil", "{\\mbox{$\\c{}$}}"),+     ("raquo", "{\\mbox{$\\text{\\guillemotright}$}}"),+     ("Acirc", "{\\mbox{$\\text{\\^A}$}}"),+     ("Aring", "{\\mbox{$\\text{\\r{A}}$}}"),+     ("AElig", "{\\mbox{$\\text{\\AE}$}}"),+     ("Ecirc", "{\\mbox{$\\text{\\^E}$}}"),+     ("Icirc", "{\\mbox{$\\text{\\^I}$}}"),+     ("Ocirc", "{\\mbox{$\\text{\\^O}$}}"),+     ("Ucirc", "{\\mbox{$\\text{\\^U}$}}"),+     ("THORN", "{\\mbox{$\\text{\\Thorn}$}}"),+     ("szlig", "{\\mbox{$\\text{\\ss}$}}"),+     ("acirc", "{\\mbox{$\\text{\\^a}$}}"),+     ("aring", "{\\mbox{$\\text{\\r{a}}$}}"),+     ("aelig", "{\\mbox{$\\text{\\ae}$}}"),+     ("ecirc", "{\\mbox{$\\text{\\^e}$}}"),+     ("icirc", "{\\mbox{$\\text{\\^i}$}}"),+     ("ocirc", "{\\mbox{$\\text{\\^o}$}}"),+     ("ucirc", "{\\mbox{$\\text{\\^u}$}}"),+     ("thorn", "{\\mbox{$\\text{\\thorn}$}}"),+     ("part", "{\\mbox{$\\partial$}}"), ("isin", "{\\mbox{$\\in$}}"),+     ("prod", "{\\mbox{$\\prod$}}"), ("prop", "{\\mbox{$\\propto$}}"),+     ("cong", "{\\mbox{$\\cong$}}"), ("nsub", "{\\mbox{$\\nsubset$}}"),+     ("sube", "{\\mbox{$\\subseteq$}}"),+     ("supe", "{\\mbox{$\\supseteq$}}"), ("perp", "{\\mbox{$\\bot$}}"),+     ("sdot", "{\\mbox{$\\cdot$}}"), ("#915", "{\\mbox{$\\Gamma$}}"),+     ("#916", "{\\mbox{$\\Delta$}}"), ("#920", "{\\mbox{$\\Theta$}}"),+     ("#923", "{\\mbox{$\\Lambda$}}"), ("#926", "{\\mbox{$\\Xi$}}"),+     ("#928", "{\\mbox{$\\Pi$}}"), ("#931", "{\\mbox{$\\Sigma$}}"),+     ("#933", "{\\mbox{$\\Upsilon$}}"), ("#934", "{\\mbox{$\\Phi$}}"),+     ("#936", "{\\mbox{$\\Psi$}}"), ("#937", "{\\mbox{$\\Omega$}}"),+     ("#945", "{\\mbox{$\\alpha$}}"), ("#946", "{\\mbox{$\\beta$}}"),+     ("beta", "{\\mbox{$\\beta$}}"), ("#947", "{\\mbox{$\\gamma$}}"),+     ("#948", "{\\mbox{$\\delta$}}"),+     ("#949", "{\\mbox{$\\varepsilon$}}"),+     ("#950", "{\\mbox{$\\zeta$}}"), ("zeta", "{\\mbox{$\\zeta$}}"),+     ("#951", "{\\mbox{$\\eta$}}"), ("#952", "{\\mbox{$\\theta$}}"),+     ("#953", "{\\mbox{$\\iota$}}"), ("iota", "{\\mbox{$\\iota$}}"),+     ("#954", "{\\mbox{$\\kappa$}}"), ("#955", "{\\mbox{$\\lambda$}}"),+     ("#956", "{\\mbox{$\\mu$}}"), ("#957", "{\\mbox{$\\nu$}}"),+     ("#958", "{\\mbox{$\\xi$}}"), ("#960", "{\\mbox{$\\pi$}}"),+     ("#961", "{\\mbox{$\\rho$}}"), ("#962", "{\\mbox{$\\varsigma$}}"),+     ("#963", "{\\mbox{$\\sigma$}}"), ("#964", "{\\mbox{$\\tau$}}"),+     ("#965", "{\\mbox{$\\upsilon$}}"),+     ("#966", "{\\mbox{$\\varphi$}}"), ("#967", "{\\mbox{$\\chi$}}"),+     ("#968", "{\\mbox{$\\psi$}}"), ("#969", "{\\mbox{$\\omega$}}"),+     ("#977", "{\\mbox{$\\vartheta$}}"),+     ("#982", "{\\mbox{$\\varpi$}}"), ("#402", "{\\mbox{$f$}}"),+     ("fnof", "{\\mbox{$f$}}"), ("larr", "{\\mbox{$\\leftarrow$}}"),+     ("uarr", "{\\mbox{$\\uparrow$}}"),+     ("rarr", "{\\mbox{$\\rightarrow$}}"),+     ("darr", "{\\mbox{$\\downarrow$}}"),+     ("harr", "{\\mbox{$\\leftrightarrow$}}"),+     ("#160", "{\\mbox{$~$}}"), ("nbsp", "{\\mbox{$~$}}"),+     ("#162", "{\\mbox{$\\cent$}}"), ("cent", "{\\mbox{$\\cent$}}"),+     ("#163", "{\\mbox{$\\pounds$}}"), ("#165", "{\\mbox{$\\yen$}}"),+     ("#168", "{\\mbox{$\\spddot$}}"), ("#172", "{\\mbox{$\\neg$}}"),+     ("#174", "{\\mbox{$\\circledR$}}"), ("#177", "{\\mbox{$\\pm$}}"),+     ("#181", "{\\mbox{$\\Micro$}}"), ("#215", "{\\mbox{$\\times$}}"),+     ("#247", "{\\mbox{$\\div$}}"), ("#240", "{\\mbox{$\\eth$}}"),+     ("#913", "{\\mbox{$\\Alpha$}}"), ("#914", "{\\mbox{$\\Beta$}}"),+     ("Beta", "{\\mbox{$\\Beta$}}"), ("#917", "{\\mbox{$\\Epsilon$}}"),+     ("#918", "{\\mbox{$\\Zeta$}}"), ("Zeta", "{\\mbox{$\\Zeta$}}"),+     ("#919", "{\\mbox{$\\Eta$}}"), ("#921", "{\\mbox{$\\Iota$}}"),+     ("Iota", "{\\mbox{$\\Iota$}}"), ("#922", "{\\mbox{$\\Kappa$}}"),+     ("#924", "{\\mbox{$\\Mu$}}"), ("#925", "{\\mbox{$\\Nu$}}"),+     ("#927", "{\\mbox{$\\text{O}$}}"), ("#929", "{\\mbox{$\\Rho$}}"),+     ("#932", "{\\mbox{$\\Tau$}}"), ("#935", "{\\mbox{$\\Chi$}}"),+     ("#959", "{\\mbox{$\\text{o}$}}"),+     ("#978", "{\\mbox{$\\Upsilon$}}"),+     ("#338", "{\\mbox{$\\text{\\OE}$}}"),+     ("#339", "{\\mbox{$\\text{\\oe}$}}"),+     ("#352", "{\\mbox{$\\text{\\v{S}}$}}"),+     ("#353", "{\\mbox{$\\text{\\v{s}}$}}"),+     ("#376", "{\\mbox{$\\text{\\\"Y}$}}"),+     ("Yuml", "{\\mbox{$\\text{\\\"Y}$}}"),+     ("#710", "{\\mbox{$\\text{\\^{}}$}}"),+     ("circ", "{\\mbox{$\\text{\\^{}}$}}"),+     ("#732", "{\\mbox{$\\text{\\~{}}$}}"),+     ("ensp", "{\\mbox{$\\text{ }$}}"),+     ("emsp", "{\\mbox{$\\text{\\hspace*{1em}}$}}"),+     ("bull", "{\\mbox{$\\bullet$}}"),+     ("euro", "{\\mbox{$\\text{\\EUR}$}}"),+     ("quot", "{\\mbox{$\\text{\\symbol{34}}$}}"),+     ("#161", "{\\mbox{$\\text{\\textexclamdown}$}}"),+     ("#164", "{\\mbox{$\\text{\\currency}$}}"),+     ("#166", "{\\mbox{$\\text{\\textbrokenbar}$}}"),+     ("#167", "{\\mbox{$\\text{\\S}$}}"),+     ("sect", "{\\mbox{$\\text{\\S}$}}"),+     ("#169", "{\\mbox{$\\copyright$}}"),+     ("copy", "{\\mbox{$\\copyright$}}"),+     ("#170", "{\\mbox{$\\text{\\textordfeminine{}}$}}"),+     ("ordf", "{\\mbox{$\\text{\\textordfeminine{}}$}}"),+     ("#171", "{\\mbox{$\\text{\\guillemotleft}$}}"),+     ("#173", "{\\mbox{$\\text{\\-}$}}"),+     ("#175", "{\\mbox{$\\text{\\textasciimacron}$}}"),+     ("macr", "{\\mbox{$\\text{\\textasciimacron}$}}"),+     ("#176", "{\\mbox{$^\\circ$}}"), ("#178", "{\\mbox{${}^2$}}"),+     ("sup2", "{\\mbox{${}^2$}}"), ("#179", "{\\mbox{${}^3$}}"),+     ("sup3", "{\\mbox{${}^3$}}"),+     ("#180", "{\\mbox{$\\text{\\'{}}$}}"),+     ("#182", "{\\mbox{$\\text{\\textparagraph}$}}"),+     ("para", "{\\mbox{$\\text{\\textparagraph}$}}"),+     ("#183", "{\\mbox{$\\cdot$}}"), ("#184", "{\\mbox{$\\c{}$}}"),+     ("#185", "{\\mbox{${}^1$}}"), ("sup1", "{\\mbox{${}^1$}}"),+     ("#186", "{\\mbox{$\\text{\\textordmasculine{}}$}}"),+     ("ordm", "{\\mbox{$\\text{\\textordmasculine{}}$}}"),+     ("#187", "{\\mbox{$\\text{\\guillemotright}$}}"),+     ("#188", "{\\mbox{$\\frac{1}{4}$}}"),+     ("#189", "{\\mbox{$\\frac{1}{2}$}}"),+     ("#190", "{\\mbox{$\\frac{3}{4}$}}"),+     ("#191", "{\\mbox{$\\text{\\textquestiondown}$}}"),+     ("#192", "{\\mbox{$\\text{\\`A}$}}"),+     ("#193", "{\\mbox{$\\text{\\'A}$}}"),+     ("#194", "{\\mbox{$\\text{\\^A}$}}"),+     ("#195", "{\\mbox{$\\text{\\~A}$}}"),+     ("#196", "{\\mbox{$\\text{\\\"A}$}}"),+     ("Auml", "{\\mbox{$\\text{\\\"A}$}}"),+     ("#197", "{\\mbox{$\\text{\\r{A}}$}}"),+     ("#198", "{\\mbox{$\\text{\\AE}$}}"),+     ("#199", "{\\mbox{$\\text{\\c{C}}$}}"),+     ("#200", "{\\mbox{$\\text{\\`E}$}}"),+     ("#201", "{\\mbox{$\\text{\\'E}$}}"),+     ("#202", "{\\mbox{$\\text{\\^E}$}}"),+     ("#203", "{\\mbox{$\\text{\\\"E}$}}"),+     ("Euml", "{\\mbox{$\\text{\\\"E}$}}"),+     ("#204", "{\\mbox{$\\text{\\`I}$}}"),+     ("#205", "{\\mbox{$\\text{\\'I}$}}"),+     ("#206", "{\\mbox{$\\text{\\^I}$}}"),+     ("#207", "{\\mbox{$\\text{\\\"I}$}}"),+     ("Iuml", "{\\mbox{$\\text{\\\"I}$}}"),+     ("#208", "{\\mbox{$\\DH$}}"), ("#209", "{\\mbox{$\\text{\\~N}$}}"),+     ("#210", "{\\mbox{$\\text{\\`O}$}}"),+     ("#211", "{\\mbox{$\\text{\\'O}$}}"),+     ("#212", "{\\mbox{$\\text{\\^O}$}}"),+     ("#213", "{\\mbox{$\\text{\\~O}$}}"),+     ("#214", "{\\mbox{$\\text{\\\"O}$}}"),+     ("Ouml", "{\\mbox{$\\text{\\\"O}$}}"), ("#216", "{\\mbox{$\\O$}}"),+     ("#217", "{\\mbox{$\\text{\\`U}$}}"),+     ("#218", "{\\mbox{$\\text{\\'U}$}}"),+     ("#219", "{\\mbox{$\\text{\\^U}$}}"),+     ("#220", "{\\mbox{$\\text{\\\"U}$}}"),+     ("Uuml", "{\\mbox{$\\text{\\\"U}$}}"),+     ("#221", "{\\mbox{$\\text{\\'Y}$}}"),+     ("#222", "{\\mbox{$\\text{\\Thorn}$}}"),+     ("#223", "{\\mbox{$\\text{\\ss}$}}"),+     ("#224", "{\\mbox{$\\text{\\`a}$}}"),+     ("#225", "{\\mbox{$\\text{\\'a}$}}"),+     ("#226", "{\\mbox{$\\text{\\^a}$}}"),+     ("#227", "{\\mbox{$\\text{\\~a}$}}"),+     ("#228", "{\\mbox{$\\text{\\\"a}$}}"),+     ("auml", "{\\mbox{$\\text{\\\"a}$}}"),+     ("#229", "{\\mbox{$\\text{\\r{a}}$}}"),+     ("#230", "{\\mbox{$\\text{\\ae}$}}"),+     ("#231", "{\\mbox{$\\text{\\c{c}}$}}"),+     ("#232", "{\\mbox{$\\text{\\`e}$}}"),+     ("#233", "{\\mbox{$\\text{\\'e}$}}"),+     ("#234", "{\\mbox{$\\text{\\^e}$}}"),+     ("#235", "{\\mbox{$\\text{\\\"e}$}}"),+     ("euml", "{\\mbox{$\\text{\\\"e}$}}"),+     ("#236", "{\\mbox{$\\text{\\`i}$}}"),+     ("#237", "{\\mbox{$\\text{\\'i}$}}"),+     ("#238", "{\\mbox{$\\text{\\^i}$}}"),+     ("#239", "{\\mbox{$\\text{\\\"i}$}}"),+     ("iuml", "{\\mbox{$\\text{\\\"i}$}}"),+     ("#241", "{\\mbox{$\\text{\\~n}$}}"),+     ("#242", "{\\mbox{$\\text{\\`o}$}}"),+     ("#243", "{\\mbox{$\\text{\\'o}$}}"),+     ("#244", "{\\mbox{$\\text{\\^o}$}}"),+     ("#245", "{\\mbox{$\\text{\\~o}$}}"),+     ("#246", "{\\mbox{$\\text{\\\"o}$}}"),+     ("ouml", "{\\mbox{$\\text{\\\"o}$}}"), ("#248", "{\\mbox{$\\o$}}"),+     ("#249", "{\\mbox{$\\text{\\`u}$}}"),+     ("#250", "{\\mbox{$\\text{\\'u}$}}"),+     ("#251", "{\\mbox{$\\text{\\^u}$}}"),+     ("#252", "{\\mbox{$\\text{\\\"u}$}}"),+     ("uuml", "{\\mbox{$\\text{\\\"u}$}}"),+     ("#253", "{\\mbox{$\\text{\\'y}$}}"),+     ("#254", "{\\mbox{$\\text{\\thorn}$}}"),+     ("#255", "{\\mbox{$\\text{\\\"y}$}}"),+     ("yuml", "{\\mbox{$\\text{\\\"y}$}}"),+     ("sum", "{\\mbox{$\\sum$}}"), ("ang", "{\\mbox{$\\angle$}}"),+     ("and", "{\\mbox{$\\wedge$}}"), ("cap", "{\\mbox{$\\cap$}}"),+     ("cup", "{\\mbox{$\\cup$}}"), ("int", "{\\mbox{$\\int$}}"),+     ("sim", "{\\mbox{$\\sim$}}"), ("sub", "{\\mbox{$\\subset$}}"),+     ("sup", "{\\mbox{$\\supset$}}"), ("Phi", "{\\mbox{$\\Phi$}}"),+     ("Psi", "{\\mbox{$\\Psi$}}"), ("eta", "{\\mbox{$\\eta$}}"),+     ("rho", "{\\mbox{$\\rho$}}"), ("tau", "{\\mbox{$\\tau$}}"),+     ("phi", "{\\mbox{$\\varphi$}}"), ("chi", "{\\mbox{$\\chi$}}"),+     ("psi", "{\\mbox{$\\psi$}}"), ("piv", "{\\mbox{$\\varpi$}}"),+     ("loz", "{\\mbox{$\\lozenge$}}"), ("#38", "{\\mbox{$\\&$}}"),+     ("amp", "{\\mbox{$\\&$}}"), ("#60", "{\\mbox{$<$}}"),+     ("#62", "{\\mbox{$>$}}"), ("yen", "{\\mbox{$\\yen$}}"),+     ("uml", "{\\mbox{$\\spddot$}}"), ("not", "{\\mbox{$\\neg$}}"),+     ("reg", "{\\mbox{$\\circledR$}}"), ("eth", "{\\mbox{$\\eth$}}"),+     ("Eta", "{\\mbox{$\\Eta$}}"), ("Rho", "{\\mbox{$\\Rho$}}"),+     ("Tau", "{\\mbox{$\\Tau$}}"), ("Chi", "{\\mbox{$\\Chi$}}"),+     ("#34", "{\\mbox{$\\text{\\symbol{34}}$}}"),+     ("shy", "{\\mbox{$\\text{\\-}$}}"), ("deg", "{\\mbox{$^\\circ$}}"),+     ("ETH", "{\\mbox{$\\DH$}}"), ("ni", "{\\mbox{$\\ni$}}"),+     ("or", "{\\mbox{$\\vee$}}"), ("ne", "{\\mbox{$\\neq$}}"),+     ("le", "{\\mbox{$\\leq$}}"), ("ge", "{\\mbox{$\\geq$}}"),+     ("Xi", "{\\mbox{$\\Xi$}}"), ("Pi", "{\\mbox{$\\Pi$}}"),+     ("mu", "{\\mbox{$\\mu$}}"), ("nu", "{\\mbox{$\\nu$}}"),+     ("xi", "{\\mbox{$\\xi$}}"), ("pi", "{\\mbox{$\\pi$}}"),+     ("lt", "{\\mbox{$<$}}"), ("weierp", "{\\mbox{$\\wp$}}"),+     ("image", "{\\mbox{$\\Im$}}"), ("real", "{\\mbox{$\\Re$}}"),+     ("alefsym", "{\\mbox{$\\aleph$}}"),+     ("uArr", "{\\mbox{$\\Uparrow$}}"),+     ("rArr", "{\\mbox{$\\Rightarrow$}}"),+     ("dArr", "{\\mbox{$\\Downarrow$}}"),+     ("hArr", "{\\mbox{$\\Leftrightarrow$}}"),+     ("lArr", "{\\mbox{$\\Leftarrow$}}"),+     ("rang", "{\\mbox{$\\rangle$}}"), ("lang", "{\\mbox{$\\langle$}}"),+     ("zwnj", "{}"), ("zwj", ""), ("lrm", ""), ("rlm", ""),+     ("gt", "{\\mbox{$>$}}"), ("Mu", "{\\mbox{$\\Mu$}}"),+     ("#151", "{--}"), ("Nu", "{\\mbox{$\\Nu$}}"), ("frasl", "\8260")]+ +{-DHUN| get latex representation of HTML entity like &amp; DHUN-}+ +getHtmlChar :: String -> String+getHtmlChar x = Map.findWithDefault [] x (Map.fromList htmlchars)+ +removePrintVersion :: [Char] -> [Char]+removePrintVersion lem+  = fun+      ["/Print version", "/Complete Wikibook", "/All Chapters",+       "/Print Version", "/print version", "/Printable version", "/The Whole Book"]+      lem+  where fun (y : ys) x+          = case splitOn y x of+                (z : _) -> fun ys z+                _ -> []+        fun [] x = x+ +{-DHUN| Nearly all HTML tags DHUN-}+ +goodtags1 :: [[Char]]+goodtags1+  = ["includeonly", "references", "blockquote", "noinclude",+     "noframes", "frameset", "colgroup", "fieldset", "basefont",+     "!DOCTYPE", "noscript", "address", "acronym", "caption", "strong",+     "applet", "script", "button", "select", "section", "legend",+     "strike", "object", "input", "center", "legend", "iframe", "small",+     "video", "audio", "style", "input", "label", "tbody", "thead",+     "title", "frame", "param", "base", "area", "font", "code", "span",+     "abbr", "body", "link", "menu", "meta", "samp", "cite", "head",+     "html", "poem", "form", "cite", "ref", "div", "pre", "sub", "sup",+     "big", "del", "map", "bdo", "var", "dfn", "kbd", "col", "ins",+     "dir", "img", "h1", "h2", "h3", "h4", "h5", "h6", "li", "ul", "ol",+     "tt", "dd", "dl", "dt", "hr", "em", "b", "i", "s", "u", "p", "q",+     "a"]+ +{-DHUN| HTML tags for tables rows in tables and so on, only lower case DHUN-}+ +tabletags :: [[Char]]+tabletags = ["table", "td", "th", "tr"]+ +{-DHUN| HTML tags for tables rows in tables and so on, lower case as well as upper case  DHUN-}+ +listOfTableTags :: [[Char]]+listOfTableTags = tabletags ++ (map (map toUpper) tabletags)+ +{-DHUN| All HTML tags DHUN-}+ +listOfTags :: [[Char]]+listOfTags = goodtags1 ++ (map (map toUpper) goodtags1)+ +{-DHUN| Character escaping from Unicode to latex DHUN-}+ +chartrans :: Char -> String+chartrans '\'' = "\\textquotesingle{}"+chartrans '[' = "{$\\text{[}$}"+chartrans ']' = "{$\\text{]}$}"+chartrans '&' = "\\&"+chartrans '%' = "\\%"+chartrans '{' = "\\{"+chartrans '}' = "\\}"+chartrans '_' = "\\_"+chartrans '$' = "\\${}"+chartrans '#' = "\\#"+chartrans '~' = "\\~{}"+chartrans '^' = "\\^{}"+chartrans '"' = "\\symbol{34}"+chartrans '\\' = "\\textbackslash{}"+chartrans '<' = "<{}"+chartrans '>' = ">{}"+chartrans '-' = "-{}"+chartrans c = c : []+ +{-DHUN| Character escaping from Unicode to web links inside latex with the URL package DHUN-}+ +chartransforlink :: Char -> String+chartransforlink '&' = "\\&"+chartransforlink '%' = "\\%"+chartransforlink '{' = "\\{"+chartransforlink '}' = "\\}"+chartransforlink '#' = "\\#"+chartransforlink '$' = "\\${}"+chartransforlink '\\' = "\\textbackslash{}"+chartransforlink '<' = "<{}"+chartransforlink '>' = ">{}"+chartransforlink c+  | 127 < ord c =+    concat (map chartransforlink $ escapeURIString (const False) [c])+chartransforlink c = c : []
+ src/MediaWikiParseTree.hs view
@@ -0,0 +1,74 @@+{-DHUN| A module providing all necessary types of a parse tree for the representation of source written in the MediaWiki markup language DHUN-}+module MediaWikiParseTree where+import Data.Map (Map)+ +{-DHUN| Lists the different environment possible in the mediawiki markup language and example of an environment is an HTML tag with everything included between the its opening and closing tags. Her is is called Tag DHUN-}+ +data EnvType = Wikilink+             | IncludeOnly+             | ImageMap+             | Wikitable+             | Root+             | Wikiheading+             | Itemgroup+             | ItemLine+             | ItemEnv+             | Italic+             | Bold+             | TableCap+             | TableRowSep+             | TableColSep+             | TableHeadColSep+             | Tag+             | TableTag+             | Source+             | Reserved+             | Comment+             | Template+             | TemplateInside+             | TemplateInsideVerbatim+             | Chapter+             | Gallery+             | NoWiki+             | HDevLine+             | NoInclude+             | PageBreak+             | Math+             | Link+             | Link2+             | BigMath+             | Greek+             | P302+             | HtmlChar+             | Attribute+             | SpaceIndent+             | ForbiddenTag+             | Preformat+             | DhunUrl+             | Sub+             | Sup+             | Label+             | Parameter+             | NumHtml+             deriving (Show, Eq, Read)+ +{-DHUN| A type representing a node in a the parse tree. Open and Close represent opening and closing bracket. They will be replace by environments (look at 'Environment' in this data structure) before the parse tree is processed further. The C represents a single character. S stands for a String. Tab is a special elements used like the tabulator character for line breaking purposes. Quad is similar to that. The Item... data construction are for processing itemization enumerations and so on and well be replace be environments before further processing DHUN-}+ +data Anything a = Environment EnvType StartData [Anything a]+                | Open Int EnvType StartData Int+                | Close Int EnvType+                | C a+                | S [a]+                | Item Char+                | ItemStop Char+                | ItemStart Char+                | Quad+                | Tab+                deriving (Show, Eq, Read)+ +{-DHUN| represents the result of a parser for the begin of an environment. A parser for an opening HTML tag is an example. TagAttr means tag with attributes. And is thus a string for the element and a map from string to string for it attributes. Str is a String. And Attr is key value pair and used for attribute in tables.  DHUN-}+ +data StartData = Str [Char]+               | TagAttr String (Map String String)+               | Attr (String, String)+               deriving (Show, Eq, Read)
+ src/MediaWikiParser.hs view
@@ -0,0 +1,1722 @@+{-DHUN| A parser for the medaiiwki grammar DHUN-}+module MediaWikiParser where+import Text.ParserCombinators.Parsec+import qualified Data.List as List+import qualified Data.Map as Map+import MediaWikiParseTree+import MagicStrings+import Control.Monad+import Data.String.HT (trim)+ +{-DHUN| A parser for one particular element of the mediawiki grammar DHUN-}+ +data MyParser tok = MyParser{bad ::+                             [Anything tok] -> GenParser tok () (),+                             start :: MyStack tok -> GenParser tok () StartData,+                             end :: StartData -> GenParser tok () (), allowed :: [EnvType],+                             self :: EnvType,+                             modify :: StartData -> [Anything tok] -> [Anything tok],+                             reenv :: EnvType -> EnvType}+ +{-DHUN| the stack of the parser. See documentation on MyStackFrame in this module for details. DHUN-}+ +type MyStack tok = [MyStackFrame tok]+ +{-DHUN| A stack frame on the parsers stack. A stack frame represents an environment that was opened. So something like an opening HTML tag. The value endparser. Is a parser that should match exactly the closing bracket of the environment. The value startdata is the return value of the start parser of the enviroment. This stack frame is created immediately after the startparser of an environment has matches and is given the return value of that startparser as startdata. The value environment is the environment this stack frame belongs to in case of an HTML tag this would be Tag. See the type EnvType in the module MediaWikiParseTree for a full list of possible environments. In the parse tree that is finally generated each node with arbitrarily nested children has got an EnvType associated with it. The badparser is a parser that is repeatedly tries while processing the current environment, if it matches the current environment is considered to be invalid. Backtracking occurs an the characters currently under consideration are parser (possible very) different manner. So with badparser you can signal that an environment is invalid if a creating parser (the badparser) matches within the environment. The parserenumber is just a number that uniquely identifies each parsers in the list of parsers active for the whole parsing process. These numbers are usually generated by the remake function. The nestingdepth is a bit of a misnomer. It is a unique number for each stack frame. So each stack frame that is newly created gets a different number. DHUN-}+ +data MyStackFrame tok = MyStackFrame{endparser ::+                                     GenParser tok () (),+                                     startdata :: StartData, environment :: EnvType,+                                     badparser :: [Anything tok] -> GenParser tok () (),+                                     parsernumber :: Int, nestingdepth :: Int}+ +{-DHUN| takes a result returned by parseAnything3 and converts it into a parse tree for further processing. The only purpose of this function is to convert the notation of bracket. The bracket a denoted by the Open and Close parse tree elements of the type Anything be the function parseAnything3. The need to be converted to environments, that is node with children in the parse tree. The environments will be denoted by the 'Environment' data constructors of the type Anything|DHUN-}+ +decon2 ::+         (Monad m) =>+         [(a1, MyParser a)] -> m (t, [Anything a]) -> m [Anything a]+decon2 l x+  = do (_, s) <- x+       return (findMatchingBrackets l (reverse s))+ +findMatchingBrackets3 :: [Anything Char] -> [Anything Char]+findMatchingBrackets3 = findMatchingBrackets (remake parsers)+ +{-DHUN| Usually bracket can be close in an order different from the reverse one in which they were opened. But for certain environments this is not allowed, and the order has to be strictly followed. This value is the list of those environments. DHUN-}+ +preserving :: [EnvType]+preserving+  = [Math, Source, Comment, Gallery, NoWiki, NoInclude, BigMath,+     Preformat, TableCap, TableRowSep, TableColSep, TableHeadColSep,+     TemplateInside, Wikitable, TableTag]+ +{-DHUN| Helper function for parseAnyClosingBracket. Should not be called directly. The only parameter is the current parser stack. Returns the depth on the stack of the stack frame whose closing bracket matched. DHUN-}+ +parseAnyClosingBracket2 ::+                          (Show tok, Eq tok, Read tok) =>+                          MyStack tok -> GenParser tok () Integer+parseAnyClosingBracket2+  = (parseAnyClosingBracket3 0) . (List.map (\ x -> endparser x))+ +{-DHUN| Helper function for parseAnyClosingBracket. Should not be called directly. The this will take stack frame by stack frame of the stack. The first parameter is an integer and indicates how many stack frames have allready been take of the stack. Returns the depth on the stack of the stack frame whose closing bracket matched. DHUN-}+ +parseAnyClosingBracket3 ::+                        Integer -> [GenParser tok () ()] -> GenParser tok () Integer+parseAnyClosingBracket3 i (x : xs)+  = try+      (do x+          return i)+      <|> (parseAnyClosingBracket3 (i + 1) xs)+parseAnyClosingBracket3 _ [] = pzero+ +{-DHUN| Remove the n'th elements from a list. n is an integer an given is first parameter. The list to be processed is given as second parameter DHUN-}+ +myremove :: Integer -> [a] -> [a]+myremove _ [] = []+myremove 0 (_ : xs) = myremove (-1) xs+myremove i (x : xs) = x : (myremove (i - 1) xs)+ +{-DHUN| Enumerates a list of parsers. needed to prepare a list of parsers for use with parseAnything2 DHUN-}+ +remake :: [a] -> [(Int, a)]+remake x = zip (iterate (+ 1) 0) x+ +{-DHUN| predicate to test whether the current stack-frame-index is in a stack. The first parameter is the stack-frame-index the second parameter is the stack. Returns true if it could be found DHUN-}+ +isin ::+       (Show tok, Eq tok, Read tok) => Int -> (MyStack tok) -> Bool+isin i s = i `elem` (List.map nestingdepth s)+ +{-DHUN| tries to parse exactly one specific opening bracket. The parameters are identical to the ones of parseAnyOpeningBracket, which the exception of the second parameter. The second parameter is that parser for the bracket currently under consideration. This function 'catch' the BBad 'exception' 'thrown' by parseAnything. In this case it returns pzero, causing the parser to backtrack. DHUN-}+ +parseSpecificOpeningBracket ::+                              (Show tok, Eq tok, Read tok) =>+                              Int ->+                                (Int, MyParser tok) ->+                                  (MyStack tok) ->+                                    [(Int, MyParser tok)] ->+                                      [Anything tok] ->+                                        GenParser tok () (Either2 (MyStack tok, [Anything tok]))+parseSpecificOpeningBracket v (n, x) s l i+  = do r <- do sd <- try (start x s)+               parseAnything (v + 1)+                 (MyStackFrame{endparser = (end x) sd, startdata = sd,+                               environment = self x, badparser = bad x, parsernumber = n,+                               nestingdepth = v}+                    : s)+                 l+                 ((Open (length s) (self x) sd n) : i)+       case r of+           BBad (ss, y) -> if isin v ss then pzero else return (BBad (ss, y))+           _ -> return r+ +{-DHUN| tried to parse any of the opening brackets given by the parsers passed as the third parameter. The first parameter is the stack number (see documentation of the parseAnything function for more details on that). The second parameter is the current parser stack (see documentation of the parseAnything2 function for more details on that). The forth parameter is the list of parsers to b taken into account by the general parsing process. In contrast the third parameter contains only a list of parsers that are allowed to match in the current step of the parsing process. The fifth parameter is the current parser output stream. That is the information returned by the parser up to the current step. It is kind of an accumulator for parser results. DHUN-}+ +parseAnyOpeningBracket ::+                         (Show tok, Eq tok, Read tok) =>+                         Int ->+                           MyStack tok ->+                             [(Int, MyParser tok)] ->+                               [(Int, MyParser tok)] ->+                                 [Anything tok] ->+                                   GenParser tok () (Either2 (MyStack tok, [Anything tok]))+parseAnyOpeningBracket _ _ [] _ _ = pzero+parseAnyOpeningBracket v s (x : xs) l i+  = try (parseSpecificOpeningBracket v x s l i) <|>+      parseAnyOpeningBracket v s xs l i+ +{-DHUN| insert a list of closing brackets into the parser output stream. Later on matching opening and closing brackets will be found and parse tree will be generated this way. The first parameter is an integer it is the number of brackets which should be close. The second parameter is the parser stack. It says which kind of brackets should be closed. It returns a parser output stream just containing the opening brackets DHUN-}+ +generateClosingBrackets ::+                          (Num a, Eq a, Show tok, Eq tok, Read tok) =>+                          a -> MyStack tok -> [Anything tok]+generateClosingBrackets 0 (s : xs)+  = [Close (length xs) (environment s)]+generateClosingBrackets mi (s : xs)+  = (Close (length xs) (environment s)) :+      (generateClosingBrackets (mi - 1) xs)+generateClosingBrackets _ _ = []+ +{-DHUN| insert a list of opening brackets into the parser output stream. Later on matching opening and closing brackets will be found and parse tree will be generated this way. The first parameter is an integer it is the number of brackets which should be opened. The second parameter is the parser stack. It says which kind of brackets should be opened. It returns a parser output stream just containing the opening brackets DHUN-}+ +generateOpeningBrackets ::+                          (Num a, Eq a, Show tok, Eq tok, Read tok) =>+                          a -> MyStack tok -> [Anything tok]+generateOpeningBrackets 0 _ = []+generateOpeningBrackets mi (s : xs)+  = (Open (length xs) (environment s) (startdata s) (parsernumber s))+      : (generateOpeningBrackets (mi - 1) xs)+generateOpeningBrackets _ _ = []+ +data Either2 b = RRight b+               | BBad b+ +{-DHUN| tries to match any of the currently possible closing brackets. Brackets closed in a order different from the reverse to the one in which they were opened are usually possible. And exception are the so called preserving elements, they can only be closed in the correct order. In the general case of this kind of crossbracketing it is necessary to add some opening and closing brackets to the output stream and to take the right stack frame of the stack keeping all others on it in the right order. DHUN-}+ +parseAnyClosingBracket ::+                         (Show tok, Eq tok, Read tok) =>+                         Int ->+                           MyStack tok ->+                             [(Int, MyParser tok)] ->+                               [Anything tok] ->+                                 GenParser tok () (Either2 (MyStack tok, [Anything tok]))+parseAnyClosingBracket v s l i+  = do mi <- try+               (do mmi <- parseAnyClosingBracket2 s+                   guard+                     (case s of+                          (g : _) -> (mmi == 0) ||+                                       ((environment g) == Link2) ||+                                         ((not ((environment g) `elem` preserving)) &&+                                            (not+                                               ((environment (s !! (fromIntegral mmi))) `elem`+                                                  preserving)))+                          [] -> False)+                   return mmi)+       let ss = myremove mi s+       parseAnything v ss l+         ((reverse+             ((generateClosingBrackets mi s) +++                (reverse (generateOpeningBrackets mi ss))))+            ++ i)+ +{-DHUN| this function tries to match the bad parser of the current environment. If it matches it returns BBAD, otherwise it returns RRight. See also comment of the parserAnything function. DHUN-}+ +trybadparser ::+               (Show tok, Eq tok, Read tok) =>+               MyStack tok ->+                 [Anything tok] -> GenParser tok () (Either2 (MyStack tok, [a2]))+trybadparser s i+  = do x <- case s of+                (g : _) -> (do _ <- (badparser g) i+                               return True)+                             <|> return False+                [] -> return False+       if x == True then return (BBad (s, [])) else+         return (RRight (s, []))+ +{-DHUN| this is the main function of the parser which calls itself recursively. To run the parser you should not call this function directly but rather use parseAnything2. The parameter are the same as the parameters to the parameters to the function parseAnything2. So look at the documentation for their meaning. But there is one additional parameter namely the first one. This is the stack frame number, it is increase for every stack frame and never decreased this way each stack frame has got a unique identifier this way. An other difference is the return type this function returns the always same type as the function parseAnything2, but wrapped in the Either2 monad. The Either2 monad has an additional bit to signal whether the parse was good or bad. The bad bit signals so called bad parser of the current environment has matched signaling that the environment is to be considered invalid, and we have to backtrack. But what we do here is just stop paring and return a successful parse, but return the bad flag as set in the return type. This will propagate through to the parser that was trying to open the environment that caused the current problem. If that recognizes the problem it can flag the environment as failed by returning pzero. So again here we just return BBad. So we kind of throw an exception. And in parseSpecificOpeningBracket we will catch BBad and signal the actual problem by returning pzero and that way kick of backtracking. DHUN-}+ +parseAnything ::+                (Show tok, Eq tok, Read tok) =>+                Int ->+                  MyStack tok ->+                    [(Int, MyParser tok)] ->+                      [Anything tok] ->+                        GenParser tok () (Either2 (MyStack tok, [Anything tok]))+parseAnything v s l i+  = (do eof+        return $ RRight (s, i ++ (generateClosingBrackets (length s) s)))+      <|>+      do nb <- trybadparser s i+         case nb of+             RRight _ -> try (parseAnyClosingBracket v s l i) <|>+                           case s of+                               (g : _) -> do try+                                               (parseAnyOpeningBracket v s+                                                  [x | x <- l,+                                                   (environment g) `elem` (allowed (snd x))]+                                                  l+                                                  i)+                               [] -> return (RRight ([], i))+                           <|>+                           do c <- anyToken+                              parseAnything v s l ((C c) : i)+             BBad _ -> case s of+                           (g : _) -> try+                                        (parseAnyOpeningBracket v s+                                           [x | x <- l, (environment g) `elem` (allowed (snd x))]+                                           l+                                           i)+                                        <|> return (BBad (s, i))+                           [] -> pzero+ +{-DHUN| This is the main entry point of the parse. So the function you need to call when you want to convert the source into the parse tree. The first parameter is the stack. I usually should contain only and exactly the root stack frame. The second parameter is an enumerated list of parsers. You usually take a list like the list parsers from this module and enumerate it by running remake on it. So thats the list of environments the parser is able to recognize. The third parameter is the parse results that have been created so far. Since we are just starting the parse this has to be the empty list. The function returns a parser. See the documentation of the parse module for more details on the type GenParser. Roughly is means that this parser takes an input list whose items are of type tok and that the parsers does not have state (hence the void type '()') and return a tuple. The first elements of that tuple is a stack. Where a new stack frame is added to the stack for each new environment that is found to open by the parser, like an opening HTML tag. And the second elements of the tuple is a parse tree, that is a list of parse tree elements, where each parse tree element may contain sublists of parse tree element. This way it is a real tree. DHUN-}+ +parseAnything2 ::+                 (Show tok, Eq tok, Read tok) =>+                 MyStack tok ->+                   [(Int, MyParser tok)] ->+                     [Anything tok] -> GenParser tok () (MyStack tok, [Anything tok])+parseAnything2 s l i+  = do x <- parseAnything 0 s l i+       case x of+           BBad (_, b) -> return (s, b)+           RRight b -> return b+ +{-DHUN| this find the matching closing bracket for an opening bracket. It returns a tuple. Its first element is the environment created form the given opening bracket together with its closing bracket and the content between opening and closing bracket. Its second elements is the remaining list of parsed elements, after the closing bracket. This list does still contain the Open and Close parser tree elements for opening and closing bracket, and those are not yet converted to environments. This function takes the list of parse tree elements after the opening bracket as first input parameter. It takes the index of the parser that created the opening bracket as second input parameter. That is the index created by the remake function in this module. It takes the size of the stack at the time when the opening bracket was found as third input parameter. It takes the EnvType of the environment of the opening bracket as fourth input parameter. It takes the StartData parse result associated with the opening bracket as fifth parameter. The sixth parameter is the accumulator an should be the empty list when calling this function externally. The seventh parameter is the remaining parse tree after the opening bracket without the opening and closing brackets converted to environments DHUN-}+ +findMatchingClosingBracket ::+                           [(a1, MyParser a)] ->+                             Int ->+                               Int ->+                                 EnvType ->+                                   StartData ->+                                     [Anything a] -> [Anything a] -> (Anything a, [Anything a])+findMatchingClosingBracket l n i e s b ((Close i2 e2) : xs)+  = if (i, e) == (i2, e2) then+      (Environment ((reenv (snd (l !! n))) e) s+         ((modify (snd (l !! n))) s (findMatchingBrackets l (reverse b))),+       xs)+      else findMatchingClosingBracket l n i e s ((Close i2 e2) : b) xs+findMatchingClosingBracket l n i e s b (x : xs)+  = findMatchingClosingBracket l n i e s (x : b) xs+findMatchingClosingBracket l n _ e s b []+  = (Environment e s+       ((modify (snd (l !! n))) s (findMatchingBrackets l (reverse b))),+     [])+ +{-DHUN| run findMatchingBrackets on the inner part environment given as second parameter. This function takes the enumerated list of parsers created by remake as first input parameter DHUN-}+ +findMatchingBrackets2 ::+                      [(a1, MyParser a)] -> Anything a -> Anything a+findMatchingBrackets2 l (Environment e s b)+  = Environment e s (findMatchingBrackets l b)+findMatchingBrackets2 l xs+  = Environment Root (Str "") (findMatchingBrackets l [xs])+ +{-DHUN| the parser (Anything3) creates a list of parser elements, which is not a tree. The environments which will form the nodes with children in the final tree are denoted as opening and closing brackets in this list. This function takes that list as second input parameter, finds matching pairs of opening and closing brackets and converts the to environments. The opening an closing brackets are already balanced because of the way Anything3 works, that means there is exactly one matching closing bracket for each opening one and they open and close in to proper order. This function takes the enumerated list of parsers as first input parameter, that is the same list also given to the function Anything. DHUN-}+ +findMatchingBrackets ::+                     [(a1, MyParser a)] -> [Anything a] -> [Anything a]+findMatchingBrackets l xs = findMatchingBrackets4 l xs+ +findMatchingBrackets4 ::+                      [(a1, MyParser a)] -> [Anything a] -> [Anything a]+findMatchingBrackets4 l ((Open i e s n) : xs)+  = let (t, xxs) = findMatchingClosingBracket l n i e s [] xs in+      (findMatchingBrackets2 l t) : (findMatchingBrackets4 l xxs)+findMatchingBrackets4 l (x : xs) = x : (findMatchingBrackets4 l xs)+findMatchingBrackets4 _ [] = []+ +{-DHUN| a list of environments. Most parsers use this list as their 'allowed' variable. Meaning that the parser is only allowed to match within the environments given in the 'allowed' list DHUN-}+ +everywhere :: [EnvType]+everywhere = [Wikitable] ++ everywheretbl+ +{-DHUN| list containing the Italic and Bold environments, see documentation on the list 'everywhere' in this module DHUN-}+ +bi :: [EnvType]+bi = [Italic, Bold]+ +{-DHUN| list containing the same environments as the list 'everywhere' except the Wikitable environment, see documentation on the list 'everywhere' in this module DHUN-}+ +everywheretbl :: [EnvType]+everywheretbl = bi ++ everywherebi+ +{-DHUN| list containing the same environments as the list 'everywhere' except the environment Wikitable, Bold and Italic, see documentation on the list 'everywhere' in this module DHUN-}+ +everywherebi :: [EnvType]+everywherebi = basicwhere ++ [Wikilink]+ +{-DHUN| list containing the same environments as the list 'everywhere' except the environment Wikitable, Bold, Italic and Wikilink see documentation on the list 'everywhere' in this module DHUN-}+ +basicwhere :: [EnvType]+basicwhere = [Link] ++ verybasicwhere+ +{-DHUN| list containing the same environments as the list 'everywhere' except the environment Wikitable, Bold, Italic, Wikilink and Link see documentation on the list 'everywhere' in this module DHUN-}+ +verybasicwhere :: [EnvType]+verybasicwhere+  = [Itemgroup, Root, Wikiheading, TableCap, Chapter, Tag, TableTag,+     TemplateInside, IncludeOnly]+ +{-DHUN| list containing the environments where the parser linkp is allowed to match. Currently this seems to be everywhere. So this possibly can go away  DHUN-}+ +everywherel :: [EnvType]+everywherel = basicwhere ++ bi ++ [Wikitable, Wikilink]+ +{-DHUN| list containing the same environments as the list 'everywhere' except the Link environment see documentation on the list 'everywhere' in this module DHUN-}+ +everywherel2 :: [EnvType]+everywherel2 = verybasicwhere ++ bi ++ [Wikitable, Wikilink]+ +{-DHUN| list containing the TableColSep and TableHeadColSep environments, see documentation on the list 'everywhere' in this module. the environments mean table header column separator and table column separator DHUN-}+ +wikilinkwhere :: [EnvType]+wikilinkwhere = [TableColSep, TableHeadColSep]+ +{-DHUN| the list of parsers needed for processing the HTML output created by MediaWiki DHUN-}+ +minparsers :: [MyParser Char]+minparsers+  = [doctagparser, metatagparser, supp, subp, dhunurlp, itagparser,+     pagebreakp, htmlcharp, p302p, attrp, greekp, brparser, mytablep,+     mytrsepp, mytcolsepp, mytcapp, mythcolsepp, tagparser, tagparserp,+     tagparser2, tagparser2p, tagparsert, tagparsert, tagparser2t,+     tagparsers, stagparser, commentp, numhtmlp, rtagparser]+ +htmlminparsers :: [MyParser Char]+htmlminparsers+  = [doctagparser, metatagparser, supp, subp, dhunurlp, itagparser,+     pagebreakp, htmlcharp, p302p, attrp, greekp, brparser, htmytablep,+     htmytrsepp, htmytcolsepp, htmytcapp, htmythcolsepp, tagparser,+     tagparserp, tagparser2, tagparser2p, tagparsert, tagparsert,+     tagparser2t, tagparsers, stagparser, commentp, numhtmlp,+     rtagparser]+ +{-DHUN| the list of parsers needed for processing the image title description so that is the content a html attibutes DHUN-}+ +imgparsers :: [MyParser Char]+imgparsers = [supp, subp, htmlcharp, p302p, greekp, numhtmlp]+ +{-DHUN| the list of parsers needed for parsing source code in the MediaWiki markup language DHUN-}+ +parsers :: [MyParser Char]+parsers+  = [doctagparser, metatagparser, supp, subp, dhunurlp, itagparser,+     chapterp, prep, pagebreakp, htmlcharp, p302p, attrp, greekp,+     brparser, wikilinkp, wikitablep, mytablep, wikiheadingp,+     itempgrouppt, itempgroupp, itemlinep, boldp, italicp, tablecapp,+     tablecapp2, tablecapp3, rowsepp, mytrsepp, colsepp, colsepp2,+     mytcolsepp, mytcapp, headcolsepp, headcolsepp2, mythcolsepp,+     galleryp, imagemapp, nowikip, noincludep, mathp, imagemapp,+     ttagparser, ttagparser2, ttagparsert, ttagparser2t, ttagparsers,+     tagparser, tagparser2, tagparsert, tagparser2t, tagparsers,+     stagparser, commentp, reservedp, templatewikilinkp, wikiparamp,+     wikitemplatep, templateinsideverbatimp, templateinsidep,+     gallerywlp, imagemapwlp, hdevlinep, linkp, linkp2, presectionp,+     numhtmlp, rtagparser]+ +{-DHUN| the parser record, with some fields initialized with default values DHUN-}+ +baseParser :: MyParser tok+baseParser+  = MyParser{bad = \ _ -> pzero, start = undefined,+             end = \ _ -> return (), allowed = everywhere, self = undefined,+             modify = \ _ x -> x, reenv = id}+ +{-DHUN| this function takes a string and returns a parser that matches any of the given strings DHUN-}+ +oneOfTheStrings :: [String] -> Parser String+oneOfTheStrings (x : xs) = try (string x) <|> (oneOfTheStrings xs)+oneOfTheStrings [] = pzero+ +{-DHUN| parses a HTML entity, that is a character escaped with the ampersand notation DHUN-}+ +htmlcharp :: MyParser Char+htmlcharp+  = baseParser{start =+                 \ _ ->+                   do _ <- char '&'+                      s <- (oneOfTheStrings [fst x | x <- htmlchars])+                      _ <- char ';'+                      return (Str (s)),+               allowed = Preformat : SpaceIndent : NoWiki : everywhere,+               self = HtmlChar}+ +{-DHUN| parses a HTML entity, escaped with numeric ampersand notation DHUN-}+ +numhtmlp :: MyParser Char+numhtmlp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "&#"+                      s <- try (many1 digit) <|>+                             do ss <- try (string "x") <|> try (string "X")+                                sss <- try (many1 hexDigit)+                                return $ ss ++ sss+                      _ <- char ';'+                      return (Str (s)),+               allowed = Preformat : SpaceIndent : NoWiki : everywhere,+               self = NumHtml}+ +{-DHUN| parses a HTML #302 character. Special parser needed since it acts on the receding character DHUN-}+ +p302p :: MyParser Char+p302p+  = baseParser{start =+                 \ _ ->+                   do c <- anyChar+                      _ <- string "&#x302;"+                      return (Str (c : [])),+               self = P302}+ +{-DHUN| parses a HTML &sub entity. DHUN-}+ +subp :: MyParser Char+subp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "&sub"+                      c <- anyChar+                      _ <- string ";"+                      return (Str (c : [])),+               self = Sub}+ +{-DHUN| parses a HTML &sup entity. DHUN-}+ +supp :: MyParser Char+supp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "&sup"+                      c <- anyChar+                      _ <- string ";"+                      return (Str (c : [])),+               self = Sup}+ +{-DHUN| parses the start of a new URL. That is the place where a page begin that was downloaded from an URL different from the previous one DHUN-}+ +dhunurlp :: MyParser Char+dhunurlp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "\ndhunparserurl "+                      return (Str ""),+               end = \ _ -> string "\n" >> return (), self = DhunUrl,+               allowed = [Root, Tag]}+ +{-DHUN| parses a Greek HTML entity. So a Greek letter or something similar DHUN-}+ +greekp :: MyParser Char+greekp+  = baseParser{start =+                 \ _ ->+                   do _ <- char '&'+                      s <- (oneOfTheStrings greek)+                      _ <- char ';'+                      return (Str (s)),+               self = Greek}+ +{-DHUN| parses the mediawiki math tag. That is a latex formula in the wiki DHUN-}+ +mathp :: MyParser Char+mathp+  = (maketagparser ["math"]){allowed =+                               SpaceIndent : everywhere ++ wikilinkwhere,+                             self = Math}+ +{-DHUN| parses a new chapter heading DHUN-}+ +chapterp :: MyParser Char+chapterp+  = baseParser{start =+                 \ _ ->+                   do _ <- try+                             (do _ <- string "\n"+                                 many (char ' '))+                      string "dhunincludechaper" >> return (Str ""),+               end = \ _ -> string "/dhunincludechaper" >> return (),+               self = Chapter}+ +{-DHUN| parses a horizontal dividing line DHUN-}+ +hdevlinep :: MyParser Char+hdevlinep+  = baseParser{start =+                 \ _ ->+                   do _ <- string "----"+                      skipMany (string "-")+                      return (Str ""),+               allowed = [Root], self = HDevLine}+ +{-DHUN| parses the mediawiki 'nowiki' tag DHUN-}+ +nowikip :: MyParser Char+nowikip+  = baseParser{start = \ _ -> string "<nowiki>" >> return (Str ""),+               end = \ _ -> string "</nowiki>" >> return (),+               allowed = everywhere ++ wikilinkwhere ++ [SpaceIndent],+               self = NoWiki}+ +{-DHUN| parses the mediawiki 'noinclude' tag DHUN-}+ +noincludep :: MyParser Char+noincludep+  = baseParser{start =+                 \ _ -> string "<noinclude>" >> return (Str ""),+               end =+                 \ _ ->+                   try (string "</noinclude>" >> return ()) <|>+                     lookAhead (eof >> return ()),+               self = NoInclude}+ +{-DHUN| parses the mediawiki 'includeonly' tag DHUN-}+ +includep :: MyParser Char+includep+  = baseParser{start =+                 \ _ -> string "<includeonly>" >> return (Str ""),+               end = \ _ -> string "</includeonly>" >> return (),+               self = IncludeOnly}+ +{-DHUN| parses the mediawiki 'onlyinclude' tag DHUN-}+ +includep2 :: MyParser Char+includep2+  = baseParser{start =+                 \ _ -> string "<onlyinclude>" >> return (Str ""),+               end = \ _ -> string "</onlyinclude>" >> return (),+               self = IncludeOnly}+ +{-DHUN| parses the mediawiki 'gallery' tag DHUN-}+ +galleryp :: MyParser Char+galleryp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<gallery"+                      skipMany (try (attr))+                      _ <- try (many (try (oneOf " \n"))) <|> return []+                      _ <- char '>'+                      return (Str ""),+               end = \ _ -> string "</gallery>" >> return (), self = Gallery}+ +{-DHUN| parses a wikilink inside a gallery DHUN-}+ +gallerywlp :: MyParser Char+gallerywlp+  = baseParser{bad =+                 \ _ ->+                   do _ <- lookAhead (try (string "</gallery>"))+                      return (),+               start = \ _ -> string "\n" >> return (Str ""),+               end =+                 \ _ ->+                   do _ <- lookAhead (string "\n")+                      return (),+               modify = \ _ x -> dropWhile (== (C ' ')) x, allowed = [Gallery],+               self = Wikilink}+ +{-DHUN| parses the mediawiki 'imagemap' tag DHUN-}+ +imagemapp :: MyParser Char+imagemapp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<imagemap"+                      skipMany (try (attr))+                      _ <- try (many (try (oneOf " \n"))) <|> return []+                      _ <- char '>'+                      return (Str ""),+               end = \ _ -> string "</imagemap>" >> return (), self = ImageMap}+ +{-DHUN| parses a wikilink inside and imagemap DHUN-}+ +imagemapwlp :: MyParser Char+imagemapwlp+  = baseParser{bad =+                 \ _ ->+                   do _ <- lookAhead (try (string "</imagemap>"))+                      return (),+               start =+                 \ _ ->+                   (do _ <- string "\n"+                       try (lookAhead (string "Image:")) <|>+                         try (lookAhead (string "File:"))+                         <|> (lookAhead (string "Datei:")))+                     >> return (Str ""),+               end =+                 \ _ ->+                   do _ <- lookAhead (string "\n")+                      return (),+               allowed = [ImageMap], self = Wikilink}+ +{-DHUN| matches a sequence of arbitrary characters up to the character (an excluding it) where one of the strings given as first parameter matches DHUN-}+ +myany :: [String] -> Parser String+myany x+  = do b <- (try (lookAhead (oneOfTheStrings x) >> return False)) <|>+              return True+       if b then+         do c <- anyChar+            cs <- (myany x)+            return (c : cs)+         else return ""+ +{-DHUN| parses the mediawiki template DHUN-}+ +wikitemplatep :: MyParser Char+wikitemplatep+  = baseParser{start =+                 \ _ ->+                   do _ <- string "{{"+                      s <- myany ["}}", "|"]+                      return (Str s),+               end = \ _ -> string "}}" >> return (),+               allowed =+                 everywhere +++                   wikilinkwhere ++ [TemplateInsideVerbatim, SpaceIndent],+               self = Template}+ +{-DHUN| a special stack frame for parsing the inside of a template DHUN-}+ +madframe :: MyStackFrame Char+madframe+  = MyStackFrame{endparser =+                   (try (lookAhead (oneOfTheStrings ["}}", "|", "="]))) >> return (),+                 startdata = Str "", environment = TemplateInside,+                 badparser = \ _ -> pzero, parsernumber = 0, nestingdepth = 0}+ +{-DHUN| parses the inside of a mediawiki template DHUN-}+ +templateinsidep :: MyParser Char+templateinsidep+  = baseParser{start =+                 \ _ ->+                   do _ <- string "|"+                      (_, bb) <- lookAhead+                                   (try (parseAnything2 [madframe] (remake parsers) []))+                      if+                        all+                          (\ g ->+                             case g of+                                 Open _ _ _ _ -> False+                                 _ -> True)+                          bb+                        then+                        try+                          (do s <- myany ["|", "}}", "="]+                              b <- (try (string "=") >> return True) <|> return False+                              if b then return (Str s) else pzero)+                          <|> return (Str "")+                        else return (Str ""),+               end = \ _ -> lookAhead (oneOfTheStrings ["|", "}}"]) >> return (),+               allowed = [Template], self = TemplateInside}+ +{-DHUN| parses the inside of a mediawiki template, it is parser verbatim that means inner structures are parsed, but returned as plain characters in the parse tree. Needed for templates use for source codes DHUN-}+ +templateinsideverbatimp :: MyParser Char+templateinsideverbatimp+  = baseParser{start =+                 \ sta ->+                   case sta of+                       (g : _) -> case (startdata g) of+                                      Str gg -> if+                                                  (trim gg) `elem`+                                                    ["HaskellGHCiExample",+                                                     "\"HaskellGHCi\",Visual Basic .NET: Vorlage:Code",+                                                     "C++-Programmierung/ Vorlage:Syntax",+                                                     "C++-Programmierung/ Vorlage:Code",+                                                     "LaTeX/Usage", "LaTeX/LaTeX", "Latex Index"]+                                                  then+                                                  do _ <- string "|"+                                                     try+                                                       (do s <- myany ["|", "}}", "="]+                                                           b <- (try (string "=") >> return True)+                                                                  <|> return False+                                                           if b then return (Str s) else pzero)+                                                       <|> return (Str "")+                                                  else pzero+                                      _ -> pzero+                       [] -> pzero,+               end = \ _ -> lookAhead (oneOfTheStrings ["|", "}}"]) >> return (),+               allowed = [Template], self = TemplateInsideVerbatim,+               reenv = const TemplateInside}+ +{-DHUN| parses the inside of a template parameter DHUN-}+ +wikiparamp :: MyParser Char+wikiparamp+  = baseParser{start = \ _ -> string "{{{" >> return (Str ""),+               end = \ _ -> string "}}}" >> return (),+               allowed = everywhere ++ wikilinkwhere ++ [SpaceIndent],+               self = Parameter}+ +{-DHUN| parses a wikilink DHUN-}+ +wikilinkp :: MyParser Char+wikilinkp+  = baseParser{start = \ _ -> string "[[" >> return (Str ""),+               end = \ _ -> string "]]" >> return (),+               bad =+                 \ pchr ->+                   if+                     not $+                       (C '|') `elem`+                         (takeWhile+                            (\ g ->+                               case g of+                                   Open _ Wikilink _ _ -> False+                                   _ -> True)+                            pchr)+                     then+                     do _ <- lookAhead+                               ((try ((string "]") >> notFollowedBy (string "]")) <|>+                                   (try (string "[" >> return ()))+                                   <|> (try (string "\n") >> return ())))+                        return ()+                     else pzero,+               allowed = everywhere ++ wikilinkwhere ++ [SpaceIndent],+               self = Wikilink}+ +{-DHUN| parses a wikilink template for wikipedia links DHUN-}+ +templatewikilinkp :: MyParser Char+templatewikilinkp+  = baseParser{start = \ _ -> string "{{w|" >> return (Str ""),+               end = \ _ -> string "}}" >> return (),+               allowed = everywhere ++ wikilinkwhere,+               modify = \ _ x -> (C 'w') : (C ':') : x, self = Wikilink}+ +{-DHUN| parses a link DHUN-}+ +linkp :: MyParser Char+linkp+  = baseParser{bad =+                 \ _ ->+                   do _ <- lookAhead (do char '\n')+                      return (),+               start =+                 \ _ ->+                   do _ <- string "["+                      skipMany (char ' ')+                      s <- oneOfTheStrings ["http", "https", "mailto", "//"]+                      return (Str (if s == "//" then "http://" else s)),+               end = \ _ -> string "]" >> return (), allowed = everywherel,+               self = Link}+ +{-DHUN| parses a link, in contrast to linkp this does not match inside links and does not require the square bracket notation DHUN-}+ +linkp2 :: MyParser Char+linkp2+  = baseParser{start =+                 \ _ ->+                   do s <- oneOfTheStrings ["http://", "https://"]+                      return (Str s),+               end = \ _ -> lookAhead (oneOf " \n\r\t<>|\"") >> return (),+               allowed = everywherel2, self = Link2, reenv = const Link}+ +{-DHUN| parses a wikitable DHUN-}+ +wikitablep :: MyParser Char+wikitablep+  = baseParser{start =+                 \ _ ->+                   do _ <- char '\n'+                      skipMany (char ' ')+                      _ <- try (string "{|") <|> try (string "{{(!}}")+                      s <- many (noneOf "\n")+                      return (Str s),+               end =+                 \ _ ->+                   do _ <- string "\n"+                      skipMany (char ' ')+                      _ <- try (string "|}") <|> try (string "{{!)}}")+                      return (),+               self = Wikitable}+ +{-DHUN| parses a heading, can be a chapter heading as well as a section heading and so on  DHUN-}+ +wikiheadingp :: MyParser Char+wikiheadingp+  = baseParser{bad =+                 \ _ ->+                   lookAhead+                     (do _ <- string "\n"+                         return ()),+               start =+                 \ _ ->+                   do a1 <- string "\n="+                      a2 <- try (string "=") <|> return ""+                      a3 <- try (string "=") <|> return ""+                      a4 <- try (string "=") <|> return ""+                      a5 <- try (string "=") <|> return ""+                      a6 <- try (string "=") <|> return ""+                      case (a1 ++ a2 ++ a3 ++ a4 ++ a5 ++ a6) of+                          (_ : xs) -> return (Str xs)+                          [] -> pzero,+               end =+                 \ (Str x) ->+                   do _ <- string x+                      _ <- notFollowedBy (char '=')+                      return (),+               self = Wikiheading, allowed = everywherel2}+ +{-DHUN| parses an italic text DHUN-}+ +italicp :: MyParser Char+italicp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "''"+                      return (Str "''"),+               end =+                 \ _ ->+                   do (do _ <- try (string "''")+                          _ <- notFollowedBy (string "'")+                          return ())+                        <|> notFollowedBy (noneOf "\n")+                      return (),+               allowed = SpaceIndent : Wikitable : Bold : everywherebi,+               self = Italic}+ +{-DHUN| parses a bold text DHUN-}+ +boldp :: MyParser Char+boldp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "'''"+                      return (Str "'''"),+               end =+                 \ _ ->+                   do (do _ <- try (string "'''")+                          return ())+                        <|> notFollowedBy (noneOf "\n")+                      return (),+               allowed = SpaceIndent : Wikitable : Italic : everywherebi,+               self = Bold}+ +{-DHUN| parses a table caption DHUN-}+ +tablecapp :: MyParser Char+tablecapp+  = baseParser{bad =+                 \ _ ->+                   lookAhead+                     (try+                        (do _ <- string "||"+                            return ())+                        <|>+                        try+                          (do _ <- char '\n'+                              _ <- notFollowedBy (try (char '|') <|> (char '!'))+                              return ())+                        <|>+                        do _ <- string "!!"+                           return ()),+               start =+                 \ _ ->+                   do _ <- string "\n"+                      skipMany (char ' ')+                      _ <- string "|+"+                      _ <- notFollowedBy (oneOf "-}")+                      return (Str ""),+               end =+                 \ _ ->+                   lookAhead+                     (do _ <- char '\n'+                         _ <- try (char '|') <|> char '!'+                         notFollowedBy . char $ '}'+                         return ()),+               allowed = [Wikitable], self = TableCap}+ +{-DHUN| parses a table caption with additional parameter given to the beginning of the caption element in the wiki source  DHUN-}+ +tablecapp2 :: MyParser Char+tablecapp2+  = baseParser{start =+                 \ _ ->+                   do _ <- string "\n"+                      skipMany (char ' ')+                      _ <- string "|+"+                      _ <- many (noneOf "|")+                      _ <- char '|'+                      _ <- notFollowedBy (oneOf "-}")+                      return (Str ""),+               end =+                 \ _ ->+                   lookAhead+                     (try+                        (do _ <- char '\n'+                            _ <- try (char '|') <|> char '!'+                            notFollowedBy . char $ '}'+                            return ())+                        <|>+                        (try ((string "||" >> return ())) <|> (string "!!" >> return ()))),+               allowed = [Wikitable], self = TableCap}+ +{-DHUN| parses a table caption DHUN-}+ +tablecapp3 :: MyParser Char+tablecapp3+  = baseParser{start =+                 \ _ ->+                   do _ <- string "\n"+                      skipMany (char ' ')+                      _ <- string "|+"+                      _ <- notFollowedBy (oneOf "-}")+                      return (Str "2"),+               allowed = [Wikitable], self = TableCap}+ +{-DHUN| parses a table row separator DHUN-}+ +rowsepp :: MyParser Char+rowsepp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "\n"+                      skipMany (char ' ')+                      _ <- try (string "|-") <|> try (string "{{!-}}")+                      s <- many (noneOf "\n")+                      return (Str s),+               allowed = [Wikitable], self = TableRowSep}+ +{-DHUN| parses a table column separator, with additional parameters parser to the beginning of the environment. This parser actually parses only the beginning elements and whats inside it See  DHUN-}+ +colsepp :: MyParser Char+colsepp+  = baseParser{bad =+                 \ _ ->+                   lookAhead+                     (try+                        (do _ <- try (string "||") <|> try (string "{{!!}}")+                            return ())+                        <|>+                        try+                          (do _ <- char '\n'+                              return ())+                        <|>+                        do _ <- try (string "!!")+                           return ()),+               start =+                 \ _ ->+                   try+                     (try+                        (do _ <- string "\n"+                            skipMany (char ' ')+                            _ <- try (string "|") <|> try (string "{{!}}")+                            _ <- notFollowedBy (oneOf "-}")+                            return (Str ""))+                        <|>+                        do _ <- try (string "||") <|> try (string "{{!!}}")+                           return (Str "")),+               end =+                 \ _ ->+                   try+                     (do _ <- try (string "|") <|> try (string "{{!}}")+                         _ <- notFollowedBy (oneOf "}|")+                         return ()),+               allowed = [Wikitable], self = TableColSep}+ +{-DHUN| parses a column separator without anything inside it DHUN-}+ +colsepp2 :: MyParser Char+colsepp2+  = baseParser{start =+                 \ _ ->+                   try+                     (do _ <- string "\n"+                         skipMany (char ' ')+                         _ <- try (string "|") <|> try (string "{{!}}")+                         _ <- notFollowedBy (oneOf "-}")+                         return (Str "2"))+                     <|>+                     do _ <- try (string "||") <|> try (string "{{!!}}")+                        return (Str "2"),+               allowed = [Wikitable], self = TableColSep}+ +{-DHUN| parses a table header column separator, with additional parameters parser to the beginning of the environment. This parser actually parses only the beginning elements and whats inside it See  DHUN-}+ +headcolsepp :: MyParser Char+headcolsepp+  = baseParser{bad =+                 \ _ ->+                   lookAhead+                     (try+                        (do _ <- try (string "||") <|> (string "{{!!}}")+                            return ())+                        <|>+                        try+                          (do _ <- char '\n'+                              return ())+                        <|>+                        do _ <- try (string "!!")+                           return ()),+               start =+                 \ _ ->+                   try+                     (do _ <- string "\n"+                         skipMany (char ' ')+                         _ <- string "!"+                         _ <- notFollowedBy (oneOf "-}")+                         return (Str ""))+                     <|>+                     do _ <- string "!!"+                        return (Str ("")),+               end =+                 \ _ ->+                   do _ <- try (char '|') <|> ((string "{{!}}") >> return '|')+                      notFollowedBy (oneOf "-}|")+                      return (),+               allowed = [Wikitable], self = TableHeadColSep}+ +{-DHUN| parses a header column separator without anything inside it DHUN-}+ +headcolsepp2 :: MyParser Char+headcolsepp2+  = baseParser{start =+                 \ _ ->+                   try+                     (do _ <- string "\n"+                         skipMany (char ' ')+                         _ <- string "!"+                         _ <- notFollowedBy (oneOf "-}")+                         return (Str ""))+                     <|>+                     do _ <- string "!!"+                        return (Str ""),+               allowed = [Wikitable], self = TableHeadColSep}+ +{-DHUN| matches a key value pair . So an attribute of an HTML element DHUN-}+ +attr :: GenParser Char () ([Char], [Char])+attr+  = do skipMany1 (oneOf " \n")+       k <- many1 (try (alphaNum) <|> oneOf ":-")+       v <- try+              (do skipMany (oneOf " \n")+                  _ <- char '='+                  skipMany (oneOf " \n")+                  vv <- try+                          (do _ <- try (char '"')+                              vvv <- many (noneOf "\"><")+                              _ <- try (char '"') <|> try (noneOf "<|>") <|> return ' '+                              return vvv)+                          <|>+                          try+                            (do _ <- (char '\'')+                                vvv <- many (noneOf "'><")+                                _ <- try (char '\'') <|> try (noneOf "<|>") <|> return ' '+                                return vvv)+                          <|>+                          (do vvv <- many (noneOf "\"'></| ")+                              _ <- try (char '\'') <|> try (char '"') <|> try (noneOf "</|> ")+                                     <|> return ' '+                              return vvv)+                  return vv)+              <|> pzero+       return (k, v)+ +{-DHUN| Matches a key value pair. So an attribute of an HTML element DHUN-}+ +attrns :: GenParser Char u ([Char], [Char])+attrns+  = do k <- many1 (try (alphaNum) <|> oneOf ":-")+       v <- do _ <- char '='+               skipMany (oneOf " \n")+               vv <- try+                       (do _ <- try (char '"') <|> char '\''+                           vvv <- many (noneOf "\"'><|")+                           _ <- try (char '"') <|> try (noneOf "<|>") <|> return ' '+                           return vvv)+                       <|>+                       (do vvvv <- (noneOf "\"'></| =")+                           vvv <- many (noneOf "\"'></| ")+                           _ <- try (char '"') <|> try (char '\'') <|> try (noneOf "</|> ")+                                  <|> return ' '+                           return (vvvv : vvv))+               return vv+       _ <- try (many (oneOf " \n")) <|> return []+       return (k, v)+ +{-DHUN| Matches a list of key value pairs . So all attributes of an HTML element DHUN-}+ +attrp :: MyParser Char+attrp+  = baseParser{start =+                 \ _ ->+                   do atr <- try (attrns)+                      return (Attr atr),+               allowed = [TableHeadColSep, TableColSep, TableCap],+               self = Attribute}+ +{-DHUN| Parses the HTML 'pre' tag DHUN-}+ +prep :: MyParser Char+prep+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<"+                      p <- try (string "pre") <|> try (string "PRE") <|>+                             try (string "xmp")+                             <|> string "XMP"+                      atr <- many (try (attr))+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- char '>'+                      return (TagAttr p (Map.fromList atr)),+               end =+                 \ (TagAttr x _) ->+                   do _ <- char '<'+                      _ <- char '/'+                      _ <- string x+                      _ <- char '>'+                      return (),+               allowed = everywhere, self = Preformat}+ +{-DHUN| Parses the HTML 'br' tag DHUN-}+ +brparser :: MyParser Char+brparser+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<"+                      _ <- try (string "/") <|> return ""+                      _ <- try (string "br") <|> string ("BR")+                      skipMany (try (attr))+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- try (string "/") <|> return ""+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- char '>'+                      return (TagAttr "br" Map.empty),+               allowed = SpaceIndent : everywhere, self = Tag}+ +{-DHUN| Returns a Parser that matches all HTML elements, given by the list of strings given as first input parameter. The parser does not match inside tables. Use makettagparser for that DHUN-}+ +maketagparser :: [String] -> MyParser Char+maketagparser tags+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<"+                      t <- (oneOfTheStrings tags)+                      atr <- many (try (attr))+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- char '>'+                      return (TagAttr (t) (Map.fromList atr)),+               end =+                 \ (TagAttr x _) ->+                   do _ <- char '<'+                      _ <- try (many (oneOf " ")) <|> return []+                      _ <- if x `elem` nonNestTags then try (char '/') <|> (return '/')+                             else (char '/')+                      _ <- string x+                      _ <- char '>'+                      return (),+               allowed = SpaceIndent : everywheretbl, self = Tag}+ +{-DHUN| Parser for the 'meta' tag of HTML DHUN-}+ +metatagparser :: MyParser Char+metatagparser+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<"+                      t <- (oneOfTheStrings ["meta"])+                      atr <- many (try (attr))+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- try (char '/') <|> (return '/')+                      _ <- try (char '>') <|> (return '>')+                      return (TagAttr (t) (Map.fromList atr)),+               allowed = SpaceIndent : everywhere, self = Tag}+ +{-DHUN| Parser for the !DOCTYPE tag of HTML DHUN-}+ +doctagparser :: MyParser Char+doctagparser+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<"+                      t <- (oneOfTheStrings ["!DOCTYPE"])+                      _ <- many (noneOf ">")+                      _ <- char '>'+                      return (TagAttr (t) (Map.fromList [])),+               allowed = SpaceIndent : everywhere, self = Tag}+ +{-DHUN| Parser for closing HTML tags that have not matching opening tag. DHUN-}+ +ctagparser :: [String] -> GenParser Char () ()+ctagparser tags+  = do _ <- string "</"+       _ <- (oneOfTheStrings tags)+       _ <- try (many (oneOf " \n")) <|> return []+       _ <- char '>'+       return ()+ +{-DHUN| Returns a parser that matches all HTML elements, given by the list of strings given as first input parameter. The parser matches only the opening part of the tag. The inside of it is not processed by this parser. The opening tag may also self closing like <br/> because of the tailing /. DHUN-}+ +maketagparser2 :: [String] -> MyParser Char+maketagparser2 tags+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<"+                      t <- (oneOfTheStrings tags)+                      atr <- many (try (attr))+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- try (char '/') <|> (return '/')+                      _ <- char '>'+                      return (TagAttr (t) (Map.fromList atr)),+               allowed = Wikitable : SpaceIndent : everywheretbl, self = Tag}+ +{-DHUN| Returns a parser that matches all HTML elements, given by the list of strings given as first input parameter. The parser matches only the opening part of the tag. The inside of it is not processed by this parser. The opening tag may not be self closing so not like <br/> because of the tailing /. DHUN-}+ +maketagparser3 :: [String] -> MyParser Char+maketagparser3 tags+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<"+                      t <- (oneOfTheStrings tags)+                      atr <- many (try (attr))+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- char '>'+                      return (TagAttr (t) (Map.fromList atr)),+               allowed = SpaceIndent : everywheretbl, self = Tag}+ +{-DHUN| tags that can not be nested and are thus allowed to closed by an opening tag instead of a closing one DHUN-}+ +nonNestTags :: [String]+nonNestTags+  = ["tt", "pre", "TT", "PRE", "b", "B", "i", "I", "sc", "SC",+     "code", "CODE"]+ +{-DHUN| Returns a parser that matches all HTML elements, given by the list of strings given as first input parameter. The parser matches only inside tables. Use maketagparser for that DHUN-}+ +makettagparser :: [String] -> MyParser Char+makettagparser tags+  = baseParser{bad =+                 \ _ ->+                   do _ <- lookAhead (do try (string "\n|") <|> (string "||"))+                      return (),+               start =+                 \ _ ->+                   do _ <- string "<"+                      t <- (oneOfTheStrings tags)+                      atr <- many (try (attr))+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- char '>'+                      return (TagAttr (t) (Map.fromList atr)),+               end =+                 \ (TagAttr x _) ->+                   do _ <- char '<'+                      _ <- try (many (oneOf " ")) <|> return []+                      _ <- if x `elem` nonNestTags then try (char '/') <|> (return '/')+                             else (char '/')+                      _ <- string x+                      _ <- char '>'+                      return (),+               allowed = [Wikitable], self = Tag}+ +{-DHUN| Returns a parser that matches all HTML elements, given by the list of strings given as first input parameter. The parser matches only the opening part of the tag. The inside of it is not processed by this parser. The opening tag may also self closing like <br/> because of the tailing /. Matches only inside tables DHUN-}+ +makettagparser2 :: [String] -> MyParser Char+makettagparser2 tags+  = baseParser{bad =+                 \ _ ->+                   do _ <- lookAhead+                             (do _ <- anyChar+                                 try (string "\n|") <|> (string "||"))+                      return (),+               start =+                 \ _ ->+                   do _ <- string "<"+                      t <- (oneOfTheStrings tags)+                      atr <- many (try (attr))+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- char '/'+                      _ <- char '>'+                      return (TagAttr (t) (Map.fromList atr)),+               allowed = [Wikitable], self = Tag}+ +{-DHUN| maketagparser for all HTML elements see documentation on function maketagparser DHUN-}+ +tagparser :: MyParser Char+tagparser = maketagparser listOfTags+ +{-DHUN| maketagparser for the 'pre' HTML tag see documentation on function maketagparser DHUN-}+ +tagparserp :: MyParser Char+tagparserp = maketagparser ["pre"]+ +{-DHUN| maketagparser for the HTML tags for HTML tables see documentation on function maketagparser DHUN-}+ +tagparsert :: MyParser Char+tagparsert+  = (maketagparser listOfTableTags){self = TableTag,+                                    reenv = const Tag}+ +{-DHUN| makettagparser for all HTML elements see documentation on function makettagparser DHUN-}+ +ttagparser :: MyParser Char+ttagparser = makettagparser listOfTags+ +{-DHUN| makettagparser for the 'pre' HTML tag see documentation on function makettagparser DHUN-}+ +ttagparserp :: MyParser Char+ttagparserp = makettagparser ["pre"]+ +{-DHUN| makettagparser for the HTML tags for HTML tables see documentation on function makettagparser DHUN-}+ +ttagparsert :: MyParser Char+ttagparsert+  = (makettagparser listOfTableTags){self = TableTag,+                                     reenv = const Tag}+ +{-DHUN| maketagparser2 for all HTML elements see documentation on function maketagparser2 DHUN-}+ +tagparser2 :: MyParser Char+tagparser2 = maketagparser2 listOfTags+ +{-DHUN| maketagparser2 for the 'pre' HTML tag see documentation on function maketagparser2 DHUN-}+ +tagparser2p :: MyParser Char+tagparser2p = maketagparser2 ["pre"]+ +{-DHUN| maketagparser2 for the HTML tags for HTML tables see documentation on function maketagparser2 DHUN-}+ +tagparser2t :: MyParser Char+tagparser2t+  = (maketagparser2 listOfTableTags){self = TableTag,+                                     reenv = const Tag}+ +{-DHUN| makettagparser2 for all HTML elements see documentation on function makettagparser2 DHUN-}+ +ttagparser2 :: MyParser Char+ttagparser2 = makettagparser2 listOfTags+ +{-DHUN| makettagparser2 for the 'pre' HTML tag see documentation on function makettagparser2 DHUN-}+ +ttagparser2p :: MyParser Char+ttagparser2p = makettagparser2 ["pre"]+ +{-DHUN| makettagparser2 for the HTML tags for HTML tables see documentation on function makettagparser2 DHUN-}+ +ttagparser2t :: MyParser Char+ttagparser2t+  = (makettagparser2 listOfTableTags){self = TableTag,+                                      reenv = const Tag}+ +{-DHUN| a parser for mediawiki source extension tags DHUN-}+ +tagparsers :: MyParser Char+tagparsers+  = (maketagparser ["source", "syntaxhighlight"]){self = Source}+ +{-DHUN| a parser for mediawiki source extension tags inside tables DHUN-}+ +ttagparsers :: MyParser Char+ttagparsers+  = (maketagparser ["source", "syntaxhighlight"]){self = Source,+                                                  allowed = [Wikitable]}+ +{-DHUN| a parser for HTML tables DHUN-}+ +mytablep :: MyParser Char+mytablep+  = (maketagparser ["table"]){self = TableTag,+                              reenv = const Wikitable,+                              allowed = Wikitable : SpaceIndent : everywheretbl}+ +{-DHUN| a parser for HTML table rows DHUN-}+ +mytrsepp :: MyParser Char+mytrsepp+  = (maketagparser3 ["tr"]){reenv = const TableRowSep,+                            allowed = everywhere}+ +{-DHUN| a parser for normal HTML table cells DHUN-}+ +mytcolsepp :: MyParser Char+mytcolsepp+  = (maketagparser3 ["td"]){reenv = const TableColSep,+                            allowed = everywhere}+ +{-DHUN| a parser for HTML table captions cells DHUN-}+ +mytcapp :: MyParser Char+mytcapp+  = (maketagparser ["caption"]){reenv = const TableCap,+                                allowed = everywhere}+ +{-DHUN| a parser for HTML table header cells, so th tags DHUN-}+ +mythcolsepp :: MyParser Char+mythcolsepp+  = (maketagparser3 ["th"]){reenv = const TableHeadColSep,+                            allowed = everywhere}+ +{-DHUN| a parser for HTML tables for html parse mode only DHUN-}+ +htmytablep :: MyParser Char+htmytablep = (maketagparser ["table"])+ +{-DHUN| a parser for HTML table rows for html parse mode only DHUN-}+ +htmytrsepp :: MyParser Char+htmytrsepp = (maketagparser ["tr"])+ +{-DHUN| a parser for normal HTML table cells for html parse mode only DHUN-}+ +htmytcolsepp :: MyParser Char+htmytcolsepp = (maketagparser ["td"])+ +{-DHUN| a parser for HTML table captions cells for html parse mode only DHUN-}+ +htmytcapp :: MyParser Char+htmytcapp = (maketagparser ["caption"])+ +{-DHUN| a parser for HTML table header cells, so th tags for html parse mode only DHUN-}+ +htmythcolsepp :: MyParser Char+htmythcolsepp = (maketagparser ["th"])+ +{-DHUN| a parser for closing HTML tags which don't have an opening partner. This parser is only allowed to match within itemization enumerations etc. DHUN-}+ +itagparser :: MyParser Char+itagparser+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<"+                      skipMany (char '/')+                      t <- (oneOfTheStrings ["small"])+                      atr <- many (try (attr))+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- char '>'+                      return (TagAttr (t) (Map.fromList atr)),+               allowed = [Itemgroup], self = Tag}+ +{-DHUN| a parser for closing HTML tags which don't have an opening partner DHUN-}+ +rtagparser :: MyParser Char+rtagparser+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<"+                      skipMany (char '/')+                      _ <- (oneOfTheStrings (listOfTags ++ listOfTableTags))+                      atr <- many (try (attr))+                      _ <- try (many (oneOf " \n")) <|> return []+                      _ <- char '>'+                      return (TagAttr "bad" (Map.fromList atr)),+               allowed = everywhere, self = Tag}+ +{-DHUN| a parser for HTML opening tags which might be self closing but never have a matching closing partner DHUN-}+ +stagparser :: MyParser Char+stagparser+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<"+                      t <- (oneOfTheStrings (listOfTags ++ listOfTableTags))+                      atr <- many (try (attr))+                      _ <- try (many (oneOf " ")) <|> return []+                      _ <- try (char '/') <|> return 'f'+                      _ <- char '>'+                      return (TagAttr t (Map.fromList atr)),+               self = Tag, allowed = []}+ +{-DHUN| a parser for HTML page breaks DHUN-}+ +pagebreakp :: MyParser Char+pagebreakp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<div style=\"page-break-before:always\"/>"+                      return (Str ""),+               end = \ _ -> return (), allowed = [Root], self = PageBreak}+ +{-DHUN| a parser for HTML comments DHUN-}+ +commentp :: MyParser Char+commentp+  = baseParser{start =+                 \ _ ->+                   do _ <- string "<!--"+                      return (Str ""),+               allowed = everywhere ++ [Tag, TemplateInsideVerbatim],+               end =+                 \ _ ->+                   do _ <- string "-->"+                      return (),+               self = Comment}+ +{-DHUN| a parser for mediawiki reserved words DHUN-}+ +reservedp :: MyParser Char+reservedp+  = baseParser{start =+                 \ _ ->+                   do s <- try (string "__NOTOC__") <|>+                             try (string "__NOEDITSECTION__")+                             <|> try (string "__notoc__")+                             <|> try (string "__TOC__")+                             <|> try (string "__Toc__")+                             <|> try (string "__INHALTSVERZEICHNIS__")+                             <|> try (string "__KEIN_INHALTSVERZEICHNIS__")+                             <|> try (string "__FORCETOC__")+                             <|> string "&nbsp;"+                      return (Str s),+               self = Reserved, allowed = SpaceIndent : everywhere}+ +{-DHUN| See documentation on evaluateItemgroup and itemParserLevelTwoDHUN-}+ +itemStartString :: Anything Char -> String+itemStartString (ItemStart x) = x : []+itemStartString _ = ""+ +{-DHUN| See documentation on evaluateItemgroup and itemParserLevelTwo DHUN-}+ +itemStopString :: Anything Char -> String+itemStopString (ItemStop x) = x : []+itemStopString _ = ""+ +{-DHUN| see documentation on evaluateItemgroup. Parser to parse the ItemStart and ItemStop elements which are essentially bracket into environments which are essentially nodes with children in the parse tree DHUN-}+ +itemParserLevelTwo :: MyParser (Anything Char)+itemParserLevelTwo+  = MyParser{bad = \ _ -> pzero,+             start =+               \ _ ->+                 do pos <- getPosition+                    z <- token show (\ _ -> pos)+                           (\ x -> if (itemStartString x == []) then Nothing else Just x)+                    return (Str (itemStartString z)),+             end =+               \ (Str y) ->+                 do pos <- getPosition+                    _ <- token show (\ _ -> pos)+                           (\ x -> if (itemStopString x == y) then Just x else Nothing)+                    return (),+             allowed = [Root, ItemEnv], self = ItemEnv, modify = \ _ x -> x,+             reenv = id}+ +{-DHUN| see documentation on evaluateItemgroup. helper function to generate a list of only opening or only closing brackets, that is ItemStart or ItemStop values. The string given as first parameter states which kinds of bracket shall be opened or closed. For Openning brackets you have to call this function ItemStart as second and True as third parameter. For closing brackets you have to use ItemStop and False DHUN-}+ +generateEnvironmentTagsHelper ::+                              String -> (Char -> Anything Char) -> Bool -> [Anything Char]+generateEnvironmentTagsHelper (c : cs) t b+  = if b then+      (t c) : ([Item c]) ++ (generateEnvironmentTagsHelper cs t b) else+      (generateEnvironmentTagsHelper cs t b) ++ [(t c)]+generateEnvironmentTagsHelper [] _ _ = []+ +{-DHUN| see documentation on evaluateItemgroup and insertEnvironmentTags. The first parameter is a string consisting of the characters #:* that is the begging of the last Itemline. The second is the same for the current ItemLine. This function return a list of ItemStart and ItemStop values for the difference between the first and the second parameter DHUN-}+ +generateEnvironmentTags :: String -> String -> [Anything Char]+generateEnvironmentTags (o : os) (n : ns)+  = if (o == n) then generateEnvironmentTags os ns else+      (generateEnvironmentTagsHelper (o : os) ItemStop False) +++        (generateEnvironmentTagsHelper (n : ns) ItemStart True)+generateEnvironmentTags (o : os) []+  = generateEnvironmentTagsHelper (o : os) ItemStop False+generateEnvironmentTags [] (n : ns)+  = generateEnvironmentTagsHelper (n : ns) ItemStart True+generateEnvironmentTags [] [] = []+ +{-DHUN| see documentation on evaluateItemgroup. The first parameter is a string consisting of the characters #:* that is the begging of the last Itemline. The second parameter is the content of an Itemgroup. This function returns the parse tree with the ItemStart and ItemStop values inserted   DHUN-}+ +insertEnvironmentTags ::+                      String -> [Anything Char] -> [Anything Char]+insertEnvironmentTags s ((Environment ItemLine (Str x) _) : xs)+  = (generateEnvironmentTags s x) +++      ((if+          (((length s) > (length x)) &&+             (if length (generateEnvironmentTags s x) > 0 then+                (case last (generateEnvironmentTags s x) of+                     Item _ -> False+                     _ -> True)+                else True)+               && (x /= ""))+            || (s == x)+          then [Item (last s)] else [])+         ++ insertEnvironmentTags x xs)+insertEnvironmentTags s (x : xs) = x : insertEnvironmentTags s xs+insertEnvironmentTags _ [] = []+ +{-DHUN| see documentation on evaluateItemgroup. Inserts the ItemStart and ItemStop values as preparation for running the second level parse on the content of an ItemGroup. The first pararmenter is a string consisting of the characters #:* that is the begging of the first Itemline. The second parameter is the content of an Itemgroup. This function returns the parse tree with the ItemStart and ItemStop values inserted  DHUN-}+ +toEnvironmentTags :: String -> [Anything Char] -> [Anything Char]+toEnvironmentTags s l+  = insertEnvironmentTags ""+      ((Environment ItemLine (Str s) []) :+         l ++ [(Environment ItemLine (Str "") [])])+ +{-DHUN| see documentation on evaluateItemgroup. Get the second level parse result, back to the first level parse result DHUN-}+ +convertFromParsingLevelTwoToLevelOne ::+                                     [Anything (Anything Char)] -> [Anything Char]+convertFromParsingLevelTwoToLevelOne ((C x) : xs)+  = x : convertFromParsingLevelTwoToLevelOne xs+convertFromParsingLevelTwoToLevelOne ((Environment Root _ x) : xs)+  = (convertFromParsingLevelTwoToLevelOne x) +++      (convertFromParsingLevelTwoToLevelOne xs)+convertFromParsingLevelTwoToLevelOne+  ((Environment ItemEnv s l) : xs)+  = (Environment ItemEnv s+       (findMatchingBrackets3 ((convertFromParsingLevelTwoToLevelOne l))))+      : convertFromParsingLevelTwoToLevelOne xs+convertFromParsingLevelTwoToLevelOne (_ : xs)+  = (convertFromParsingLevelTwoToLevelOne xs)+convertFromParsingLevelTwoToLevelOne [] = []+ +{-DHUN| see documentation on evaluateItemgroup. Runs the parser itemParserLevelTwo on the inner part of an ItemGroup DHUN-}+ +runItemGroupPraserLevelTwo ::+                           GenParser (Anything Char) () [Anything (Anything Char)] ->+                             [Anything Char] -> [Anything (Anything Char)]+runItemGroupPraserLevelTwo p input+  = case (parse p "" input) of+        Left _ -> []+        Right x -> x+ +{-DHUN| this is for parsing itemization. It is implemented as two step process in the first step Itemgroup is created with ItemLine s in it. And ItemLine is a line starting with any combination of *#: . And Itemgroup is a sequence of lines of that kind. After this is done this function gets called with the content of an itemgroup. In the second step ItemStart and ItemStop elements are created, those are essentially the bracketed of the opening an closing part of the enumerations itemizations etc. . The function toEnvironmentTags does the insertion of the ItemStop and ItemStart values and remove the ItemLine values. parseAnything2 is run on it using the itemParserLevelTwo. This is turned into the parse tree by being passed to decon2 and put out of the parser monad by runItemGroupPraserLevelTwo. The resulting parse tree is one of type [Anything (Anything Char)] this needs to be but one level down to [Anything Char] this is done be convertFromParsingLevelTwoToLevelOne. The first parameter is a string consisting of the characters #:* that is the begging of the first Itemline. The second parameter is the content of an Itemgroup  DHUN-}+ +evaluateItemgroup :: String -> [Anything Char] -> [Anything Char]+evaluateItemgroup s l+  = convertFromParsingLevelTwoToLevelOne+      (runItemGroupPraserLevelTwo+         (decon2 (remake [itemParserLevelTwo])+            (parseAnything2+               [MyStackFrame{endparser = pzero, startdata = Str "",+                             environment = Root, badparser = \ _ -> pzero, parsernumber = 0,+                             nestingdepth = 0}]+               (remake [itemParserLevelTwo])+               []))+         (toEnvironmentTags s l))+ +{-DHUN| a parser for a group of lines starting with one of *:;# representing in enumeration itemization etc. . This particular parser is allowed to match nearly everywhere DHUN-}+ +itempgroupp :: MyParser Char+itempgroupp+  = MyParser{bad = \ _ -> pzero,+             start =+               \ _ ->+                 (do _ <- string "\n"+                     a <- many1 (oneOf ['*', ':', ';', '#'])+                     return (Str a)),+             end =+               \ _ ->+                 lookAhead+                   (try+                      (do _ <- string "\n"+                          notFollowedBy ((oneOf ['*', ':', ';', '#'])))),+             allowed = [Root, Wikitable, TemplateInside, Tag], self = Itemgroup,+             modify = \ (Str x) -> evaluateItemgroup x, reenv = id}+ +{-DHUN| a parser for a group of lines starting with one of *:;# representing in enumeration itemization etc. . This particular parser is only allowed to match within templates DHUN-}+ +itempgrouppt :: MyParser Char+itempgrouppt+  = MyParser{bad = \ _ -> pzero,+             start =+               \ _ ->+                 do _ <- string "\n"+                    a <- many1 (oneOf ['*', ':', ';', '#'])+                    return (Str a),+             end =+               \ _ ->+                 (try (lookAhead (string "}}") <|> (lookAhead (string "\n|"))) >>+                    return ()),+             allowed = [TemplateInside], self = Itemgroup,+             modify = \ (Str x) -> evaluateItemgroup x, reenv = id}+ +{-DHUN| a parser for a preformat created by indenting with space DHUN-}+ +presectionp :: MyParser Char+presectionp+  = MyParser{bad = \ _ -> try (string "}}") >> (return ()),+             start =+               \ _ ->+                 do _ <- string "\n"+                    _ <- char ' '+                    return (Str ""),+             end =+               \ _ ->+                 lookAhead+                   (do _ <- string "\n"+                       notFollowedBy (char ' ')),+             allowed = [Root, TemplateInside, Tag], self = SpaceIndent,+             modify = \ _ x -> (C ' ') : x, reenv = id}+ +{-DHUN| a parser for a line starting with one of *:;# representing in enumeration itemization etc. DHUN-}+ +itemlinep :: MyParser Char+itemlinep+  = MyParser{bad = \ _ -> pzero,+             start =+               \ _ ->+                 do _ <- string "\n"+                    a <- many1 (oneOf ['*', ':', ';', '#'])+                    return (Str a),+             end = \ _ -> (return ()), allowed = [Itemgroup], self = ItemLine,+             modify = \ _ x -> x, reenv = id}
+ src/MyState.hs view
@@ -0,0 +1,88 @@+{-DHUN| A module for mutable states used in the programm DHUN-}+module MyState where+import qualified Data.Map as Map+import Data.Map (Map)+import Control.Monad.Trans.State (State)+import MediaWikiParseTree+import BaseFont+ +{-DHUN| a type used as mutable state while processing a table. See documentation of the TableHelper module DHUN-}+ +data TableState = TableState{rowCounter :: Int,+                             inputLastRowOfHeader :: Int, outputLastRowOfHeader :: Int,+                             outputTableHasHeaderRows :: Bool,+                             lastRowHadEmptyMultiRowMap :: Bool, isFirstRow :: Bool,+                             lastCellWasHeaderCell :: Bool, stillInTableHeader :: Bool,+                             currentColumn :: Int, multiRowMap :: Map Int (Int, Int),+                             numberOfColumnsInTable :: Int, lastCellWasMultiRow :: Bool,+                             seperatingLinesRequestedForTable :: Bool,+                             currentRowIsHeaderRow :: Bool,+                             lastCellWasNotFirstCellOfRow :: Bool, columnsWidthList :: [Float],+                             lastCellWasMultiColumn :: Bool, activeColumn :: Maybe Int}+ +{-DHUN| see documentation of the makeLables function in WikiHelper module DHUN-}+ +data UrlState = UrlState{iUrlState :: Int, sUrlState :: String,+                         mUrlState :: Map String String}+              deriving (Show, Eq, Read)+ +{-DHUN| see initial value of the type UrlState DHUN-}+ +initialUrlState :: UrlState+initialUrlState+  = UrlState{iUrlState = 0, sUrlState = "", mUrlState = Map.empty}+ +{-DHUN a type used as mutable state during the course of the LaTeXRederer DHUN-}+ +data MyState = MyState{getImages :: [String], getJ :: Int,+                       getF :: Float, getC :: Int, getInTab :: Int, getInGallery :: Bool,+                       getInFootnote :: Bool, getInHeading :: Bool, getInCenter :: Bool,+                       getInCode :: Bool, getTitle :: String,+                       templateMap :: Map String [String], urls :: Map String String,+                       urld :: WikiUrlData, getGalleryNumbers :: [Integer],+                       currentUrl :: String, fndict :: Map String [Anything Char],+                       tablist :: [[String]], tabmap :: Map Int (Map Int Double),+                       fontStack :: [FontStyle], font :: Font}+             deriving (Show, Eq)+ +{-DHUN| Renderer is the State monad using MyState as mutable state DHUN-}+ +type Renderer = State MyState+ +{-DHUN| the initial value for MyState DHUN-}+ +initialState :: MyState+initialState+  = MyState{getImages = [], getJ = 1, getF = 1, getC = 1,+            getInTab = 0, getInGallery = False, getInFootnote = False,+            getInHeading = False, getInCenter = False, getInCode = False,+            getTitle = "", templateMap = Map.fromList [], urls = Map.empty,+            urld = BaseUrl (WikiBaseUrl ""), getGalleryNumbers = [],+            currentUrl = "", fndict = Map.empty, tablist = [],+            tabmap = Map.empty,+            fontStack =+              [FontStyle{stylebase = Normal, bold = False, italic = False}],+            font = ComputerModernRoman}+ +{-DHUN| represents an URL to a wiki (not to a page thereof), which is not a sister project of wikipedia, so not wikibooks wikisource, etc. DHUN-}+ +data WikiBaseUrl = WikiBaseUrl{baseUrl :: String}+                 deriving (Show, Eq)+ +{-DHUN| represents an URL to a wiki (not to a page thereof), which is a sister project of wikipedia, so wikibooks wikisource, etc. DHUN-}+ +data WikiUrlInfo = WikiUrlInfo{language :: String,+                               wikitype :: String}+                 deriving (Show, Eq)+ +{-DHUN| represents an URL to a wiki (not to a page thereof), which is either a sister project of wikipedia, so wikibooks wikisource, etc. or isn't a sister project of wikipedia DHUN-}+ +data WikiUrlData = BaseUrl WikiBaseUrl+                 | UrlInfo WikiUrlInfo+                 deriving (Show, Eq)+ +{-DHUN| represents an URL to a page on a wiki DHUN-}+ +data WikiLinkInfo = WikiLinkInfo{urldata :: WikiUrlData,+                                 page :: String}+                  deriving (Show, Eq)
+ src/TableHelper.hs view
@@ -0,0 +1,378 @@+{-DHUN| helper functions to convert tables from the parse tree notation to the latex notation DHUN-}+module TableHelper where+import MediaWikiParseTree+import Tools+import Text.Printf+import Data.Char+import qualified Data.Map as Map+import Data.Map (Map)+import Data.Maybe+import Control.Monad+import MyState+ +{-DHUN| the width of a columns as float wrapped in a Just value of the maybe monad if it could be determined. Return the value Nothing of the maybe monad otherwise. The only parameter is of part of the parse tree that describe the opening part of the table cell element. DHUN-}+ +widthOfColumn :: [Anything Char] -> Maybe Float+widthOfColumn = msum . (map f)+  where f (Environment Attribute (Attr (k, v)) _)+          = listToMaybe $+              do (z, _) <- reads v+                 guard (k == "width")+                 guard ('%' `elem` v)+                 return (1.0e-2 * z)+        f _ = Nothing+ +columnMultiplicityForSimple :: [Anything Char] -> Int+columnMultiplicityForSimple x+  = case columnMultiplicity x of+        Just a -> a+        _ -> -1+ +raggedArrayOfWidths ::+                    [Anything Char] -> [Maybe Float] -> [[Maybe Float]]+raggedArrayOfWidths ((Environment TableRowSep _ _) : xs) temp+  = if temp == [] then raggedArrayOfWidths xs [] else+      temp : (raggedArrayOfWidths xs [])+raggedArrayOfWidths ((Environment TableColSep _ x) : xs) temp+  = (raggedArrayOfWidths xs+       (temp +++          [widthOfColumn x] +++            (concat+               (replicate ((columnMultiplicityForSimple x) - 1) [Nothing]))))+raggedArrayOfWidths ((Environment TableHeadColSep _ x) : xs) temp+  = (raggedArrayOfWidths xs+       (temp +++          [widthOfColumn x] +++            (concat+               (replicate ((columnMultiplicityForSimple x) - 1) [Nothing]))))+raggedArrayOfWidths (_ : xs) temp = (raggedArrayOfWidths xs temp)+raggedArrayOfWidths [] temp = [temp]+ +numberOfColumns :: [Anything Char] -> Int+numberOfColumns a+  = (maximum ([length x | x <- (raggedArrayOfWidths a [])]))+ +initialListofWidths :: [Anything Char] -> [Maybe Float]+initialListofWidths x = replicate (numberOfColumns x) Nothing+ +listMax :: [Maybe Float] -> [Maybe Float] -> [Maybe Float]+listMax (Just x : xs) (Just y : ys)+  = Just (max x y) : listMax xs ys+listMax (x : xs) (y : ys) = (x `mplus` y) : listMax xs ys+listMax [] (y : ys) = y : listMax [] ys+listMax (x : xs) [] = x : listMax xs []+listMax [] [] = []+ +preliminaryWidths ::+                  [[Maybe Float]] -> [Maybe Float] -> [Maybe Float]+preliminaryWidths l k = foldl (listMax) k l+ +standardColumnWitdh :: [Anything Char] -> Maybe Float+standardColumnWitdh a+  = if columns > columnsWithDefinedWidth then+      if sumOfDefinedWidths > 1.0 then Nothing else+        Just $+          (1.0 - sumOfDefinedWidths) /+            fromIntegral (columns - columnsWithDefinedWidth)+      else if sumOfDefinedWidths > 1.001 then Nothing else Just 0.0+  where l = rawWidths a+        columns = numberOfColumns a+        columnsWithDefinedWidth = length (filter isJust l)+        sumOfDefinedWidths = sum (map fromJust (filter isJust l))+ +rawWidths :: [Anything Char] -> [Maybe Float]+rawWidths a+  = (preliminaryWidths (raggedArrayOfWidths a [])+       (initialListofWidths a))+ +{-DHUN fallback function for the width of columns if the precompilation procedure for the width of columns is not available yet. So particularly when the precompilation is just running. Takes the parse tree representation of the table as first input parameter. Returns the list of widths of the columns. I am not documenting its subfunctions since the final width of the columns don't have anything to do with the width calculated here, still these preliminary widths are needed for the precompilation procedure DHUN-}+ +columnWidths :: [Anything Char] -> [Float]+columnWidths a = w+  where l = rawWidths a+        m = numberOfColumns a+        mf = fromIntegral m+        f = 1.0 - (scalefactor mf)+        w = fromMaybe (concat (replicate m [f / mf])) $+              do ww <- standardColumnWitdh a+                 return [x * f | x <- map (fromMaybe ww) l]+ +{-DHUN| part of the correction calculation for the space between columns inside a table. Takes the number of columns as first input parameter returns a scaling factor DHUN-}+ +scalefactor :: (Fractional a, Ord a) => a -> a+scalefactor n | n <= 10 = 18.0 * (n) / 448.0+scalefactor _ = 12.8 * (11.0) / 448.0+ +{-DHUN| part of the correction calculation for the space between columns inside a table. Takes the number of columns as first input parameter returns a scaling factor DHUN-}+ +tableScale :: Int -> Float+tableScale nColumns = (1.0 / n) * (1.0 - (scalefactor n))+  where n = fromIntegral nColumns+ +{-DHUN| returns the latex environment name for a table environments. It the float passes as first parameter it 1.0 the result is longtable, otherwise it is tabular. This function is usually called with the width of the current cell in units of the line width as first parameter. Outside any table this value is 1.0 inside a table it is always smaller than 1.0. So this function will return tabular in case of a nested table, which is necessary since longtables can not be nested inside other longtables, but tabulars can be nested within longtables as well as tabulars. DHUN-}+ +tableEnvironment :: Float -> String+tableEnvironment 1.0 = "longtable"+tableEnvironment _ = "tabular"+ +innerTableSpecifier :: [Float] -> String -> String+innerTableSpecifier (f : xs) t+  = ">{\\RaggedRight}p{" +++      (printf "%0.5f" f) +++        "\\linewidth}" ++ t ++ (innerTableSpecifier xs t)+innerTableSpecifier [] _ = []+ +{-DHUN| Returns the table header which represents the width of the columns of a table in units of the line width.  It takes a list of width as second parameter. It is understood that necessary correction for the width to compensate for the space needed by separations of columns have already been applied. The is the first boolean parameter is true rules will be drawn in the table, otherwise they won't. See also documentation of the wdth3 function in the module LatexRenderer.  DHUN-}+ +tableSpecifier :: Bool -> [Float] -> String+tableSpecifier True f = '|' : (innerTableSpecifier f "|")+tableSpecifier False f = (innerTableSpecifier f "")+ +{-DHUN| Takes the multirowmap as first input parameter. See documentation on the function multiRowDictChangeStart in this module for details on the multirowmap. It returns true if there are currently no multirow cells active in the given multirowdict DHUN-}+ +myempty :: Map Int (Int, Int) -> Bool+myempty d = [x | x <- Map.toList d, (fst (snd x)) /= 0] == []+ +{-DHUN| takes the string found in the header symbol of a table or the opening tag of the html table tag. That is the place where the attributes are, but only understood as string so without parsing the attributes as map, and returns a boolean. It this boolean is true the rules of the table need to be drawn, otherwise they must not be drawn DHUN-}+ +seperatingLinesRequested :: String -> Bool+seperatingLinesRequested s+  = (isInfixOf2 "Prettytable" (map toLower s)) ||+      (isInfixOf2 "prettytable" (map toLower s)) ||+        (isInfixOf2 "wikitable" (map toLower s))+ +{-DHUN| returns the latex symbol for a horizontal line on the last row of a table, that is a horizontal rule, if the first boolean parameter is true, otherwise the empty string is returned. This function is usually being called with the first parameter indicating whether or not rules should be drawn with the table DHUN-}+ +rowDelimiter :: Bool -> String+rowDelimiter True = "\\\\ \\hline"+rowDelimiter False = ""+ +{-DHUN| returns the latex symbol for a horizontal line in a table, that is a horizontal rule, if the first boolean parameter is true, otherwise the empty string is returned. This function is usually being called with the first parameter indicating whether or not rules should be drawn with the table DHUN-}+ +horizontalLine :: Bool -> String+horizontalLine True = " \\hline"+horizontalLine False = ""+ +{-DHUN| return the latex symbol for a partly drawn  inner horizontal line in a table, that is a horizontal rule. It has to be drawn only partly since multirow cells intersect with it.  The second parameter is the multirowmap (the documentation on the function multiRowDictChangeStart in this module for details). The third parameter is the total number of columns in the table. The first parameter is a and index that is incremented during the course of this function and has to be 1 when called this function from outside DHUN-}+ +makeCLines :: Int -> Map Int (Int, Int) -> Int -> [Char]+makeCLines m d t+  = if m <= t then+      fromMaybe def $+        do (a, b) <- Map.lookup m d+           guard (a /= 0)+           return $ makeCLines (m + (if b > 0 then b else 1)) d t+      else ""+  where def+          = "\\cline{" +++              (show m) ++ "-" ++ (show m) ++ "}" ++ (makeCLines (m + 1) d t)+ +{-DHUN| return the latex symbol for an inner horizontal line in a table, that is a horizontal rule. If the first boolean parameter is true the rule is drawn otherwise it is not. If multirow cells interfere with this rule the rule is only drawn in parts as required. The second parameter is the multirowmap (the documentation on the function multiRowDictChangeStart in this module for details). The third parameter is the total number of columns in the table DHUN-}+ +innerHorizontalLine :: Bool -> Map Int (Int, Int) -> Int -> String+innerHorizontalLine b d m+  = if b then+      if myempty d then horizontalLine True else ' ' : makeCLines 1 d m+      else ""+ +{-DHUN| the symbol in latex for separating columns. It is returned if the fist boolean parameter is true otherwise the empty string is returned. This function is usually called with the first parameter being true if the current column was not the first column of a row since the symbol is not needed before the start of the first column of a row. This is a contrast to html where the first cell of a row has its own td or th tag. The mediawiki markup notation is similar to html in this respect. DHUN-}+ +columnSeperator :: Bool -> String+columnSeperator True = "&"+columnSeperator False = ""+ +{-DHUN| takes the parse result of the attributes of a th tag or td tag or a corresponding header column separator or column separator as second parameter. It takes a key for this map of attributes as string as first parameter. If the key is present in the map, and the value found in the map at that key can be parsed as an Integer that integer is returned. If no value for the key could be found in the map or it could not be parsed as an integer the value Nothing of the Maybe monad is returned. DHUN-}+ +genMultiplicity :: String -> [Anything Char] -> Maybe Int+genMultiplicity s = msum . (map f)+  where f (Environment Attribute (Attr (k, v)) _)+          = listToMaybe $+              do (z, _) <- reads v+                 guard (k == s)+                 return z+        f _ = Nothing+ +{-DHUN| takes the parse result of the attributes of a th tag or td tag or a corresponding header column separator or column separator as second parameter. It takes a key for this map of attributes as string as first parameter. It returns a result of the lookup of the key in the map (so the value). as string wrapped into the Maybe monad. If no value for the key could be found in the map it returns the value Nothing of the Maybe monad. DHUN-}+ +genLookup :: String -> [Anything Char] -> Maybe String+genLookup s = msum . (map f)+  where f (Environment Attribute (Attr (k, v)) _)+          = listToMaybe $+              do return ()+                 guard (k == s)+                 return v+        f _ = Nothing+ +{-DHUN| the column multiplicity of the current cell. The first parameter is the parse result of the inner part of the column separator of header column separator, that corresponds to the attributes of the th or td html elements. The result is an integer wrapped into the maybe monad. The value Nothing of the Maybe monad is returned if the attribute colspan is not present (or did not have a value parseable as Integer) within the first parameter DHUN-}+ +columnMultiplicity :: [Anything Char] -> Maybe Int+columnMultiplicity = genMultiplicity "colspan"+ +{-DHUN| the row multiplicity of the current cell. The first parameter is the parse result of the inner part of the column separator of header column separator, that corresponds to the attributes of the th or td html elements. The result is an integer wrapped into the maybe monad. The value Nothing of the Maybe monad is returned if the attribute rowspan is not present (or did not have a value parseable as Integer) within the first parameter DHUN-}+ +rowMultiplicity :: [Anything Char] -> Maybe Int+rowMultiplicity = genMultiplicity "rowspan"+ +{-DHUN| the column multiplicity of the current cell. The first parameter is the parse result of the inner part of the column separator of header column separator, that corresponds to the attributes of the th or td html elements.The result is an integer that default to zero DHUN-}+ +columnMultiplicityForCounting :: [Anything Char] -> Int+columnMultiplicityForCounting = (fromMaybe 1) . columnMultiplicity+ +{-DHUN| return the symbol for the start of a multicolumn cell in latex. The first parameter is the parse result of the inner part of the column separator of header column separator, that corresponds to the attributes of the th or td html elements. It takes the list of the final widths of all columns of the table as second parameter. It takes to the column index of the current column as third parameter. The fourth parameter is a boolean if it is true rules will be drawn in the table otherwise they won't. The fifth parameter is the table state. That is the mutable state that exists during rendering of a table. DHUN-}+ +multiColumnStartSymbol ::+                       [Anything Char] -> [Float] -> Int -> Bool -> TableState -> String+multiColumnStartSymbol l f i t st+  = fromMaybe "" $+      do n <- columnMultiplicity l+         return $ "\\multicolumn{" ++ (show n) ++ "}{" ++ (spec n) ++ "}{"+  where spec mm+          = case activeColumn st of+                Nothing -> tableSpecifier t (mylist mm)+                _ -> "l"+        mylist nn+          = [min 1.0+               ((1.0 - (scalefactor 1.0)) * (sum (take nn (drop (i - 1) f))))+               / (1.0 - (scalefactor (fromIntegral nn)))]+ +{-DHUN| return the symbol for the end of a multicolumn cell in latex. The first boolean parameter tells if the cell is actually a multicolumn cell. If it is false the empty string is returned instead DHUN-}+ +multiColumnEndSymbol :: Bool -> String+multiColumnEndSymbol True = "}"+multiColumnEndSymbol False = ""+ +{-DHUN| return the symbol for the end of a multirow cell in latex. The first boolean parameter tells if the cell is actually a multirow cell. If it is false the empty string is returned instead DHUN-}+ +multiRowEndSymbol :: Bool -> String+multiRowEndSymbol True = "}"+multiRowEndSymbol False = ""+ +{-DHUN| This function takes a default value as first parameter. It takes a predicate as second parameter. It take a map from Int to a two tuple of Int as firth parameter. It takes a key for that map as fourth parameter. It takes a function mapping a two tuple of Int to the same type as the default value as third parameter. It tries to find a two tuple of Ints (that is value) in the map under the given key. If it finds one and the predicate returns true on the first element of that two tuple it returns the result of the function on the two tuple. In any other case it returns the default value DHUN-}+ +withDefault ::+            t ->+              (Int -> Bool) ->+                (Int -> Int -> t) -> Int -> Map Int (Int, Int) -> t+withDefault def p f i d+  = fromMaybe def $+      do (a, b) <- Map.lookup i d+         guard $ p a+         return $ f a b+ +{-DHUN| this function return the vertical separator for column for the table header in latex. The only parameter is a boolean. If it is true rules will be drawn in the table, otherwise they won't DHUN-}+ +verticalSeperator :: Bool -> [Char]+verticalSeperator True = "|"+verticalSeperator False = ""+ +{-DHUN| the function returns the a string to be inserted into a latex document for multirows at a when a new column (that is a new cell) starts, thats when a column separator, or header column separator is encountered. The first parameter it the index of the current column. The second parameter is the multirowdict (see documentation of the multiRowDictChangeStart function in this module). The third parameter is a boolean. If it is true rules will be drawn in the table, otherwise they won't DHUN-}+ +multiRowSymbol :: Int -> Map Int (Int, Int) -> Bool -> String+multiRowSymbol i d t+  = withDefault "" (> 0)+      (\ _ b ->+         "\\multicolumn{" +++           (show b) +++             "}{" +++               (verticalSeperator t) +++                 "c" +++                   (verticalSeperator t) ++ "}{}&" ++ (multiRowSymbol (i + b) d t))+      i+      d+ +{-DHUN| the function returns the a string to be inserted into a latex document for multirows at a when a new row starts, thats when a row separator is encountered. The first parameter it the index of the current column. The second parameter is the multirowdict (see documentation of the multiRowDictChangeStart function in this module). The third parameter is a boolean. If it is true rules will be drawn in the table, otherwise they won't DHUN-}+ +multiRowSymbolForRowSep ::+                        Int -> Map Int (Int, Int) -> Bool -> String+multiRowSymbolForRowSep i d t+  = withDefault "" (> 0)+      (\ _ b ->+         "&\\multicolumn{" +++           (show b) +++             "}{" +++               (verticalSeperator t) +++                 "c" +++                   (verticalSeperator t) +++                     "}{}" ++ (multiRowSymbolForRowSep (i + b) d) t)+      i+      d+ +{-DHUN| the function returns the a string to be inserted into a latex document for multirows at the end of the table. The first parameter it the index of the current column. The second parameter is the multirowdict (see documentation of the multiRowDictChangeStart function in this module). The third parameter is a boolean. If it is true rules will be drawn in the table, otherwise they won't DHUN-}+ +multiRowSymbolForTableEnd ::+                          Int -> Map Int (Int, Int) -> Bool -> String+multiRowSymbolForTableEnd i d t+  = withDefault "" (> 0)+      (\ _ b ->+         "&\\multicolumn{" +++           (show b) +++             "}{" +++               (verticalSeperator t) +++                 "c" +++                   (verticalSeperator t) +++                     "}{}" ++ (multiRowSymbolForTableEnd (i + 1) d t))+      i+      d+ +{-DHUN| in case of a multirow, that cell has to be skipped further down. So if I got a multirow in row 1 column 2 with a rowspan of 2 or more I need to expand row 2 column 1 by 1 . So if I passed row 2 column one I am not in row 2 column 2 since that is where the multirow cell resides, I am rather in row 2 cell 3. And if there are more multicolumns involved I am more possible even further right. So this function just tell me how many cells I have to skip. The first parameter is the index of the current column. The second parameter is the multirowdict. See also documentation on the function multiRowDictChangeStart in this module  DHUN-}+ +multiRowCount :: Int -> Map Int (Int, Int) -> Int+multiRowCount i d+  = withDefault 0 (/= 0) (\ _ b -> b + (multiRowCount (i + 1) d)) i d+ +{-DHUN| see documentation on multiRowDictChangeStart. This function take the index of the current column as first parameter. This function takes the multiRowDict as first parameter and returns the modified version of it. DHUN-}+ +multiRowDictChangeEnd ::+                      Int -> Map Int (Int, Int) -> Map Int (Int, Int)+multiRowDictChangeEnd i d+  = withDefault d (/= 0)+      (\ a b ->+         multiRowDictChangeEnd (i + 1) (Map.insert i (a - 1, b) d))+      i+      d+ +{-DHUN| The multiRowDict is a facility for keeping track of cells spanning multiple rows. It is stored as mutable state in the type TableState in the parameter multiRowMap. It is passed to this function as second parameter. This function return an updated version of it. It is a map mapping and Int to a tuple whose both elements are also ints. It the key is the column index and the value is a pair (rowmultiplicity, columnmultiplicity). The rowmultiplicity is the number of rows the cell spans. This number is decrease every time a row ends. So it actually says how many rows the columns spans further down from the current column. The column multiplicity is the number of columns the cell spans. This function take the index of the current column as first parameter. This function takes the parse result of the opening part of the cell environment of the current cell as third input parameter. This function calculates only the changes in the multirowdict for the opening environment of the cell. You should not use this function but rather use multiRowDictChange since this also considers the effect by ending of cells DHUN-}+ +multiRowDictChangeStart ::+                        Int -> Map Int (Int, Int) -> [Anything Char] -> Map Int (Int, Int)+multiRowDictChangeStart i d l+  = fromMaybe d $+      do n <- rowMultiplicity l+         return (Map.insert i ((n - 1), c) d)+  where c = (columnMultiplicityForCounting l)+ +{-DHUN| calculate the full change to the multirowdict. See documentation on the function multiRowDictChangeStart in this module for more information on the multirowdict. The first parameter is the index of the current column. The second parameter is the current multirowdict. This function takes the parse result of the opening part of the cell environment of the current cell as third input parameter. This function returns the updated multirowdict. DHUN-}+ +multiRowDictChange ::+                   Int -> Map Int (Int, Int) -> [Anything Char] -> Map Int (Int, Int)+multiRowDictChange i d l+  = multiRowDictChangeStart n (multiRowDictChangeEnd i d) l+  where n = i + (multiRowCount i d)+ +{-DHUN| returns the latex symbol for the start of a multirow cell. That is a cell spanning multiple rows. The second parameter is activeColumn. This is an integer wrapped in the maybe monad. If it is has the value Just then the row is to be renderer in a special mode. This mode is needed to determine the width of the columns. In this special mode no line break occur and width of the paper is infinite, so that the width of the of each column is its respective natural width. So there is no limit on the width of the column. If the value is Nothing this means that the table is typeset in normal mode and the width is to be limited. The first parameter is the inner parse result of the row separator containing information on whether or not the cell is multirow DHUN-}+ +multiRowStartSymbol :: [Anything Char] -> Maybe Int -> String+multiRowStartSymbol l m+  = fromMaybe "" $+      do n <- rowMultiplicity l+         return $+           "\\multirow{" +++             (show n) +++               "}{" ++ (if isJust m then "*" else "\\linewidth") ++ "}{"+ +{-DHUN| a symbol to be added at the end of header cell in order to make its content bold. The only boolean parameter is use to indicate whether the cell currently under consideration is a header cell. Otherwise the empty string is returned.  DHUN-}+ +headendsym :: Bool -> String+headendsym False = ""+headendsym True = "}"+ +{-DHUN| a symbol to be added at the start of header cell in order to make its content bold DHUN-}+ +headstartsym :: String+headstartsym = "{\\bfseries "+ +{-DHUN| the symbol to be inserted into the latex document, for the end of a row in a table. The first boolean parameter is should be true if the current table is not nested in an other one. The second boolean parameter should be true if the column was the last column of the header of the table. The header of the table is repeated by latex each time page wrapping inside the table occurs. See also documentation of the longtable latex package DHUN-}+ +rowendsymb :: Bool -> Bool -> String+rowendsymb True True = "\\endhead "+rowendsymb _ _ = "\\\\"
+ src/Tools.hs view
@@ -0,0 +1,92 @@+{-DHUN| various helper functions DHUN-}+module Tools where+import Data.List (isPrefixOf, tails)+import Data.Char+import Data.List.Split (splitOn)+import Control.Monad+import System.IO+import Data.List.HT (dropWhileRev)+ +{-DHUN| Write a unicode string to a utf8 encoded file. The first parameter is the filename, the second the contend to be written to the file. DHUN-}+ +writeFile :: FilePath -> String -> IO ()+writeFile f s+  = do h <- openFile f WriteMode+       hSetEncoding h utf8+       hPutStr h s+       hClose h+ +{-DHUN| read a utf8 encoded file fully as a unicode string. The first parameter is the filename. The return value is the content of the file wrapped in the IO monad. DHUN-}+ +readFile :: FilePath -> IO String+readFile f+  = do h <- openFile f ReadMode+       hSetEncoding h utf8+       z <- hGetContents h+       return z+ +{-DHUN| If the list is not empty it returns the list without the last item, otherwise the empty list- DHUN-}+ +nullinit :: [a] -> [a]+nullinit l = if null l then [] else init l+ +{-DHUN| Returns the list with the first element stripped wrapped in a Just of the Maybe monad. If the list is empty returns the value Nothing of the maybe monad. DHUN-}+ +maybeTail :: [a] -> Maybe [a]+maybeTail [] = Nothing+maybeTail (_ : xs) = Just xs+ +{-DHUN| Returns the first element of a list wrapped in a Just of the Maybe monad. If the list is empty returns the value Nothing of the Maybe monad, DHUN-}+ +maybeHead :: [a] -> Maybe a+maybeHead [] = Nothing+maybeHead (x : _) = Just x+ +{-DHUN| The first parameter is and item. the second parameter is a list. If the list contains the item it returns the list up to the first occurrence of the item with the item itself excluded, otherwise it returns the empty list. DHUN-}+ +headSplitEq :: (Eq a) => a -> [a] -> [a]+headSplitEq c s+  = case splitOn [c] s of+        g : _ -> g+        [] -> []+ +{-DHUN| Removes all white space characters trailing on the right hand side of a string DHUN-}+ +rtrim :: String -> String+rtrim = dropWhileRev isSpace+ +{-DHUN| The first parameter is an original item. The second parameter is a replacement item. The third parameter is a list. This function replaces all occurrences of the original item, with the replacement item in the list. DHUN-}+ +replace :: (Eq a) => a -> a -> [a] -> [a]+replace src target = map (\ x -> if x == src then target else x)+ +{-DHUN| The first parameter is an input list. The second parameter is an original list that may or may not or may several times be part of the input list. The third parameter is an a replacement list. This function replaces all occurrences of the original list in the input list, with the replacement list. DHUN-}+ +replace2 :: (Eq a) => [a] -> [a] -> [a] -> [a]+replace2 hay needle nail+  | needle `isPrefixOf` hay =+    nail ++ replace2 (drop (length needle) hay) needle nail+replace2 (x : xs) needle nail+  | otherwise = x : (replace2 xs needle nail)+replace2 [] _ _ = []+ +{-DHUN| The first parameter is an input list.  The second parameter is also a list, that might be contained in the input list. If this is the case this function returns true. Otherwise this function returns false  DHUN-}+ +isInfixOf2 :: (Eq a) => [a] -> [a] -> Bool+isInfixOf2 needle haystack+  = any (needle `isPrefixOf`) (tails haystack)+ +{-DHUN| Converts a single character in hex notation to an integer. The integer is wrapped in a mMybe monad. If an integer could be found it is wrapped in a Just of the Maybe monad. Otherwise the value Nothing of the Maybe monad is returned DHUN-}+ +unhexChar :: Char -> Maybe Integer+unhexChar c = lookup c hexTable+  where hexTable+          = zip ['0' .. '9'] [0 .. 9] +++              zip ['a' .. 'f'] [10 .. 15] ++ zip ['A' .. 'F'] [10 .. 15]+ +{-DHUN| Converts a sequence of characters in hex notation to an integer. The integer is wrapped in a Maybe monad. If an integer could be found it is wrapped in a Just of the Maybe monad. Otherwise the value Nothing of the Maybe monad is returned DHUN-}+ +unhex :: String -> Maybe Integer+unhex = foldM f 0+  where f acc ch+          = maybe Nothing (\ val -> Just $ 16 * acc + val) (unhexChar ch)
+ src/UrlAnalyse.hs view
@@ -0,0 +1,252 @@+{-DHUN| module for processing urls and downloading their content with repect to mediawiki DHUN-}+module UrlAnalyse+       (getpage, analyse, analyseFull, unify, WikiUrl, getLemma,+        FullWikiUrl, hostname, url, alternatives, lemma, wikiUrl, geturl,+        parses, geturl2, fullWikiUrlZero, getExpandedPage, getpage2)+       where+import qualified Network.Browser as Browser+import Network.HTTP.Conduit+import Data.ByteString.Lazy.Internal+import Network.URL as URL+import Network.HTTP+import Control.Monad+import Data.Maybe+import Data.List.Split+import Data.List+import Text.XML.HXT.Core+import Data.Tree.NTree.TypeDefs+import Codec.Binary.UTF8.String+import Control.Exception+import qualified Data.ByteString as BStr+import qualified Data.ByteString.UTF8 as UTF8Str+ +{-DHUN| This represents the main url of a wiki page. So the url of the wiki page that should be converted to latex. It is a tuple wrapped into the maybe monad, to deal with case in which the url could not be parses. The first element of the tuple is just the main url parser with Network.URL The second element is a list of urls. These URLs are possible base urls for wiki pages. So en.wikipedia.org/wiki/Foobar has got the main url en.wikipedia.org/wiki/Foobar and one of the base urls us en.wikipedia.org/wiki/. Base urls are important since the wiki source related to the main url might include subpage in wiki notation that is [[JohnDow]]. The actual url to look up JohnDow is the baseurl plus JohnDow so that is en.wikipedia.org/wiki/JohnDow Since also images in the commons and similar things are possible, the are usually some baseurls to be looked at. This way the base URl have to be a list. DHUN-}+ +type WikiUrl = Maybe (URL, [URL])+ +{-DHUN| same as WikiURL. two additional parameters. the host parameter is name of host. And lemma is the name of the page on the wiki DHUN-}+ +wikiUrl :: FullWikiUrl -> WikiUrl+wikiUrl fu = return (url fu, alternatives fu)+ +data FullWikiUrl = FullWikiUrl{url :: URL, alternatives :: [URL],+                               hostname :: String, lemma :: String}+                 deriving (Eq, Ord)+ +fullWikiUrlZero :: FullWikiUrl+fullWikiUrlZero+  = FullWikiUrl{url =+                  URL{URL.url_type =+                        Absolute+                          (Host{URL.protocol = HTTP False, URL.host = "",+                                URL.port = Nothing}),+                      url_path = "", url_params = []},+                alternatives = [], hostname = "", lemma = ""}+ +{-DHUN| returns the list of baseurls of an WikiURL. The list may be empty if the WikiURL has none. See documentation on the type 'WikiURL' to understand what a baseurl is. DHUN-}+ +parses :: WikiUrl -> [URL]+parses u+  = do uu <- maybeToList u+       snd uu+ +{-DHUN| takes a baseurl and a wiki lemma and creates the url under which the wiki source code of the lemma can be retrieved. So the Url en.wikipedia.org/wiki/FoorBar has possible many baseurls. One of which is  en.wikipedia.org/wiki/. The wiki source of the lemma JonDow can be retrieved from the wiki via the url en.wikipedia.org/wiki/Special:Export/JohnDow. Which is just what these function returns. See also documentation on the type 'WikiUrl' on what a baseurl is. DHUN-}+ +modpath :: String -> URL -> URL+modpath s u+  = u{url_path =+        if p /= [] then p ++ "/Special:Export/" ++ s else+          "Special:Export/" ++ s}+  where p = (url_path u)+ +modpathForExpansion :: URL -> URL+modpathForExpansion u+  = u{url_path =+        (if p /= [] then p ++ "/Special:ExpandTemplates" else+           "Special:ExpandTemplates"),+      url_params = []}+  where p = (url_path u)+ +{-DHUN| load a webpage via http the url to the webpage has to be given as string on the first input parameter. The result of the request is returned as a String wrapped in the IO monad. DHUN-}+ +geturl :: String -> IO String+geturl u+  = Control.Exception.catch+      (do x <- Browser.browse $+                 do Browser.setAllowRedirects True+                    Browser.request $ getRequest u+          return (rspBody (snd x)))+      fun+  where  +        fun :: ErrorCall -> IO String+        fun _ = return ""+ +geturl3 :: String -> String -> String -> IO String+geturl3 u d s+  = Control.Exception.catch+      (do req0 <- parseUrl u+          let req+                = (urlEncodedBody+                     (map (\ (a, b) -> (UTF8Str.fromString a, UTF8Str.fromString b))+                        [("wpInput", d), ("removecomments", "1"), ("removenowiki", "1"),+                         ("generate_xml", "0"), ("contexttitle", s)]))+                    req0+          res <- withManager $ httpLbs req+          return ((unpackChars (responseBody res))))+      fun+  where  +        fun :: ErrorCall -> IO String+        fun _ = return ""+ +geturl2 :: String -> IO BStr.ByteString+geturl2 u+  = Control.Exception.catch+      (do x <- Browser.browse $+                 do Browser.setAllowRedirects True+                    Browser.request $+                      Request{rqURI = rqURI dg, rqMethod = rqMethod dg,+                              rqHeaders = rqHeaders dg, rqBody = UTF8Str.fromString (rqBody dg)}+          return (rspBody (snd x)))+      fun+  where  +        fun :: ErrorCall -> IO BStr.ByteString+        fun _ = return (BStr.pack [])+        dg = (getRequest u)+ +{-DHUN| helper function to get the actual wiki source as string out of a part of and xml tree returned by the xml parser. Only used for the function getTextContent DHUN-}+ +toText :: [NTree XNode] -> Maybe String+toText [NTree _ [NTree (XText l) []]] = Just l+toText _ = Nothing+ +{-DHUN| this function gets the actual wiki source of a wiki page out of the result String returned by the Special:Export function of mediawiki. You should not call this function directly since it may break the flow of control. Better use the function getTextContent2 DHUN-}+ +getTextContent :: String -> IO (Maybe String)+getTextContent z+  = do h <- runX+              ((readString [withValidate no, withParseHTML yes] z) >>>+                 (deep (isElem >>> hasName "text")))+       x <- return . toText $ h+       return (seq x x)+ +{-DHUN| this function gets the actual wiki source of a wiki page out of the result String returned by the Special:Export function of mediawiki. This function returns its result wrapped in a maybe monad so it can return the maybe value Nothing in case of failure but does not break the flow of control. It is also wrapped in the IO monad since the xml parser used is bound to the IO monad  DHUN-}+ +getTextContent2 :: String -> IO (Maybe String)+getTextContent2 z+  = catchJust myfun (getTextContent z) (\ _ -> return Nothing)+ +getExpandedTextContent :: String -> IO (Maybe String)+getExpandedTextContent z+  = do h <- runX+              ((readString [withValidate no, withParseHTML yes] z) >>>+                 (deep+                    (isElem >>> hasName "textarea" >>>+                       (hasAttrValue "id" (\ g -> g == "output")))))+       x <- return . toText $ h+       return (seq x x)+ +getExpandedTextContent2 :: String -> IO (Maybe String)+getExpandedTextContent2 z+  = catchJust myfun (getExpandedTextContent z)+      (\ _ -> return Nothing)+ +{-DHUN| exception predicate interested in all exceptions. Thats means we catch all exceptions. This needed in getTexTContent2 so that the maybe value nothing is returned in case of an exception but the control flow is not interrupted DHUN-}+ +myfun :: SomeException -> Maybe ()+myfun _ = return ()+ +{-DHUN| gets the wiki source code of a lemma on a wiki. The first parameter is the lemma. So JohnDow for en.wikipedia/wiki/JohnDow. The second parameter is the wikiurl. A wikiurl specifies the wiki from which the data should be downloaded. See documentation on the type 'WikiUrl' for more information. Also see documentation on the function 'analyze' to see how to create a 'WikiUrl'. This function returns the wiki source code of the lemma as String it is wrapped in the IO monad since it does a http request it is also wrapped in the Maybe monad since it may not be able to retrieve the source. DHUN-}+ +getpage :: String -> WikiUrl -> IO (Maybe String)+getpage ss u+  = do l <- mapM (geturl . unify . exportURL . modpath ss) (parses u)+       ll <- mapM getTextContent2 l+       lll <- return (seq ll ll)+       return $+         (listToMaybe $ concat (map maybeToList lll)) >>=+           (return . decodeString)+ +getpage2 :: String -> WikiUrl -> IO (Maybe (String, URL))+getpage2 ss u+  = do l <- mapM (geturl . unify . exportURL . modpath ss) (parses u)+       ll <- mapM getTextContent2 l+       lll <- return (seq ll ll)+       return $ (listToMaybe $ concat (map go (zip lll (parses u))))+  where go (Just xx, uu) = [(decodeString xx, uu)]+        go _ = []+ +getExpandedPage :: String -> String -> URL -> IO (Maybe String)+getExpandedPage ss d u+  = do l <- mapM+              ((\ x -> geturl3 x d ss) . unify . exportURL . modpathForExpansion)+              [u]+       ll <- mapM getExpandedTextContent2 l+       lll <- return (seq ll ll)+       return $+         (listToMaybe $ concat (map maybeToList lll)) >>=+           (return . decodeString)+ +{-DHUN| unescapes the special character underscore and % from url notation DHUN-}+ +unify :: [Char] -> [Char]+unify ('%' : ('2' : ('0' : xs))) = '_' : unify xs+unify ('%' : ('2' : ('5' : xs))) = '%' : unify xs+unify (x : xs) = x : (unify xs)+unify [] = []+ +{-DHUN| converts an url given as String into a WikiURL. See description on type 'WikiURL' on what that means. DHUN-}+ +analyse :: String -> WikiUrl+analyse s+  = do vv <- v+       ww <- importURL "http://commons.wikimedia.org/wiki"+       return (vv, z ++ [ww])+  where v = importURL s+         +        z :: [URL]+        z = do u <- maybeToList $ v+               l <- return $ splitOn "/" $ (unify (url_path u))+               x <- (map+                       (\ i ->+                          if (length l) > i then [intercalate "/" (take i l)] else mzero)+                       [0, 1, 2])+               map (\ i -> u{url_path = i}) x+ +{-DHUN| converts an url given as String into the lemma it points to on the wiki.  DHUN-}+ +getLemma :: String -> Maybe String+getLemma s = z+  where v = importURL s+         +        z :: Maybe String+        z = do u <- v+               l <- return $ splitOn "/" $ (unify (url_path u))+               let x = if (length l) > 1 then drop 1 l else l+               let xx+                     = if "index.php" `elem` x then+                         case dropWhile (/= "index.php") x of+                             (_ : ys) -> ys+                             _ -> []+                         else x+               return $ intercalate "/" xx+ +{-DHUN| converts an url given as String into the host (as string) it points to on the wiki.  DHUN-}+ +getHost :: String -> Maybe String+getHost s = z+  where v = importURL s+         +        z :: Maybe String+        z = do u <- v+               case (url_type u) of+                   Absolute h -> return (URL.host h)+                   _ -> mzero+ +analyseFull :: String -> Maybe FullWikiUrl+analyseFull theUrl+  = do ana <- analyse theUrl+       l <- getLemma theUrl+       h <- getHost theUrl+       return $+         FullWikiUrl{url = fst ana, alternatives = snd ana, hostname = h,+                     lemma = l}
+ src/WikiHelper.hs view
@@ -0,0 +1,270 @@+{-DHUN| general helper function for converting from the parsetree to latex DHUN-}+module WikiHelper where+import Tools+import MediaWikiParseTree+import Data.Char+import Data.List.Split+import MagicStrings+import qualified Data.Map as Map+import MyState+import Data.List+import Data.String.HT (trim)+ +{-DHUN| add latex label elements to the parse tree. chapter section subsection and so on will be referenced by these labels. It takes the initial UrlState as second parameter. And the parse tree to be processed as first parameter. It returns a tuple. The first element is them modified urlstate and the second is the modified parse tree with the labels added. The field sUrlState of UrlState contains the page name of the downloaded page currently being processed by the algorithm. the filed mUrlState of UrlState is the number of the currenty label. And ,UrlState is a mapping from combined page and chapter, section etc. names (like urls) to their label numbers.    DHUN-}+ +makeLables ::+           [Anything Char] -> UrlState -> (UrlState, [Anything Char])+makeLables ll states+  = let (f, s) = mapAccumL makeLablesForNode states ll in+      (f, concat s)+  where  +        makeLablesForNode ::+                          UrlState -> Anything Char -> (UrlState, [Anything Char])+        makeLablesForNode st (Environment DhunUrl ss l)+          = (st{iUrlState = (iUrlState st) + 1, sUrlState = yy,+                mUrlState = Map.insert yy lab (mUrlState st)},+             [Environment DhunUrl ss l] ++ [Environment Label (Str lab) []])+          where yy = (replace2 (shallowFlatten l) " " "_")+                lab = (show . iUrlState $ st)+        makeLablesForNode st (Environment Wikiheading (Str ss) l)+          = (st{iUrlState = (iUrlState st) + 1,+                mUrlState =+                  Map.insert ((sUrlState st) ++ "#" ++ yy) lab (mUrlState st)},+             [Environment Wikiheading (Str ss) l] +++               [Environment Label (Str lab) []])+          where lab = (show . iUrlState $ st)+                yy = (replace2 (trim (shallowFlatten l)) " " "_")+        makeLablesForNode st (Environment e s l)+          = (fst zz, [Environment e s (snd $ zz)])+          where zz = makeLables l st+        makeLablesForNode st x = (st, [x])+ +{-DHUN| remove superfluous br html tags from the parse tree. Always run before converting the parse tree to latex DHUN-}+ +removeBr :: [Anything Char] -> [Anything Char]+removeBr ((C '\n') : ((Environment Tag (TagAttr "br" _) _) : xs))+  = (C '\n') : removeBr xs+removeBr+  ((Environment Tag (TagAttr "br" _) _) :+     ((Environment Tag (TagAttr "br" a2) l2) : xs))+  = removeBr ((Environment Tag (TagAttr "br" a2) l2) : xs)+removeBr+  ((Environment Wikilink s1 l1) :+     ((Environment Tag (TagAttr "br" a2) l2) : xs))+  = if isImage (shallowFlatten l1) then+      removeBr ((Environment Wikilink s1 l1) : xs) else+      (Environment Wikilink s1 l1) :+        (removeBr ((Environment Tag (TagAttr "br" a2) l2) : xs))+removeBr ((Environment SpaceIndent x l) : xs)+  = (Environment SpaceIndent x (removeBr l)) : removeBr xs+removeBr (x : xs) = x : removeBr xs+removeBr [] = []+ +{-DHUN| checks if a given string is an image inclusion in wiki notation. In wiki notation an image is included by [[Image:FooBar.png]], but image may be replace by localized versions like Bild in German, so this function checks for those and return true if it seems to be an image DHUN-}+ +isImage :: String -> Bool+isImage x+  = ([z | z <- map (++ ":") imgtags, z `isPrefixOf` (map toLower x)]+       /= [])+ +{-DHUN| flattens a parse tree shallowly. that is take all characters on the surface level of the parse tree and combines them into a single string. It does not decent into substructures of the parse and so neglects all characters there and does not return those with the exception of character in SpaceIndent environments directly attached to the surface level DHUN-}+ +shallowFlatten :: [Anything Char] -> String+shallowFlatten ((C a) : xs) = a : (shallowFlatten xs)+shallowFlatten ((S a) : xs) = a ++ (shallowFlatten xs)+shallowFlatten ((Environment SpaceIndent _ l) : xs)+  = '\n' : ((shallowFlatten l) ++ (shallowFlatten xs))+shallowFlatten (_ : xs) = shallowFlatten xs+shallowFlatten [] = []+ +{-DHUN| A link in wiki notation is given by [foorbar.com a caption]. This function returns the location the link points to so foobar.com as String. It takes the parse tree representation of the  link as input parameter DHUN-}+ +linkLocation :: [Anything Char] -> String+linkLocation l+  = case yy of+        [] -> ""+        (z : _) -> z+  where xx = (splitOn " " (shallowFlatten l))+        yy+          = splitOn "|"+              (case xx of+                   [] -> ""+                   (g : _) -> g)+ +{-DHUN| changes the extension for a filename given in the wiki source to the extension to be used in the latex document. For example svg documents are converted to png documents. So this function converts the string 'svg' to the string 'png' DHUN-}+ +normalizeExtension :: String -> String+normalizeExtension ('s' : ('v' : ('g' : _))) = "\\SVGExtension"+normalizeExtension ('j' : ('p' : ('e' : ('g' : _)))) = "jpg"+normalizeExtension ('j' : ('p' : ('g' : _))) = "jpg"+normalizeExtension ('g' : ('i' : ('f' : _))) = "png"+normalizeExtension ('p' : ('n' : ('g' : _))) = "png"+normalizeExtension ('t' : ('i' : ('f' : ('f' : _)))) = "png"+normalizeExtension ('t' : ('i' : ('f' : _))) = "png"+normalizeExtension (' ' : xs) = normalizeExtension xs+normalizeExtension (x : xs) = x : (normalizeExtension xs)+normalizeExtension [] = []+ +normalizeExtension2 :: String -> String+normalizeExtension2 ('s' : ('v' : ('g' : _))) = "svg"+normalizeExtension2 ('j' : ('p' : ('e' : ('g' : _)))) = "jpg"+normalizeExtension2 ('j' : ('p' : ('g' : _))) = "jpg"+normalizeExtension2 ('g' : ('i' : ('f' : _))) = "gif"+normalizeExtension2 ('p' : ('n' : ('g' : _))) = "png"+normalizeExtension2 ('t' : ('i' : ('f' : ('f' : _)))) = "tif"+normalizeExtension2 ('t' : ('i' : ('f' : _))) = "tif"+normalizeExtension2 (' ' : xs) = normalizeExtension xs+normalizeExtension2 (x : xs) = x : (normalizeExtension xs)+normalizeExtension2 [] = []+ +{-DHUN| returns the extension of a filename. DHUN-}+ +fileNameToExtension :: String -> String+fileNameToExtension s = last (splitOn "." (map toLower s))+ +{-DHUN| a predicate that can be run on an element of a parse tree that returns true if the element is a wikilink. A wikilink is denoted as [[Foobar]] in the wiki notation, an links to an other mediawiki page on the same or a different wiki DHUN-}+ +isWikiLink :: (Anything Char) -> Bool+isWikiLink (Environment Wikilink _ []) = False+isWikiLink (Environment Wikilink _ _) = True+isWikiLink _ = False+ +{-DHUN| changes Math elements on the surface level of a parse tree to bigmath elements. Those will be rendered as equation environments. Normal math is usually only display be the dollar math environment in latex.  DHUN-}+ +shallowEnlargeMath :: [Anything Char] -> [Anything Char]+shallowEnlargeMath ((Environment Math s l) : xs)+  = (Environment BigMath s l) : shallowEnlargeMath xs+shallowEnlargeMath (x : xs) = x : shallowEnlargeMath xs+shallowEnlargeMath [] = []+ +{-DHUN| this function modified chapter headings. It is used when converting a chapter heading from the parse tree to latex. In the wiki often the page name is used as chapter heading and thus only the parts after the slashes and colons are to be taken into account. Also underscores have to be replaced by spaces DHUN-}+ +chapterTransform :: String -> String+chapterTransform s+  = replace '_' ' ' (last (splitOn ":" (last (splitOn "/" s))))+ +{-DHUN| returns the separator to separate items in enumeration, itemizations and so on. Currently this is always \\item{} but this may change depending on which latex package is used to display enumerations and so on. Takes the char for this type of enumeration etc. in wiki notation. That is a hash for enumeration and a asterisk for itemization and so on DHUN-}+ +itemSeperator :: Char -> String+itemSeperator c = itemSeperator2 [c]+ +{-DHUN| see documentation on itemSeperator. The only difference is that this function takes a string containing a single character instead of the single character itself DHUN-}+ +itemSeperator2 :: String -> String+itemSeperator2 "#" = "\\item{}"+itemSeperator2 ":" = "\\item{}"+itemSeperator2 ";" = "\\item{}"+itemSeperator2 "*" = "\\item{}"+itemSeperator2 _ = "\\item{}"+ +{-DHUN| returns the name of a latex environment for an itemization enumeration etc.. The first parameter is a string in wiki notation and declare which type environment should be used. The second parameter is a float giving the width of the current cell in units of the line width when inside a table and is 1.0 if currently not inside any table. DHUN-}+ +itemEnvironmentName :: String -> Float -> String+itemEnvironmentName "#" _ = "myenumerate"+itemEnvironmentName ":" _ = "myquote"+itemEnvironmentName ";" _ = "mydescription"+itemEnvironmentName "*" _ = "myitemize"+itemEnvironmentName _ _ = "list"+ +{-DHUN| returns additional parameter for the opening of a latex environment for an itemization enumeration etc. The second parameter is a float giving the width of the current cell in units of the line width when inside a table and is 1.0 if currently not inside any table. DHUN-}+ +itemEnvironmentParameters :: String -> Float -> String+itemEnvironmentParameters "#" _ = ""+itemEnvironmentParameters ":" _ = ""+itemEnvironmentParameters ";" _ = ""+itemEnvironmentParameters "*" _ = ""+itemEnvironmentParameters _ _ = "{\\labelitemi}{\\leftmargin=1em}"+ +{-DHUN| do multple replacements in a row. The first argument is haystack. The second one a list of pair of a needle and a corresponding nail. The haystack with each needle replaced by a nail is returned DHUN-}+ +multireplace :: (Eq a) => [a] -> [([a], [a])] -> [a]+multireplace haystack ((needle, nail) : xs)+  = multireplace (replace2 haystack needle nail) xs+multireplace haystack [] = haystack+ +{-DHUN| converts a mathematical expression (that is something within a math tag in the wiki) to an latex expression. Essentially the wiki is using latex. But it allows for some extra features that are take care of in this transformation DHUN-}+ +mathTransform :: [Anything Char] -> String+mathTransform x+  = multireplace (replace '\n' ' ' (shallowFlatten x)) replist+ +{-DHUN| list of replacements to be applied to contents of math tags in wiki notation for use in the latex equation environment DHUN-}+ +replist :: [([Char], [Char])]+replist+  = [("\\or", "\\vee{}"), ("%", "\\%"), ("\\and", "\\wegde"),+     ("\\begin{align}", "\\begin{aligned}"),+     ("\\end{align}", "\\end{aligned}"), ("\\\\%", "\\%"),+     ("\\part ", "\\partial "), ("\\part{", "\\partial{"), ("\\;", ""),+     ("\\|", "\\Vert"), ("\\!", ""), ("\\part\\", "\\partial\\")]+ +{-DHUN| helper function for line breaking in source code and preformatted block. Not to be called from outside this module. Converts character to parse tree entities, to be process by breakLinesHelper3 DHUN-}+ +breakLinesHelper4 :: [Anything Char] -> [Anything Char]+breakLinesHelper4 ((C '\n') : xs)+  = (Environment Tag (TagAttr "br" Map.empty) []) :+      breakLinesHelper4 xs+breakLinesHelper4 ((C '\t') : xs) = Tab : breakLinesHelper4 xs+breakLinesHelper4 ((C ' ') : xs) = Quad : breakLinesHelper4 xs+breakLinesHelper4 (x : xs) = x : breakLinesHelper4 xs+breakLinesHelper4 [] = []+ +{-DHUN| the width of a tab character in spaces DHUN-}+ +tabwidth :: Int+tabwidth = 4+ +{-DHUN| helper function for line breaking in source code and preformatted block. Not to be called from outside this module. Inserts br tags where line breaks are needed, the first parameter is an integer which represents the current column in the text, it should be zero when this function is called externally. The second parameter is an integer an represents the maximum length of the line in characters. The third input parameter is the code block to which the line breaks should be added in parse tree notation. The function returns the code block with added br tags for the line breaks in parse tree notation DHUN-}+ +breakLinesHelper3 ::+                  Int -> Int -> [Anything Char] -> [Anything Char]+breakLinesHelper3 _ m ((Environment Tag (TagAttr "br" y) []) : xs)+  | y == Map.empty =+    (Environment Tag (TagAttr "br" Map.empty) []) :+      breakLinesHelper3 0 m xs+breakLinesHelper3 i m (Tab : xs)+  = if i + wl >= m then+      (Environment Tag (TagAttr "br" Map.empty) []) :+        Tab : breakLinesHelper3 0 m xs+      else Tab : breakLinesHelper3 (i + tabwidth) m xs+  where wlb = length (takeWhile fun xs)+        wl = if (wlb < m) then wlb else 0+        fun x+          = (x /= Quad) &&+              (x /= (Environment Tag (TagAttr "br" Map.empty) []))+breakLinesHelper3 i m (x : xs)+  = if i + wl >= m then+      (Environment Tag (TagAttr "br" Map.empty) []) :+        x : breakLinesHelper3 0 m xs+      else x : breakLinesHelper3 (i + 1) m xs+  where wlb = length (takeWhile (fun) xs)+        wl = if (wlb < m) then wlb else 0+        fun xx+          = (xx /= Quad) &&+              (xx /= (Environment Tag (TagAttr "br" Map.empty) []))+breakLinesHelper3 _ _ [] = []+ +{-DHUN| Breaks lines in source code and preformatted block. Inserts br tags where line breaks are needed. The first parameter is an integer an represents the maximum length of the line in characters. The second input parameter is the code block to which the line breaks should be added in parse tree notation. The function returns the code block with added br tags for the line breaks in parse tree notation DHUN-}+ +breakLines3 :: Int -> [Anything Char] -> [Anything Char]+breakLines3 m s+  = rebreak (breakLinesHelper3 0 m (breakLinesHelper4 s))+ +{-DHUN| Adds quads in between double br line breaks, needed since double \\newline is not allowed in latex DHUN-}+ +rebreak :: [Anything Char] -> [Anything Char]+rebreak+  ((Environment Tag (TagAttr "br" a) l) :+     ((Environment Tag (TagAttr "br" a2) l2) : xs))+  = (Environment Tag (TagAttr "br" a) l) :+      Quad : (rebreak ((Environment Tag (TagAttr "br" a2) l2) : xs))+rebreak (x : xs) = x : (rebreak xs)+rebreak [] = []+ +{-DHUN| Replaces several parse tree item representations of white space characters with the corresponding whitespace characters themselves in parse tree notation. DHUN-}+ +renormalize :: Anything Char -> Anything Char+renormalize (Environment Tag (TagAttr "br" _) []) = C '\n'+renormalize Quad = C ' '+renormalize Tab = C '\t'+renormalize x = x
+ src/WikiLinkHelper.hs view
@@ -0,0 +1,188 @@+{-DHUN| helper functions to convert from parse tree notation to latex notation DHUN-}+module WikiLinkHelper where+import Tools+import qualified Data.Map as Map+import qualified Data.Set as Set+import MagicStrings+import MyState+import MediaWikiParseTree+import Data.List+import Network.HTTP+import WikiHelper+import Data.Char+import Data.List.Split+import Control.Monad+ +{-DHUN| takes a list of language prefixes and sister project prefixes and return a the first one or two elements of that list as tuple of Strings wrapped into maybe monads, returns nothing at the appropriate elements to the tuple if the list does not have enough elements. The first element of the tuple is populated first DHUN-}+ +getprefixes :: [String] -> (Maybe String, Maybe String)+getprefixes ss+  = case ss of+        [] -> (Nothing, Nothing)+        (x : xs) -> (Just $ filter (not . isSpace) (map toLower x),+                     case xs of+                         [] -> Nothing+                         (y : _) -> Just $ filter (not . isSpace) (map toLower y))+ +{-DHUN| in the wiki source a heading is given by == foo bar == where the number of space gives the level of the heading. In latex this is done with string like 'section. This function translates from wiki notation to latex notation DHUN-}+ +getsec :: String -> String+getsec "=" = "chapter"+getsec "==" = "section"+getsec "===" = "subsection"+getsec "====" = "subsubsection"+getsec "=====" = "paragraph"+getsec "======" = "subparagraph"+getsec _ = "subparagraph"+ +{-DHUN| in the wiki source a heading is given by == foo bar == where the number of space gives the level of the heading. In latex this is done with string like 'section'. Some of with need additional commands after the actual heading command. Those are returned by this function  DHUN-}+ +getsecpost :: String -> String+getsecpost "=" = "\n\\myminitoc\n"+getsecpost "==" = ""+getsecpost "===" = ""+getsecpost "====" = ""+getsecpost "=====" = "{$\\text{ }$}\\newline"+getsecpost "======" = "{$\\text{ }$}\\newline"+getsecpost _ = "{$\\text{ }$}\\newline"+ +{-DHUN| a predicate that returns true if the string is a valid image size in wiki notation. In the wiki an image is include like [[Image:FoorBar.png|300px]] where 300px means that the image should be displayed at a width of 300 pixel. This function takes strings and looks whether it looks like an integer number flowed by 'px' and is thus a valid width definition for an image in wiki notation DHUN-}+ +isImageSize :: String -> Bool+isImageSize x+  = if (isSuffixOf "px" x) then+      if (reads (take ((length x) - 2) x)) == ([] :: [(Float, [Char])])+        then False else True+      else False+ +{-DHUN| this predicate returns true if the string seems to be a caption of an image in wiki notation. And image give like [[Image:JohnDow.png|foo bar]] where 'foo bar' is the caption of the image. So this function just tests whether the string looks like one of the reserved keyword of mediawiki or like an image size definition (see function isImageSize) and return true if none of that fits DHUN-}+ +isCaption :: String -> Bool+isCaption x+  = if isImageSize x then False else+      if x `elem` ["thumb", "right", "left", "center"] then False else+        True+ +{-DHUN| escapes all charters of a string for use a a link with the hyperref package in latex DHUN-}+ +escapelink :: String -> String+escapelink s = concat (map chartransforlink s)+ +{-DHUN| analyzes a host name. If it belongs to a wikimedia project it returns an UrlInfo value otherwise it returns a WikiBaseUrl value. In any case it is the type WikiUrlData. This information is needed when building writing down links to subpages in latex or downloading images from the wiki. DHUN-}+ +analyseNetloc :: String -> WikiUrlData+analyseNetloc nl = myurldata+  where langm+          = do p <- prefix+               guard $ p `elem` foreignPrefixes+               guard $ (length splits) > 1+               prefix+        wtypem+          = case langm of+                Nothing -> do p <- prefix+                              guard $ (length splits) > 1+                              guard $ Set.member p wikiset+                              prefix+                Just _ -> do guard $ (length splits) > 2+                             p2 <- prefix2+                             guard $ Set.member p2 wikiset+                             prefix2+        myurldata+          = case (langm, wtypem) of+                (Just lang, Just wtype) -> UrlInfo+                                             (WikiUrlInfo{language = lang, wikitype = wtype})+                _ -> BaseUrl (WikiBaseUrl nl)+        splits = splitOn "." nl+        (prefix, prefix2) = getprefixes splits+        wikiset = Set.fromList . Map.elems . Map.fromList $ multilangwikis+ +{-DHUN| splits a wikilink in caption and link target and returns the target. So a wkilink is given like [[FooBar|John Dow]]. This link links to the lemma FooBar and is displayed with the caption 'John Dow'. So this function returns FooBar for that link. DHUN-}+ +localWikiLinkLocation :: String -> String+localWikiLinkLocation s = headSplitEq '|' s+ +{-DHUN| This function takes the contend of a wikilink in wiki markup notation as first input parameter in parse tree notation. It takes the state of the Latex Renderer as second input parameter. It returns the absolute url of the given wikilink as string DHUN-}+ +wikiLinkLocationesc :: [Anything Char] -> MyState -> String+wikiLinkLocationesc l st+  = getUrlFromWikiLinkInfoesc .+      getWikiLinkInfo (shallowFlatten l) . urld+      $ st+ +{-DHUN| converts a WikiLinkInfo value pointing to a page on a wiki to the full url of that page as string. It is escaped for the use with the hyperref latex package DHUN-}+ +getUrlFromWikiLinkInfoesc :: WikiLinkInfo -> String+getUrlFromWikiLinkInfoesc i+  = case (urldata i) of+        UrlInfo x -> "http://" +++                       (language x) +++                         "." +++                           (wikitype x) ++ ".org/wiki/" ++ (escapelink (urlEncode (page i)))+        BaseUrl (WikiBaseUrl x) -> "http://" +++                                     x ++ "/wiki/" ++ (escapelink (urlEncode (page i)))+ +{-DHUN| converts a WikiLinkInfo value pointing to a page on a wiki to the full url of that page as string. It is not is escaped in any way, so ready for use in a webbrowers DHUN-}+ +getUrlFromWikiLinkInfo :: WikiLinkInfo -> String+getUrlFromWikiLinkInfo i+  = case (urldata i) of+        UrlInfo x -> "http://" +++                       (language x) +++                         "." ++ (wikitype x) ++ ".org/wiki/" ++ (urlEncode (page i))+        BaseUrl (WikiBaseUrl x) -> "http://" +++                                     x ++ "/wiki/" ++ (urlEncode (page i))+ +{-DHUN| converts a WikiUrlData value pointing to a wiki and a string (like a part of a url) pointing to a page relative to that wiki and returns the full url of that page as string DHUN-}+ +wikiUrlDataToString :: WikiUrlData -> String -> String+wikiUrlDataToString w i+  = case w of+        UrlInfo x -> "http://" +++                       (language x) ++ "." ++ (wikitype x) ++ ".org" ++ i+        BaseUrl (WikiBaseUrl x) -> "http://" ++ x ++ i+ +{-DHUN This function takes the contend of a wikilink in wiki markup notation as first input parameter. So for the wiki link (mediawiki markup notation) [[en:JohnDow|John Dow]] this is 'en:JohnDow|John Dow' (the single quotes were added to make the string distinguishable from the text and are not part of the passed parameter). It takes the WikiUrlData value describing the wiki the page currently being processed belongs to as second parameter. It returns a WikiLinkInfo value describing the target of the link given as first parameter when evaluated with respect to the second parameter DHUN-}+ +getWikiLinkInfo :: String -> WikiUrlData -> WikiLinkInfo+getWikiLinkInfo s i = WikiLinkInfo{urldata = udata, page = pagen}+  where udata+          = case (langmm, wtypemm) of+                (Just l, Just w) -> UrlInfo WikiUrlInfo{language = l, wikitype = w}+                _ -> i+        wtypem+          = do p <- prefix+               guard $ (length splits) > 1+               Map.lookup p (Map.fromList allwikis)+        langm+          = case wtypem of+                Nothing -> do p <- prefix+                              _ <- find (== p) foreignPrefixes+                              guard $ (length splits) > 1+                              prefix+                Just _ -> do p2 <- prefix2+                             _ <- find (== p2) foreignPrefixes+                             guard $ (length splits) > 2+                             prefix2+        langmm+          = case langm of+                Nothing -> langi+                x -> x+        wtypemm+          = case wtypem of+                Nothing -> wtypei+                x -> x+        langi+          = case i of+                UrlInfo ui -> Just (language ui)+                BaseUrl _ -> Nothing+        wtypei+          = case i of+                UrlInfo ui -> Just (wikitype ui)+                BaseUrl _ -> Nothing+        pagen = intercalate ":" ((mapn langm) . (mapn wtypem) $ splits)+        mapn h+          = case h of+                Nothing -> id+                Just _ -> drop 1+        splits = splitOn ":" (headSplitEq '|' s)+        (prefix, prefix2) = getprefixes splits
+ src/mediawiki2latex.hs view
@@ -0,0 +1,330 @@+{-DHUN| This is the main entry point of mediawiki2latex it parses the command line and delegatesto the requested submodules DHUN-}+module Main where+import All+import Control.Monad.State+import Control.Monad.Error+import System.Directory+import System.Environment+import System.Console.GetOpt+import System.Exit+import ImperativeState+import Data.Maybe+import Hex+import Server+import System.FilePath.Posix+import System.Info++{-DHUN| Data structure to repesent a single option on the command line. DHUN-}+ +data Flag = Verbose+          | Vector+          | Version+          | Templates String+          | Resolution String+          | Paper String+          | Copy String+          | Input String+          | Output String+          | LibDir String+          | MediaWiki+          | HTML+          | InternalTemplates+          | Hex String+          | Server String+          deriving (Show, Eq)+ ++{-DHUN| String constant on for the "version" commad line option. DHUN-}++versionOption :: String+versionOption = "version"+ +{-DHUN| String constant on for the "resolution" commad line option. DHUN-}++resolutionOption :: String+resolutionOption = "resolution"+ +{-DHUN| String constant on for the "output" commad line option. DHUN-}++output :: String+output = "output"+ +{-DHUN| String constant on for the "hex" commad line option. DHUN-}++hexen :: String+hexen = "hex"+ +{-DHUN| String constant on for the "templates" commad line option. DHUN-}++templates :: String+templates = "templates"++{-DHUN| String constant on for the "url" commad line option. DHUN-}++url :: String+url = "url"+ ++{-DHUN| String constant on for the "medaiwiki" commad line option. DHUN-}++mediawiki :: String+mediawiki = "mediawiki"+ +{-DHUN| String constant on for the "html" commad line option. DHUN-}++html :: String+html = "html"+ +{-DHUN| String constant on for the "paper" commad line option. DHUN-}++paperOption :: String+paperOption = "paper"+ +{-DHUN| String constant on for the "internal" commad line option. DHUN-}++internal :: String+internal = "internal"+ +{-DHUN| String constant on for the "vector" commad line option. DHUN-}++vectorOption :: String+vectorOption = "vector"++{-DHUN| String constant on for the "copy" commad line option. DHUN-}+ +copyOption :: String+copyOption = "copy"++{-DHUN| String constant on for the "server" commad line option. DHUN-}++serverOption :: String+serverOption = "server"+ +{-DHUN| Datastructure describing all possible command line options DHUN-}++options :: [OptDescr Flag]+options+  = [Option ['V', '?', 'v'] [versionOption, "help"] (NoArg Version)+       "show version number",+     Option ['o'] [output] (ReqArg Output "FILE")+       "output FILE (REQUIRED)",+     Option ['x'] [hexen] (ReqArg Hex "CONFIG")+       "hex encoded full configuration for run",+     Option ['s'] [serverOption] (ReqArg Server "PORT")+       "run in server mode listen on the given port",+     Option ['t'] [templates] (ReqArg Templates "FILE")+       "user template map FILE",+     Option ['r'] [resolutionOption] (ReqArg Resolution "INTEGER")+       "maximum image resolution in dpi INTEGER",+     Option ['u'] [url] (ReqArg Input "URL") "input URL (REQUIRED)",+     Option ['p'] [paperOption] (ReqArg Paper "PAPER")+       "paper size, on of A4,A5,B5,letter,legal,executive",+     Option ['m'] [mediawiki] (NoArg MediaWiki)+       "use MediaWiki to expand templates",+     Option ['h'] [html] (NoArg Main.HTML)+       "use MediaWiki generated html as input (default)",+     Option ['g'] [vectorOption] (NoArg Main.Vector)+       "keep vector graphics in vector form",+     Option ['i'] [internal] (NoArg Main.InternalTemplates)+       "use internal template definitions",+     Option ['c'] [copyOption] (ReqArg Main.Copy "DIRECTORY")+       "copy LaTeX tree to DIRECTORY"]+ +{-DHUN| parsed the options given on the command line via the getopt library DHUN-}++compilerOpts :: [String] -> IO ([Flag], [String])+compilerOpts argv+  = case getOpt Permute options argv of+        (o, n, []) -> return (o, n)+        (_, _, errs) -> ioError+                          (userError (concat errs ++ usageInfo header options))++{-DHUN| header string for the usage help DHUN-}+ +header :: String+header = "Usage: mediawiki2latex [OPTION...]"++{-DHUN| header string giving the current version string of mediawiki2latex DHUN-}++versionHeader :: String+versionHeader+  = "mediawiki2latex version 7.4\n" ++ (usageInfo header options)++{-DHUN| print the version string of mediawiki2latex. Takes the output of the compilerOpts function as input. Prints the version string if no options were given or the version command was given does noting otherwise DHUN-}++printVersion :: (Eq a) => ([Flag], [a]) -> IO ()+printVersion o+  = if (Version `elem` (fst o)) || o == ([], []) then+      putStrLn versionHeader >> exitSuccess else return ()++{-DHUN| checks whether the given option exists exactly once in the given (getopt parsed) command line. Takes a predicate (returning a Maybe type) as first input parameter. Takes the decription string for the option under consideration as second parameter. Takes the  (getopt parsed) command line as third input parameter. Return an either monad giving Right together with the value of the option in cases the option exists exacatly once in the command line, gives Left with an Error values otherwise DHUN-}++exactlyOne :: (a -> Maybe b) -> String -> [a] -> Either MyError b+exactlyOne predicate s o+  = case filter isJust (map predicate o) of+        ((Just x) : []) -> Right x+        _ -> Left (NotExcatlyOneError s)++{-DHUN| checks whether the given option exists at most once in the given (getopt parsed) command line. Takes a predicate (returning a Maybe type) as first input parameter. Takes the decription string for the option under consideration as second parameter. Takes the  (getopt parsed) command line as third input parameter. Return an either monad giving Right together with the value of the option in cases the option exists at most once once in the command line, gives Left with an Error values otherwise DHUN-}+ +atMostOne ::+          (a1 -> Maybe a) -> String -> [a1] -> Either MyError (Maybe a)+atMostOne predicate s o+  = case filter isJust (map predicate o) of+        (x : []) -> Right x+        ([]) -> Right Nothing+        _ -> Left (NotAtMostOneError s)+ +{-DHUN| predicate for the "resolution" option. see atMostOne and exactlyOne functions for details DHUN-}++resolutionPredicate :: Flag -> Maybe String+resolutionPredicate (Resolution x) = Just x+resolutionPredicate _ = Nothing++{-DHUN| predicate for the "copy" option. see atMostOne and exactlyOne functions for details DHUN-}+ +copyPredicate :: Flag -> Maybe String+copyPredicate (Copy x) = Just x+copyPredicate _ = Nothing++{-DHUN| predicate for the "output" option. see atMostOne and exactlyOne functions for details DHUN-}++outputPredicate :: Flag -> Maybe String+outputPredicate (Output x) = Just x+outputPredicate _ = Nothing++{-DHUN| predicate for the "input" option. see atMostOne and exactlyOne functions for details DHUN-}++inputPredicate :: Flag -> Maybe String+inputPredicate (Input x) = Just x+inputPredicate _ = Nothing++{-DHUN| predicate for the "templates" option. see atMostOne and exactlyOne functions for details DHUN-}++templatesPredicate :: Flag -> Maybe String+templatesPredicate (Templates x) = Just x+templatesPredicate _ = Nothing++{-DHUN| predicate for the "hex" option. see atMostOne and exactlyOne functions for details DHUN-}+ +hexPredicate :: Flag -> Maybe String+hexPredicate (Hex x) = Just x+hexPredicate _ = Nothing++{-DHUN| predicate for the "server" option. see atMostOne and exactlyOne functions for details DHUN-}++serverPredicate :: Flag -> Maybe String+serverPredicate (Server x) = Just x+serverPredicate _ = Nothing+ +{-DHUN| predicate for the "paper" option. see atMostOne and exactlyOne functions for details DHUN-}++paperPredicate :: Flag -> Maybe String+paperPredicate (Paper x) = Just x+paperPredicate _ = Nothing+ +{-DHUN| default images resolution. All images with a right resolution will be dithered to this resolution unless is is overridden with the "resolution"  command line option DHUN-}++defaultResolution :: Integer+defaultResolution = 300+ +{-DHUN| the default paper format DHUN-}++defaultPaper :: String+defaultPaper = "A4"++{-DHUN| function to count the number of given command lines options which are part of a certain set of possible command line options. Takes a Maybe value representing whether the command line option is present and returns 1 on Just and 0 otherwise DHUN-}++maybeToInt :: (Num a) => Maybe t -> a+maybeToInt (Just _) = 1+maybeToInt _ = 0++{-DHUN| function to count the number of given command lines option which are part of a certain set of possible command line options. Takes a Bool values representing whether the command line option is present and returns 1 on True and 0 otherwise DHUN-}++boolToInt :: (Num a) => Bool -> a+boolToInt True = 1+boolToInt _ = 0+ +{-DHUN| Caculates a configuration information for the run of program from the options given on the command line. It takes the pathname of the current working directory as first input parameter. It takes the (getopt parsed) command line as second input parameter.It returns an Either Monad. In case the command line made sence the Right type containg the configuation is returned otherwise the Left values with a Error Values desribing the problem is returned DHUN-}++checkOpts :: FilePath -> [Flag] -> Either MyError FullConfig+checkOpts cwd o+  = do serverVal <- atMostOne serverPredicate serverOption o+       case serverVal of+           Just x -> case reads x of+                         [(z, _)] -> return+                                       FullConfig{resolution = 300, outputFilename = "",+                                                  inputUrl = "", runMode = ImperativeState.HTML,+                                                  paper = "A4", vector = False,+                                                  ImperativeState.copy = Nothing, mainPath = "",+                                                  server = Just z}+                         _ -> Left (NotIntegerError serverOption)+           _ -> do hexVal <- atMostOne hexPredicate hexen o+                   case hexVal of+                       Just x -> return ((read . unhex) x)+                       _ -> do resolutionOpt <- atMostOne resolutionPredicate+                                                  resolutionOption+                                                  o+                               resolutionVal <- case resolutionOpt of+                                                    (Just x) -> case reads x of+                                                                    [(z, _)] -> Right z+                                                                    _ -> Left+                                                                           (NotIntegerError+                                                                              resolutionOption)+                                                    _ -> Right defaultResolution+                               outputVal <- exactlyOne outputPredicate output o+                               inputVal <- exactlyOne inputPredicate url o+                               templatesVal <- atMostOne templatesPredicate templates o+                               copyVal <- atMostOne copyPredicate copyOption o+                               paperOpt <- atMostOne paperPredicate paperOption o+                               paperVal <- case paperOpt of+                                               Just x -> if+                                                           x `elem`+                                                             ["A4", "A5", "B5", "letter", "legal",+                                                              "executive"]+                                                           then Right x else Left PaperError+                                               _ -> Right defaultPaper+                               let mediaWikiVal = (MediaWiki `elem` o)+                               let htmlVal = (Main.HTML `elem` o)+                               let temVal = (Main.InternalTemplates `elem` o)+                               let vectorVal = (Main.Vector `elem` o)+                               let mysum+                                     = (boolToInt temVal) + (boolToInt mediaWikiVal) ++                                         (boolToInt htmlVal)+                                         + (maybeToInt templatesVal)+                               if mysum > 1 then Left ToManyOptionsError else Right ()+                               runModeVal <- if mysum == (1 :: Integer) then+                                               case templatesVal of+                                                   Just xx -> Right (UserTemplateFile xx)+                                                   _ -> if mediaWikiVal then Right ExpandedTemplates+                                                          else+                                                          if htmlVal then Right ImperativeState.HTML+                                                            else Right (StandardTemplates)+                                               else Right ImperativeState.HTML+                               return+                                 (FullConfig{resolution = resolutionVal, outputFilename = outputVal,+                                             inputUrl = inputVal, runMode = runModeVal,+                                             paper = paperVal, vector = vectorVal,+                                             copy = copyVal >>= (return . (cwd </>)),+                                             mainPath = cwd ++ (if os=="linux" then "" else "\\"), server = Nothing})+ +{-DHUN| main entry point of mediawiki2latex DHUN-}++main :: IO ()+main+  = do a <- getArgs+       o <- compilerOpts a+       printVersion o+       cwd <- getCurrentDirectory+       case (checkOpts cwd (fst o)) of+           Right x -> case (server x) of+                          Just zz -> serve zz+                          _ -> do (xx, _) <- (runStateT (runErrorT (All.all x))+                                                imperativeStateZero)+                                  case xx of+                                      Left n -> print n+                                      _ -> return ()+           Left y -> print y+       return ()++