{-# LANGUAGE OverloadedStrings #-} module Database.Design.Ampersand.Output.PandocAux ( writepandoc , XRefObj(..) , xRefTo, xRefToLatexRefString , headerWithLabel , definitionListItemLabel , pandocEqnArray , pandocEqnArrayWithLabels , pandocEqnArrayWithLabel , pandocEquation , pandocEquationWithLabel , uniquecds , count , ShowMath(..) , latexEscShw, escapeNonAlphaNum , xrefCitation , texOnly_Id , texOnly_fun , texOnly_rel ) where import Database.Design.Ampersand.ADL1 import Database.Design.Ampersand.FSpec import Data.Char hiding (Space) import Text.Pandoc import Text.Pandoc.Builder import Database.Design.Ampersand.Core.AbstractSyntaxTree import Database.Design.Ampersand.Basics hiding (hPutStrLn) import Prelude hiding (writeFile,readFile,getContents,putStr,putStrLn) import Database.Design.Ampersand.Misc import System.Process (system) import System.Exit (ExitCode(ExitSuccess,ExitFailure)) import System.FilePath -- (combine,addExtension,replaceExtension) import System.Directory import System.Info (os) import Data.Monoid import Data.List import Control.Monad import Data.Maybe fatal :: Int -> String -> a fatal = fatalMsg "Output.PandocAux" -- | Default key-value pairs for use with the Pandoc template defaultWriterVariables :: FSpec -> [(String , String)] defaultWriterVariables fSpec = [ ("title", (case (fsLang fSpec, diagnosisOnly (getOpts fSpec)) of (Dutch , False) -> "Functionele Specificatie van " (English, False) -> "Functional Specification of " (Dutch , True) -> "Diagnose van " (English, True) -> "Diagnosis of " )++name fSpec) -- , ("mainfont", -- , ("sansfont", -- , ("monofont", -- , ("mathfont", , ("fontsize", "10pt,a4paper") --can be overridden by geometry package (see below) , ("lang" , case fsLang fSpec of Dutch -> "dutch" English -> "english") , ("mainlang", case fsLang fSpec of Dutch -> "dutch" English -> "english") , ("documentclass","report") ] ++ [ ("toc" , "<>") | not (diagnosisOnly (getOpts fSpec))]++ [ ("header-includes", unlines [ "% ============Ampersand specific Begin=================" , "% First a couple of LaTeX packages are included:" , "" , "% The glossaries package supports acronyms and multiple glossaries" , "\\usepackage[toc]{glossaries} % Add the glossaries to the table of contents" , "\\makeglossaries" , "" , "% geometry provides a flexible and easy interface to page dimentions" , "\\usepackage[ top=1.5cm, bottom=1.5cm, outer=5cm, inner=2cm" , " , heightrounded, footskip=.5cm" , " , marginparwidth=2.5cm, marginparsep=0.5cm]{geometry}" , "" , "% breqn – Automatic line breaking of displayed equations" , "\\usepackage{breqn}" , "" , "% colonequals – Colon equals symbols" , "\\usepackage{colonequals}" , "" , "" , "\\usepackage{textcomp}" , "% == [all]{hypcap} after {hyperref} shows the ref'd picture i.o. the caption @ click ==" , "" , "\\usepackage[all]{hypcap}" , "" , "% hack1) For the purpose of clear references in Latex. See also https://github.com/AmpersandTarski/ampersand/issues/31" , "\\makeatletter" , "\\let\\orgdescriptionlabel\\descriptionlabel" , "\\renewcommand*{\\descriptionlabel}[1]{%" , " \\let\\orglabel\\label" , " \\let\\label\\@gobble" , " \\phantomsection" , " \\edef\\@currentlabel{#1}%" , " %\\edef\\@currentlabelname{#1}%" , " \\let\\label\\orglabel" , " \\orgdescriptionlabel{#1}%" , "}" , "\\makeatother" , "% End-hack1" , "" , "% hack2) The LaTeX commands \\[ and \\], are redefined in the amsmath package, making sure that ecuations are" , "% not numbered. This is undesireable behaviour. this is fixed with the following hack, inspired on a note" , "% found at http://tex.stackexchange.com/questions/40492/what-are-the-differences-between-align-equation-and-displaymath" , "\\DeclareRobustCommand{\\[}{\\begin{equation}}" , "\\DeclareRobustCommand{\\]}{\\end{equation}}" , "% End-hack2" , "" , "" , "\\def\\id#1{\\mbox{\\em #1\\/}}" , "\\newcommand{\\marge}[1]{\\marginpar{\\begin{minipage}[t]{3cm}{\\noindent\\small\\em #1}\\end{minipage}}}" , "\\def\\define#1{\\label{dfn:#1}\\index{#1}{\\em #1}}" , "\\def\\defmar#1{\\label{dfn:#1}\\index{#1}\\marge{#1}{\\em #1}}" , "\\newcommand{\\iden}{\\mathbb{I}}" , "\\newcommand{\\ident}[1]{\\mathbb{I}_{#1}}" , "\\newcommand{\\full}{\\mathbb{V}}" , "\\newcommand{\\fullt}[1]{\\mathbb{V}_{[#1]}}" , "\\newcommand{\\flip}[1]{{#1}^\\smallsmile} %formerly: {#1}^\\backsim" , "\\newcommand{\\kleeneplus}[1]{{#1}^{+}}" , "\\newcommand{\\kleenestar}[1]{{#1}^{*}}" , "\\newcommand{\\asterisk}{*}" , "\\newcommand{\\cmpl}[1]{\\overline{#1}}" , "\\newcommand{\\subs}{\\vdash}" , "\\newcommand{\\rel}{\\times}" , "\\newcommand{\\fun}{\\rightarrow}" , "\\newcommand{\\isa}{\\sqsubseteq}" , "\\newcommand{\\N}{\\mbox{\\msb N}}" , "\\newcommand{\\disjn}[1]{\\id{disjoint}(#1)}" , "\\newcommand{\\fsignat}[3]{\\id{#1}:\\id{#2}\\fun\\id{#3}}" , "\\newcommand{\\signat}[3]{\\id{#1}:\\id{#2}\\rel\\id{#3}}" , "\\newcommand{\\signt}[2]{\\mbox{\\({#1}_{[{#2}]}\\)}}" , "\\newcommand{\\declare}[3]{\\id{#1}:\\ \\id{#2}\\rel\\id{#3}}" , "\\newcommand{\\fdeclare}[3]{\\id{#1}:\\ \\id{#2}\\fun\\id{#3}}" , "% ============Ampersand specific End===================" ]) | fspecFormat (getOpts fSpec) == FLatex ] --DESCR -> functions to write the pandoc -- String = the name of the outputfile -- The first IO() is a Pandoc output format -- The second IO(): If the output format is latex, then this IO() generates a .pdf from the .tex writepandoc :: FSpec -> Pandoc -> (String,IO(),IO()) writepandoc fSpec thePandoc = (outputFile,makeOutput,postProcessMonad) where outputFile = addExtension (combine (dirOutput (getOpts fSpec)) (baseName (getOpts fSpec))) (case fspecFormat (getOpts fSpec) of Fasciidoc -> ".txt" Fcontext -> ".context" Fdocbook -> ".docbook" Fman -> ".man" Fmarkdown -> ".md" Fmediawiki -> ".mediawiki" Forg -> ".org" Fplain -> ".plain" Frst -> ".rst" FPandoc -> ".pandoc" Frtf -> ".rtf" FLatex -> ".tex" Fhtml -> ".html" Fopendocument -> ".odt" Ftexinfo -> ".texinfo" Ftextile -> ".textile" ) makeOutput = do template <- readDefaultTemplate fSpecFormatString verboseLn (getOpts fSpec) ("Generating "++fSpecFormatString++" to : "++outputFile) --verboseLn (getOpts fSpec) "Variables to set in the template:" --verboseLn (getOpts fSpec) (intercalate "\n " (map show (writerVariables (writerOptions template)))) writeFile outputFile (pandocWriter (writerOptions template) thePandoc) verboseLn (getOpts fSpec) "... done." where pandocWriter :: WriterOptions -> Pandoc -> String pandocWriter = case fspecFormat (getOpts fSpec) of Fasciidoc -> fatal 145 "No current support for asciidoc" FPandoc -> writeNative Fcontext -> writeConTeXt Fdocbook -> writeDocbook Fhtml -> writeHtmlString FLatex -> writeLaTeX Fman -> writeMan Fmarkdown -> writeMarkdown Fmediawiki -> writeMediaWiki Fopendocument -> writeOpenDocument Forg -> writeOrg Fplain -> writePlain Frst -> writeRST Frtf -> writeRTF Ftexinfo -> writeTexinfo Ftextile -> writeTextile fSpecFormatString :: String fSpecFormatString = case fspecFormat (getOpts fSpec) of FPandoc -> "pandoc" Fasciidoc -> "asciidoc" Fcontext -> "context" Fdocbook -> "docbook" Fhtml -> "html" FLatex -> "latex" Fman -> "man" Fmarkdown -> "markdown" Fmediawiki -> "mediawiki" Fopendocument -> "opendocument" Forg -> "org" Fplain -> "plain" Frst -> "rst" Frtf -> "rtf" Ftexinfo -> "texinfo" Ftextile -> "textile" readDefaultTemplate :: String -> IO(Maybe String) readDefaultTemplate s = do { let fp = ampersandDataDir (getOpts fSpec) ".." "outputTemplates" "default."++s ; exists <- doesFileExist fp ; (if exists then do verboseLn (getOpts fSpec) $ "Using Template: "++fp contents <- readFile fp return $ Just contents else do putStrLn "" putStrLn "***WARNING: ***" putStrLn ("Template file does not exist: "++fp) putStrLn "It was part of the installation of Ampersand." putStrLn "...trying without template, but that isn't likely going to work..." putStrLn " (reinstalling Ampersand should fix this problem...)" putStrLn "***************" return Nothing ) } writerOptions :: Maybe String -> WriterOptions writerOptions template = case theme (getOpts fSpec) of ProofTheme -> ampersandDefaultWriterOptions { writerTableOfContents=False , writerNumberSections=False } _ -> ampersandDefaultWriterOptions where ampersandDefaultWriterOptions = def { writerStandalone=isJust template , writerTableOfContents=True , writerNumberSections=True , writerTemplate=fromMaybe "" template , writerVariables=defaultWriterVariables fSpec} postProcessMonad :: IO() postProcessMonad = case fspecFormat (getOpts fSpec) of FLatex -> do (ready,nrOfRounds) <- doRestOfPdfLatex (False, 0) -- initialize with: (, <0 rounds so far>) verboseLn (getOpts fSpec) ("PdfLatex was called "++ (if nrOfRounds>1 then show nrOfRounds++" times" else "once")++ if ready then "." else ", but did not solve all references!") where doRestOfPdfLatex :: (Bool,Int) -> IO (Bool,Int) doRestOfPdfLatex (ready, roundsSoFar) = if ready || roundsSoFar > 4 -- Make sure we will not hit a loop when something is wrong with call to pdfLatex ... then return (ready, roundsSoFar) else do result <- callPdfLatexOnce let logFileName = replaceExtension outputFile ("log"++show roundsSoFar) renameFile (replaceExtension outputFile "log") logFileName logFileLines <- fmap lines $ readFile logFileName {- Old comment: The log file should be renamed before reading, because readFile opens the file for lazy IO. In a next run, pdfLatex will try to write to the log file again. If it was read using readFile, it will fail because the file is still open. 8-(( -} case result of ExitSuccess -> verboseLn (getOpts fSpec) "PDF file created." ExitFailure _ -> do { let nrOfErrLines = 15 ; putStrLn "----------- LaTeX error-----------" -- get rid of latex memory info and take required nr of lines ; let reverseErrLines = take nrOfErrLines . drop 2 . dropWhile (not . ("Here is how much of TeX's memory you used:" `isPrefixOf`)) . reverse $ logFileLines ; putStrLn $ unlines . reverse $ reverseErrLines ; putStrLn "----------------------------------\n" ; putStrLn $ "ERROR: Latex execution failed." ; putStrLn $ "For more information, run pdflatex on: "++texFilename ; putStrLn $ "Or consult the log file:\n"++logFileName } -- We need to rerun latex if any of the log lines start with a rerunPrefix let notReady = result == ExitSuccess && or [ rerunPrefix `isPrefixOf` line | line <- logFileLines , rerunPrefix <- [ "LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right." , "Package longtable Warning: Table widths have changed. Rerun LaTeX." ] ] when notReady (verboseLn (getOpts fSpec) "Another round of pdfLatex is required. Hang on...") -- when notReady (dump "log") -- Need to dump the last log file, otherwise pdfLatex cannot write its log. doRestOfPdfLatex (not notReady, roundsSoFar +1) texFilename = addExtension (baseName (getOpts fSpec)) ".tex" callPdfLatexOnce :: IO ExitCode callPdfLatexOnce = do if os `elem` ["mingw32","mingw64","cygwin","windows"] --REMARK: not a clear enum to check for windows OS then do { res <- system ( pdfLatexCommand++"> "++combine (dirOutput (getOpts fSpec)) "pdflog" ) ; if res /= ExitSuccess then return res else system makeIndexCommand -- TODO: failure of makeindex is not reported correctly (requires refactoring command execution) } --REMARK: MikTex is windows; Tex-live does not have the flag -include-directory. else system ( "cd "++dirOutput (getOpts fSpec)++ " && pdflatex "++commonFlags++ texFilename ++ "> "++addExtension(baseName (getOpts fSpec)) ".pdflog" ) -- >> system makeIndexCommand -- disabled makeIndexCommand on non-windows, since it will always fail when absolute paths are used -- For some weird Latex reason this can only be avoided by setting an environment variable. where pdfLatexCommand = "pdflatex "++commonFlags++pdfgetOpts++ outputFile --makeIndexCommand = "makeglossaries "++replaceExtension outputFile "glo" --makeindex uses the error stream for verbose stuff... makeIndexCommand = "makeindex -s "++replaceExtension outputFile "ist"++" -t "++replaceExtension outputFile "glg"++" -o "++replaceExtension outputFile "gls"++" "++replaceExtension outputFile "glo 2> "++combine (dirOutput (getOpts fSpec)) "glossaries.log" pdfgetOpts = " -include-directory="++dirOutput (getOpts fSpec)++ " -output-directory="++dirOutput (getOpts fSpec)++" " commonFlags = "--halt-on-error --interaction=nonstopmode " -- MacTex options are normally with one '-', but '--interaction' is accepted -- we don't do --disable-installer on Windows, so the install dialog will pop up, even when we are in nonstopmode _ -> return() -----Linguistic goodies-------------------------------------- count :: Lang -> Int -> String -> String count lang n x = case (lang, n) of (Dutch , 0) -> "geen "++plural Dutch x (Dutch , 1) -> "één "++x (Dutch , 2) -> "twee "++plural Dutch x (Dutch , 3) -> "drie "++plural Dutch x (Dutch , 4) -> "vier "++plural Dutch x (Dutch , 5) -> "vijf "++plural Dutch x (Dutch , 6) -> "zes "++plural Dutch x (Dutch , _) -> show n++" "++plural Dutch x (English, 0) -> "no "++plural English x (English, 1) -> "one "++x (English, 2) -> "two "++plural English x (English, 3) -> "three "++plural English x (English, 4) -> "four "++plural English x (English, 5) -> "five "++plural English x (English, 6) -> "six "++plural English x (English, _) -> show n++" "++plural English x ------ Symbolic referencing --------------------------------- data XRefObj = XRefNaturalLanguageDeclaration Declaration | XRefPredicateXpression Rule | XRefNaturalLanguageConcept A_Concept | XRefDataAnalRule Rule | XRefNaturalLanguageRule Rule | XRefProcessAnalysis Pattern | XRefProcessAnalysisDeclaration Declaration | XRefConceptualAnalysisPattern Pattern | XRefConceptualAnalysisDeclaration Declaration | XRefConceptualAnalysisRule Rule | XRefInterfacesInterface Interface | XRefNaturalLanguageTheme (Maybe Pattern) xRefTo :: XRefObj -> Inlines xRefTo x = rawInline "latex" $ xRefToLatexRefString x xRefToLatexRefString :: XRefObj -> String xRefToLatexRefString x = "\\ref{"++xRefRawLabel x++"}" xRefRawLabel :: XRefObj -> String xRefRawLabel x = case x of XRefNaturalLanguageDeclaration d -> "natLangDcl:"++(escapeNonAlphaNum.fullName) d XRefPredicateXpression r -> "pex:"++(escapeNonAlphaNum.name) r XRefNaturalLanguageConcept c -> "natLangCpt:"++(escapeNonAlphaNum.name) c XRefDataAnalRule r -> "dataAnalRule:"++(escapeNonAlphaNum.name) r XRefNaturalLanguageRule r -> "natLangRule:"++(escapeNonAlphaNum.name) r XRefProcessAnalysis p -> "prcAnal:"++(escapeNonAlphaNum.name) p XRefProcessAnalysisDeclaration d -> "prcAnalDcl:"++(escapeNonAlphaNum.fullName) d XRefConceptualAnalysisPattern p -> "cptAnalPat:"++(escapeNonAlphaNum.name) p XRefConceptualAnalysisDeclaration d -> "cptAnalDcl:"++(escapeNonAlphaNum.fullName) d XRefConceptualAnalysisRule r -> "cptAnalRule:"++(escapeNonAlphaNum.name) r XRefInterfacesInterface i -> "interface:"++(escapeNonAlphaNum.name) i XRefNaturalLanguageTheme (Just t) -> "theme:"++(escapeNonAlphaNum.name) t XRefNaturalLanguageTheme Nothing -> ":losseEindjes" where fullName d = name d++"*"++(name.source) d++"*"++(name.target) d headerWithLabel :: XRefObj -> Int -> Inlines -> Blocks headerWithLabel x = headerWith (xRefRawLabel x, [],[]) definitionListItemLabel :: XRefObj -> String -> Inlines definitionListItemLabel x prefix = str prefix <> rawInline "latex" ("\\label{"++xRefRawLabel x++"}") xrefCitation :: String -> Inline -- uitbreidbaar voor andere rendering dan LaTeX xrefCitation myLabel = RawInline (Text.Pandoc.Builder.Format "latex") ("\\cite{"++escapeNonAlphaNum myLabel++"}") pandocEqnArray :: [[String]] -> [Block] pandocEqnArray [] = [] pandocEqnArray xs = (toList . para . displayMath) ( "\\begin{aligned}\n" ++ intercalate "\\\\\n " [ intercalate "&" row | row <-xs ] ++"\n\\end{aligned}" ) pandocEqnArrayWithLabels :: [(XRefObj,[String])] -> Blocks pandocEqnArrayWithLabels [] = mempty pandocEqnArrayWithLabels rows = (para .displayMath) ( "\\begin{aligned}\n" ++ intercalate "\\\\\n " [ intercalate "&" row ++ "\\label{"++xRefRawLabel x++"}" | (x,row)<-rows ] ++"\n\\end{aligned}" ) pandocEqnArrayWithLabel :: XRefObj -> [[String]] -> Blocks pandocEqnArrayWithLabel _ [] = mempty pandocEqnArrayWithLabel xref rows = (para . displayMath) ( "\\label{"++xRefRawLabel xref++"}\\begin{aligned}\\\\\n" ++ intercalate "\\\\\n " [ intercalate "&" row | row <- rows ] ++"\n\\end{aligned}" ) pandocEquation :: String -> [Block] pandocEquation x = toList . para . displayMath $ x pandocEquationWithLabel :: XRefObj -> String -> Blocks pandocEquationWithLabel xref x = para . displayMath $ ( "\\begin{aligned}\\label{"++xRefRawLabel xref++"}\\\\\n" ++x ++"\n\\end{aligned}" ) --DESCR -> pandoc print functions for Ampersand data structures --------------------------------------- -- LaTeX math markup --------------------------------------- class ShowMath a where showMath :: a -> String instance ShowMath A_Concept where showMath c = texOnly_Id (name c) instance ShowMath A_Gen where showMath g@Isa{} = showMath (genspc g)++"\\ \\le\\ "++showMath (gengen g) showMath g@IsE{} = showMath (genspc g)++"\\ =\\ "++intercalate "\\cap" (map showMath (genrhs g)) instance ShowMath Rule where showMath r = showMath (rrexp r) instance ShowMath Sign where showMath (Sign s t) = showMath s++"\\rel"++showMath t instance ShowMath Expression where showMath = showExpr . insParentheses where showExpr (EEqu (l,r)) = showExpr l++texOnly_equals++showExpr r showExpr (EImp (l,r)) = showExpr l++texOnly_subs++showExpr r showExpr (EIsc (l,r)) = showExpr l++texOnly_inter++showExpr r showExpr (EUni (l,r)) = showExpr l++texOnly_union++showExpr r showExpr (EDif (l,r)) = showExpr l++texOnly_bx ++showExpr r showExpr (ELrs (l,r)) = showExpr l++texOnly_lRes++showExpr r showExpr (ERrs (l,r)) = showExpr l++texOnly_rRes++showExpr r showExpr (EDia (l,r)) = showExpr l++texOnly_dia++showExpr r showExpr (ECps (EEps i sgn,r)) | i==source sgn||i==target sgn = showExpr r | otherwise = showExpr (ECps (EDcI i,r)) showExpr (ECps (l,EEps i sgn)) | i==source sgn||i==target sgn = showExpr l | otherwise = showExpr (ECps (l,EDcI i)) showExpr (ECps (l,r)) = showExpr l++texOnly_compose++showExpr r showExpr (ERad (l,r)) = showExpr l++texOnly_relAdd++showExpr r showExpr (EPrd (l,r)) = showExpr l++texOnly_crtPrd++showExpr r showExpr (EKl0 e) = showExpr (addParensToSuper e)++"^{"++texOnly_star++"}" showExpr (EKl1 e) = showExpr (addParensToSuper e)++"^{"++texOnly_plus++"}" showExpr (EFlp e) = showExpr (addParensToSuper e)++"^{"++texOnly_flip++"}" showExpr (ECpl e) = "\\cmpl{"++showExpr e++"}" showExpr (EBrk e) = "("++showExpr e++")" showExpr (EDcD d) = "\\id{"++name d++"}" showExpr (EDcI c) = "I_{\\id{"++name c++"}}" showExpr EEps{} = "" -- fatal 417 "EEps may occur only in combination with composition (semicolon)." -- SJ 2014-03-11: Are we sure about this? Let's see if it ever occurs... showExpr (EDcV sgn) = "V_{\\id{"++show (source sgn)++"}\\times\\id{"++show (target sgn)++"}}" showExpr (EMp1 a _) = "'{\\tt "++a++"}'" -- add extra parentheses to consecutive superscripts, since latex cannot handle these -- (this is not implemented in insParentheses because it is a latex-specific issue) addParensToSuper :: Expression -> Expression addParensToSuper e@EKl0{} = EBrk e addParensToSuper e@EKl1{} = EBrk e addParensToSuper e@EFlp{} = EBrk e addParensToSuper e = e instance ShowMath Declaration where showMath decl@(Sgn{}) = "\\declare{"++latexEscShw(name decl)++"}{"++latexEscShw(name (source decl))++"}{"++latexEscShw(name (target decl))++"}" showMath Isn{} = "\\mathbb{I}" showMath Vs{} = "\\full" -- | latexEscShw escapes to LaTeX encoding. It is intended to be used in LaTeX text mode. -- For more elaborate info on LaTeX encoding, consult the The Comprehensive LATEX Symbol List -- on: http://ftp.snt.utwente.nl/pub/software/tex/info/symbols/comprehensive/symbols-a4.pdf latexEscShw :: String -> String latexEscShw "" = "" latexEscShw ('\"':c:cs) | isAlphaNum c = "``"++latexEscShw (c:cs) | otherwise = "''"++latexEscShw (c:cs) latexEscShw "\"" = "''" latexEscShw (c:cs) | isAlphaNum c && isAscii c = c:latexEscShw cs | otherwise = f c++latexEscShw cs where f '"' = "\\textquotedbl " f '#' = "\\#" f '$' = "\\$" f '%' = "\\%" f '&' = "\\&" f '\\'= "\\textbackslash " f '^' = "\\^{}" f '_' = "\\_" f '{' = "\\{" f '|' = "\\textbar " f '}' = "\\}" f '~' = "\\~{}" f '¦' = "\\textbrokenbar " f '¨' = "\\textasciidieresis " f '¯' = "\\textasciimacron " f '´' = "\\textasciiacute " f '¢' = "\\textcent " f '£' = "\\textpound " f '¤' = "\\textcurrency " f '¥' = "\\textyen " f '€' = "\\texteuro " f '<' = "\\textless " f '>' = "\\textgreater " f '±' = "\\textpm " f '«' = "\\guillemotleft " f '»' = "\\guillemotright " f '×' = "\\texttimes " f '÷' = "\\textdiv " f '§' = "\\S " f '©' = "\\textcopyright " f '¬' = "\\textlnot " f '®' = "\\textregistered " f '°' = "\\textdegree " f 'µ' = "\\textmu " f '¶' = "\\P " f '·' = "\\textperiodcentered " f '¼' = "\\textonequarter " f '½' = "\\textonehalf " f '¾' = "\\textthreequarters " f '¹' = "\\textonesuperior " f '²' = "\\texttwosuperior " f '³' = "\\textthreesuperior " f '∞' = "\\hbipropto " f 'ä' = "\\\"{a}" -- umlaut or dieresis f 'Ä' = "\\\"{A}" -- umlaut or dieresis f 'â' = "\\^{a}" -- circumflex f 'Â' = "\\^{A}" -- circumflex f 'à' = "\\`{a}" -- grave accent f 'À' = "\\`{A}" -- grave accent f 'á' = "\\'{a}" -- acute accent f 'Á' = "\\'{A}" -- acute accent f 'ã' = "\\~{a}" -- tilde f 'Ã' = "\\~{A}" -- tilde f 'å' = "\\aa " -- f 'å' = "\\r{a}" -- alternatively: ring over the letter f 'Å' = "\\AA " -- f 'Å' = "\\r{A}" -- alternatively: ring over the letter f 'ą' = "\\k{a}" -- ogonek f 'Ą' = "\\k{A}" -- ogonek f 'ª' = "\\textordfeminine " f 'æ' = "\\ae " f 'Æ' = "\\AE " f 'ç' = "\\c{c}" -- cedilla f 'Ç' = "\\c{C}" -- cedilla f 'Ð' = "\\DH " f 'ð' = "\\dh " f 'ë' = "\\\"{e}" -- umlaut or dieresis f 'Ë' = "\\\"{E}" -- umlaut or dieresis f 'ê' = "\\^{e}" -- circumflex f 'Ê' = "\\^{E}" -- circumflex f 'è' = "\\`{e}" -- grave accent f 'È' = "\\`{E}" -- grave accent f 'é' = "\\'{e}" -- acute accent f 'É' = "\\'{E}" -- acute accent f 'ï' = "\\\"{\\i}" -- umlaut or dieresis f 'Ï' = "\\\"{I}" -- umlaut or dieresis f 'î' = "\\^{\\i}" -- circumflex f 'Î' = "\\^{I}" -- circumflex f 'ì' = "\\`{\\i}" -- grave accent f 'Ì' = "\\`{I}" -- grave accent f 'í' = "\\'{\\i}" -- acute accent f 'Í' = "\\'{I}" -- acute accent f 'ł' = "\\l " -- l with stroke f 'Ł' = "\\L " -- l with stroke f 'n' = "\\~{n}" -- tilde f 'Ñ' = "\\~{N}" -- tilde f 'Ȯ' = "\\.{O}" -- dot over the letter f 'ȯ' = "\\.{o}" -- dot over the letter f 'ö' = "\\\"{o}" -- umlaut or dieresis f 'Ö' = "\\\"{O}" -- umlaut or dieresis f 'ô' = "\\^{o}" -- circumflex f 'Ô' = "\\^{O}" -- circumflex f 'ò' = "\\`{o}" -- grave accent f 'Ò' = "\\`{O}" -- grave accent f 'ó' = "\\'{o}" -- acute accent f 'Ó' = "\\'{O}" -- acute accent f 'õ' = "\\~{o}" -- tilde f 'Õ' = "\\~{O}" -- tilde f 'ō' = "\\={o}" -- macron accent a bar over the letter) f 'Ō' = "\\={O}" -- macron accent a bar over the letter) f 'ő' = "\\H{o}" -- long Hungarian umlaut double acute) f 'Ő' = "\\H{O}" -- long Hungarian umlaut double acute) f 'Ø' = "\\O " f 'ø' = "\\o " f 'º' = "\\textordmasculine " f 'ŏ' = "\\u{o}" -- breve over the letter f 'Ŏ' = "\\u{O}" -- breve over the letter f 'œ' = "\\oe " f 'Œ' = "\\OE " f 'š' = "\\v{s}" -- caron/hacek "v") over the letter f 'Š' = "\\v{S}" -- caron/hacek "v") over the letter f 'ß' = "\\ss " f 'Þ' = "\\TH " f 'þ' = "\\th " f '™' = "\\texttrademark " f 'ü' = "\\\"{u}" -- umlaut or dieresis f 'Ü' = "\\\"{U}" -- umlaut or dieresis f 'û' = "\\^{u}" -- circumflex f 'Û' = "\\^{U}" -- circumflex f 'ù' = "\\`{u}" -- grave accent f 'Ù' = "\\`{U}" -- grave accent f 'ú' = "\\'{u}" -- acute accent f 'Ú' = "\\'{U}" -- acute accent f 'ý' = "\\'{y}" -- acute accent f 'Ý' = "\\'{Y}" -- acute accent f _ = [c] -- let us think if this should be: fatal 661 ("Symbol "++show x++" (character "++show (ord c)++") is not supported") --posixFilePath :: FilePath -> String -- tex uses posix file notation, however when on a windows machine, we have windows conventions for file paths... -- To set the graphicspath, we want something like: \graphicspath{{"c:/data/Ampersand/output/"}} --posixFilePath fp = "/"++System.FilePath.Posix.addTrailingPathSeparator (System.FilePath.Posix.joinPath (tail (splitDirectories fp))) uniquecds :: FSpec -> A_Concept -> [(String,ConceptDef)] uniquecds fSpec c = [ (if length cDefs==1 then cdcpt cd else cdcpt cd++show i , cd) | let cDefs=concDefs fSpec c , (i,cd)<-zip [(1::Integer)..] cDefs ] -- was: [(if length(cptdf c)==1 then cdcpt cd else cdcpt cd++show i , cd) | (i,cd)<-zip [(1::Integer)..] (cptdf c)] --makeDefinition :: Options -> Int -> String -> String -> String -> String -> [Block] --makeDefinition opts i nm lbl defin ref = -- case fspecFormat opts of -- FLatex -> [ Para ( [ RawInline (Text.Pandoc.Builder.Format "latex") $ "\\newglossaryentry{"++escapeNonAlphaNum nm ++"}{name={"++latexEscShw nm ++"}, description={"++latexEscShw defin++"}}\n"] ++ -- [ RawInline (Text.Pandoc.Builder.Format "latex") $ lbl ++ "\n" | i == 0] ++ -- [ RawInline (Text.Pandoc.Builder.Format "latex") $ insertAfterFirstWord refStr defStr] ++ -- [ RawInline (Text.Pandoc.Builder.Format "latex") (latexEscShw (" ["++ref++"]")) | not (null ref) ] -- ) -- ] -- _ -> [ Para ( Str defin : [ Str (" ["++ref++"]") | not (null ref) ] ) -- ] -- where refStr = "\\marge{\\gls{"++escapeNonAlphaNum nm++"}}" -- defStr = latexEscShw defin -- -- by putting the ref after the first word of the definition, it aligns nicely with the definition -- insertAfterFirstWord s wordsStr = let (fstWord, rest) = break (==' ') wordsStr -- in fstWord ++ s ++ rest --------------------------- --- LaTeX related stuff --- --------------------------- texOnly_Id :: String -> String texOnly_Id s = "\\id{"++latexEscShw s++"} " texOnly_fun :: String texOnly_fun = "\\rightarrow " texOnly_rel :: String texOnly_rel = "\\times " texOnly_compose :: String texOnly_compose = ";" texOnly_relAdd :: String texOnly_relAdd = "\\dagger " texOnly_crtPrd :: String texOnly_crtPrd = "\\asterisk " texOnly_inter :: String texOnly_inter = "\\cap " texOnly_union :: String texOnly_union = "\\cup " texOnly_subs :: String texOnly_subs = "\\vdash " texOnly_equals :: String texOnly_equals = "=" texOnly_star :: String texOnly_star = "^* " texOnly_plus :: String texOnly_plus = "^+ " texOnly_bx :: String texOnly_bx = " - " texOnly_lRes :: String texOnly_lRes = " / " texOnly_rRes :: String texOnly_rRes = " \\backslash " texOnly_dia :: String texOnly_dia = " \\Diamond " texOnly_flip :: String texOnly_flip = "\\smallsmile "