Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# ## #W GAPDoc2LaTeX.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files GAPDoc2LaTeX.g{d,i} contain a conversion program which ## produces from a GAPDoc XML-document a version which can be processed ## by LaTeX and pdfLaTeX. ## ## All the work is done by handler functions for each GAPDoc XML ## element. These functions are bound as components to the record ## `GAPDoc2LaTeXProcs'. Most element markup is easily translated to a ## corresponding LaTeX markup. It should be easy to modify details for ## some elements by small local changes of the corresponding handler ## function. The only slight complications are in places where the XML ## elements imply some labeling or indexing. Also for all (sub)section ## commands we add some commands which cause LaTeX to produce a ## GAP readable .pnr file which contains the page numbers for all ## subsections. InstallValue(GAPDoc2LaTeXProcs, rec()); ## <#GAPDoc Label="GAPDoc2LaTeX"> ## <ManSection > ## <Func Arg="tree" Name="GAPDoc2LaTeX" /> ## <Returns>&LaTeX; document as string</Returns> ## <Func Name="SetGapDocLaTeXOptions" Arg="[...]" /> ## <Returns>Nothing</Returns> ## <Description> ## The argument <A>tree</A> for this function is a tree ## describing a &GAPDoc; XML document as returned by <Ref ## Func="ParseTreeXMLString" /> (probably also checked with <Ref ## Func="CheckAndCleanGapDocTree" />). The output is a string ## containing a version of the document which can be written to a ## file and processed with &LaTeX; or pdf&LaTeX; (and probably ## &BibTeX; and <C>makeindex</C>). <P/> ## ## The output uses the <C>report</C> document class and ## needs the following &LaTeX; packages: <C>a4wide</C>, ## <C>amssymb</C>, <C>inputenc</C>, <C>makeidx</C>, <C>color</C>, ## <C>fancyvrb</C>, <C>psnfss</C>, <C>pslatex</C>, <C>enumitem</C> ## and <C>hyperref</C>. These ## are for example provided by the <Package>teTeX-1.0</Package> ## or <Package>texlive</Package> ## distributions of &TeX; (which in turn are used for ## most &TeX; packages of current Linux distributions); see ## <URL>http://www.tug.org/tetex/</URL>. <P/> ## ## In particular, the resulting <C>pdf</C>-output (and ## <C>dvi</C>-output) ## contains (internal and external) hyperlinks which can be very ## useful for onscreen browsing of the document.<P/> ## ## The &LaTeX; processing also produces a file with extension ## <C>.pnr</C> which is &GAP; readable and contains the page numbers ## for all (sub)sections of the document. This can be used by ## &GAP;'s online help; see <Ref Func="AddPageNumbersToSix" />. ## ## Non-ASCII characters in the &GAPDoc; document are translated to ## &LaTeX; input in ASCII-encoding with the help of <Ref Oper="Encode"/> ## and the option <C>"LaTeX"</C>. See the documentation of ## <Ref Oper="Encode"/> for how to proceed if you have a character which ## is not handled (yet).<P/> ## ## This function works by running recursively through the document ## tree and calling a handler function for each &GAPDoc; ## XML element. Many of these handler functions (usually in ## <C>GAPDoc2LaTeXProcs.<ElementName></C>) are not difficult to ## understand (the greatest complications are some commands for index ## entries, labels or the output of page number information). So it ## should be easy to adjust layout details to your own taste by slight ## modifications of the program. <P/> ## ## Former versions of &GAPDoc; supported some XML processing ## instructions to add some extra lines to the preamble of the &LaTeX; ## document. Its use is now deprecated, use the much more flexible <Ref ## Func="SetGapDocLaTeXOptions" /> instead: ## ## The default layout of the resulting documents can ## be changed with <Ref Func="SetGapDocLaTeXOptions"/>. This ## changes parts of the header of the &LaTeX; file ## produced by &GAPDoc;. You can see the header with ## some placeholders by <C>Page(GAPDoc2LaTeXProcs.Head);</C>. The ## placeholders are filled with components from the record ## <C>GAPDoc2LaTeXProcs.DefaultOptions</C>. The arguments of <Ref ## Func="SetGapDocLaTeXOptions"/> can be records with the same ## structure (or parts of it) with different values. As abbreviations ## there are also three strings supported as arguments. These ## are <C>"nocolor"</C> for switching all colors to black; then ## <C>"nopslatex"</C> to use standard &LaTeX; fonts instead of ## postscript fonts; and finally <C>"utf8"</C> to choose UTF-8 as input ## encoding for the &LaTeX; document. ## ## </Description> ## </ManSection> ## <#/GAPDoc> ## ## <!-- seems to be no longer needed ## A hint for large documents: In many &TeX; installations one can ## easily reach some memory limitations with documents which contain ## many (cross-)references. In <Package>teTeX</Package> you can look ## for a file <F>texmf.cnf</F> which allows to enlarge certain ## memory sizes.<P/> ## --> # the basic call, used recursivly with a result r from GetElement # and a string str to which the output should be appended # arg: r (then a string is returned) # or: r, str (then the output is appended to string str) InstallGlobalFunction(GAPDoc2LaTeX, function(arg) local r, str, name; r := arg[1]; if Length(arg)>1 then str := arg[2]; else AddRootParseTree(r); # reset to defaults in case of interrupted previous call GAPDoc2LaTeXProcs.verbatimPCDATA := false; GAPDoc2LaTeXProcs.recode := true; str := ""; fi; name := r.name; if not IsBound(GAPDoc2LaTeXProcs.(name)) then Info(InfoGAPDoc, 1, "#W WARNING: Don't know how to process element ", name, " ---- ignored\n"); else GAPDoc2LaTeXProcs.(r.name)(r, str); fi; if Length(arg)=1 then return str; fi; end); ## a common recursion loop BindGlobal("GAPDoc2LaTeXContent", function(r, str) local a; for a in r.content do GAPDoc2LaTeX(a, str); od; end); # width of index entries, we use a trick to split longer command names GAPDoc2LaTeXProcs.MaxIndexEntryWidth := 35; # a flag for recoding to LaTeX GAPDoc2LaTeXProcs.recode := true; # two utilities for attribute values like labels or text with special # XML or LaTeX characters which gets printed (always as \texttt text) GAPDoc2LaTeXProcs.EscapeAttrValOld := function(str) local res, c; res := ""; for c in str do if c = '\\' then ## Append(res, "{\\gdttbs}"); Append(res, "\\texttt{\\symbol{92}}"); elif c = '_' then Append(res, "\\_"); elif c = '{' then ## Append(res, "{\\gdttob}"); Append(res, "\\texttt{\\symbol{123}}"); elif c = '}' then ## Append(res, "{\\gdttcb}"); Append(res, "\\texttt{\\symbol{125}}"); elif c = '^' then ## Append(res, "{\\gdttht}"); Append(res, "\\texttt{\\symbol{94}}"); elif c = '~' then ## Append(res, "{\\gdttti}"); Append(res, "\\texttt{\\symbol{126}}"); elif c = '<' then Append(res, "{\\textless}"); elif c = '>' then Append(res, "{\\textgreater}"); elif c = '&' then Append(res, "\\&"); elif c = '%' then Append(res, "\\%"); elif c = '$' then Append(res, "\\$"); elif c = '#' then Append(res, "\\#"); else Add(res, c); fi; od; return res; end; # now via Unicode, handle many more characters as well GAPDoc2LaTeXProcs.EscapeAttrVal := function(str) return Encode(Unicode(str), GAPDoc2LaTeXProcs.Encoder); end; GAPDoc2LaTeXProcs.DeleteUsBs := function(str) return Filtered(str, x-> not (x in "\\_")); end; ## this is for getting a string "[ \"A\", 1, 1 ]" from [ "A", 1, 1 ] GAPDoc2LaTeXProcs.StringNrs := function(ssnr) if IsInt(ssnr[1]) then return String(ssnr); else return Concatenation("[ \"", ssnr[1], "\", ", String(ssnr[2]), ", ", String(ssnr[3]), " ]"); fi; end; GAPDoc2LaTeXProcs.Head := StringFile( Filename(DirectoriesPackageLibrary("gapdoc"),"latexhead.tex")); GAPDoc2LaTeXProcs.Tail := Concatenation( "\\newpage\n", "\\immediate\\write\\pagenrlog{[\"End\"], \\arabic{page}];}\n", "\\immediate\\closeout\\pagenrlog\n", "\\end{document}\n"); GAPDoc2LaTeXProcs.Options := rec(); GAPDoc2LaTeXProcs.DefaultOptions := rec( EarlyExtraPreamble := "", LateExtraPreamble := "", InputEncoding := "latin1", ColorDefinitions := rec( link := "0.0,0.0,0.554", cite := "0.0,0.0,0.554", file := "0.0,0.0,0.554", url := "0.0,0.0,0.554", prompt := "0.0,0.0,0.589", brkprompt := "0.589,0.0,0.0", gapinput := "0.589,0.0,0.0", gapoutput := "0.0,0.0,0.0", funcdefs := "0.0,0.0,0.0", chapter := "0.0,0.0,0.0" ), MoreColors := "\\definecolor{DarkOlive}{rgb}{0.1047,0.2412,0.0064}\n", FontPackages := "\\usepackage{mathptmx,helvet}\n\\usepackage[T1]{fontenc}\n\ \\usepackage{textcomp}\n", HyperrefOptions := rec( pdftex := "true", bookmarks := "true", a4paper := "true", pdftitle := "{Written with GAPDoc}", pdfcreator := "{LaTeX with hyperref package / GAPDoc}", colorlinks := "true", backref := "page", breaklinks := "true", pdfpagemode := "{UseNone}", MoreHyperrefOptions := "" ), TocDepth := "\\setcounter{tocdepth}{1}", Maintitlesize := "\\fontsize{50}{55}\\selectfont", ); # helper function to apply the options to the generic LaTeX head GAPDoc2LaTeXProcs.HeadWithOptions := function(extra) local head, opt, f, ff; head := GAPDoc2LaTeXProcs.Head; opt := GAPDoc2LaTeXProcs.Options; for f in RecNames(opt) do if f = "ColorDefinitions" then for ff in RecNames(opt.(f)) do head := SubstitutionSublist(head, Concatenation("CONFIGCOLOR",ff), opt.(f).(ff)); od; elif f = "HyperrefOptions" then for ff in RecNames(opt.(f)) do head := SubstitutionSublist(head, Concatenation("CONFIGHR",ff), opt.(f).(ff)); od; else head := SubstitutionSublist(head, Concatenation("CONFIG", f), opt.(f)); fi; od; head := SubstitutionSublist(head, "PIExtraPreamble", extra); return head; end; ## arg: a list of strings ## for now only the output type (one of "dvi", "pdf" or "ps") is used # to be enhanced SetGapDocLaTeXOptions := function(arg) local new, recs, r, f, ff; GAPDoc2LaTeXProcs.Options := StructuralCopy(GAPDoc2LaTeXProcs.DefaultOptions); new := GAPDoc2LaTeXProcs.Options; recs := Filtered(arg, IsRecord); # handle some abbreviations if "nocolor" in arg then Add(recs, rec( ColorDefinitions := rec( link := "0.0,0.0,0.0", cite := "0.0,0.0,0.0", file := "0.0,0.0,0.0", url := "0.0,0.0,0.0", prompt := "0.0,0.0,0.0", brkprompt := "0.0,0.0,0.0", gapinput := "0.0,0.0,0.0", gapoutput := "0.0,0.0,0.0", funcdefs := "0.0,0.0,0.0", chapter := "0.0,0.0,0.0" ) ) ); fi; if "utf8" in arg then Add(recs, rec(InputEncoding := "utf8")); fi; if "nopslatex" in arg then Add(recs, rec(FontPackages := "\n")); fi; # now overwrite the defaults for r in recs do for f in RecNames(r) do if IsRecord(r.(f)) then if IsBound(new.(f)) then for ff in RecNames(r.(f)) do if IsBound(new.(f).(ff)) then new.(f).(ff) := r.(f).(ff); fi; od; fi; else if IsBound(new.(f)) then new.(f) := r.(f); fi; fi; od; od; # set encoder accordingly if new.InputEncoding = "utf8" then GAPDoc2LaTeXProcs.Encoder := "LaTeXUTF8"; else GAPDoc2LaTeXProcs.Encoder := "LaTeX"; fi; end; # set defaults SetGapDocLaTeXOptions(); GAPDoc2LaTeXProcs.firstsix := function(r, count) local a; a := PositionSet(r.root.sixcount, count{[1..3]}); if a <> fail then a := r.root.six[r.root.sixindex[a]]; fi; return a; end; ## write head and foot of LaTeX file. GAPDoc2LaTeXProcs.WHOLEDOCUMENT := function(r, str) local i, pi, t, el, a; ## add internal paragraph numbering AddParagraphNumbersGapDocTree(r); ## checking for processing instructions i := 1; pi := rec(); while not r.content[i].name = "Book" do if r.content[i].name = "XMLPI" then t := r.content[i].content; if Length(t) > 5 and t{[1..6]} = "LaTeX " then el := GetSTag(Concatenation("<", t, ">"), 2); for a in NamesOfComponents(el.attributes) do pi.(a) := el.attributes.(a); od; fi; fi; i := i+1; od; ## collect headings of labeled sections, here we must run through the ## whole parse tree first to know the headings of text style forward ## references GAPDoc2LaTeXProcs._labeledSections := rec(); ApplyToNodesParseTree(r, function(rr) if IsRecord(rr) and IsBound(rr.name) and rr.name in ["Chapter", "Section", "Subsection", "Appendix"] then # save heading for "Text" style references to section GAPDoc2LaTeXProcs.(rr.name)(rr,""); fi; end); ## warn if no labels via .six available if not IsBound(r.six) then Info(InfoGAPDoc, 1, "#W WARNING: No labels for section number independent ", "anchors available.\n", "#W Consider running the converter for the text version first!\n"); fi; ## now the actual work starts, we give the found processing instructions ## to the Book handler GAPDoc2LaTeXProcs.Book(r.content[i], str, pi); Unbind(GAPDoc2LaTeXProcs._labeledSections); end; ## comments and processing instructions are generally ignored GAPDoc2LaTeXProcs.XMLPI := function(r, str); end; GAPDoc2LaTeXProcs.XMLCOMMENT := function(r, str); end; # do nothing with Ignore GAPDoc2LaTeXProcs.Ignore := function(arg) end; ## this makes head and foot of the LaTeX output ## - the only processing instructions handled currently are ## - options for the report class (german, papersize, ...) and ## - extra entries in the preamble (\usepackage, macro definitions, ...) GAPDoc2LaTeXProcs.Book := function(r, str, pi) local a; if not IsBound(pi.ExtraPreamble) then pi.ExtraPreamble := ""; fi; Append(str, GAPDoc2LaTeXProcs.HeadWithOptions(pi.ExtraPreamble)); # and now the text of the document GAPDoc2LaTeXContent(r, str); # that's it Append(str, GAPDoc2LaTeXProcs.Tail); end; ## the Body just prints its content GAPDoc2LaTeXProcs.Body := GAPDoc2LaTeXContent; ## the title page, the most complicated looking function GAPDoc2LaTeXProcs.TitlePage := function(r, str) local l, ll, a, s, cont; # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}\n")); Append(str, "\\begin{titlepage}\n\\mbox{}\\vfill\n\n\\begin{center}"); # title l := Filtered(r.content, a-> a.name = "Title"); Append(str, "{\\maintitlesize \\textbf{"); s := ""; GAPDoc2LaTeXContent(l[1], s); Append(str, s); Append(str, "\\mbox{}}}\\\\\n\\vfill\n\n"); # set title in info part of PDF document Append(str, "\\hypersetup{pdftitle="); Append(str, s); Append(str, "}\n"); # the title is also used for the page headings Append(str, "\\markright{\\scriptsize \\mbox{}\\hfill "); Append(str, s); Append(str, " \\hfill\\mbox{}}\n"); # subtitle l := Filtered(r.content, a-> a.name = "Subtitle"); if Length(l)>0 then Append(str, "{\\Huge \\textbf{"); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}}\\\\\n\\vfill\n\n"); fi; # version l := Filtered(r.content, a-> a.name = "Version"); if Length(l)>0 then Append(str, "{\\Huge "); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; # date l := Filtered(r.content, a-> a.name = "Date"); if Length(l)>0 then Append(str, "{"); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; Append(str, "\\mbox{}\\\\[2cm]\n"); # author name(s) l := Filtered(r.content, a-> a.name = "Author"); # collect author list for PDF info ll := []; for a in l do Append(str, "{\\Large \\textbf{"); s := ""; GAPDoc2LaTeXContent(rec(content := Filtered(a.content, b-> not b.name in ["Email", "Homepage", "Address"])), s); Append(str, s); Add(ll, s); Append(str, "\\mbox{}}}\\\\\n"); od; Append(str, "\\hypersetup{pdfauthor="); Append(str, JoinStringsWithSeparator(ll, "; ")); Append(str, "}\n"); # extra comment for front page l := Filtered(r.content, a-> a.name = "TitleComment"); if Length(l) > 0 then Append(str, "\\mbox{}\\\\[2cm]\n\\begin{minipage}{12cm}\\noindent\n"); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\end{minipage}\n\n"); fi; Append(str, "\\end{center}\\vfill\n\n\\mbox{}\\\\\n"); # email, WWW-homepage and address of author(s), if given l := Filtered(r.content, a-> a.name = "Author"); for a in l do cont := List(a.content, b-> b.name); if "Email" in cont or "Homepage" in cont or "Address" in cont then Append(str, "{\\mbox{}\\\\\n\\small \\noindent \\textbf{"); GAPDoc2LaTeXContent(rec(content := Filtered(a.content, b-> not b.name in ["Email", "Homepage", "Address"])), str); Append(str, "}"); if "Email" in cont then Append(str, Concatenation(" ", GAPDocTexts.d.Email, ": ")); GAPDoc2LaTeX(a.content[Position(cont, "Email")], str); fi; if "Homepage" in cont then Append(str, "\\\\\n"); Append(str, Concatenation(" ", GAPDocTexts.d.Homepage, ": ")); GAPDoc2LaTeX(a.content[Position(cont, "Homepage")], str); fi; if "Address" in cont then Append(str, "\\\\\n"); Append(str, Concatenation(" ", GAPDocTexts.d.Address, ": \\begin{minipage}[t]{8cm}\\noindent\n")); GAPDoc2LaTeX(a.content[Position(cont, "Address")], str); Append(str, "\\end{minipage}\n"); fi; Append(str, "}\\\\\n"); fi; od; # Address outside the Author elements l := Filtered(r.content, a-> a.name = "Address"); if Length(l)>0 then Append(str, "\n\\noindent "); Append(str, Concatenation("\\textbf{", GAPDocTexts.d.Address, ": }\\begin{minipage}[t]{8cm}\\noindent\n")); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\end{minipage}\n"); fi; Append(str, "\\end{titlepage}\n\n\\newpage"); # to make physical page numbers same as document page numbers Append(str, "\\setcounter{page}{2}\n"); # abstract l := Filtered(r.content, a-> a.name = "Abstract"); if Length(l)>0 then Append(str, Concatenation("{\\small \n\\section*{", GAPDocTexts.d.Abstract, "}\n")); # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(l[1].count{[1..3]}), "}\n")); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; # copyright page l := Filtered(r.content, a-> a.name = "Copyright"); if Length(l)>0 then Append(str, Concatenation("{\\small \n\\section*{", GAPDocTexts.d.Copyright, "}\n")); # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(l[1].count{[1..3]}), "}\n")); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; # acknowledgement page l := Filtered(r.content, a-> a.name = "Acknowledgements"); if Length(l)>0 then Append(str, Concatenation("{\\small \n\\section*{", GAPDocTexts.d.Acknowledgements, "}\n")); # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(l[1].count{[1..3]}), "}\n")); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; # colophon page l := Filtered(r.content, a-> a.name = "Colophon"); if Length(l)>0 then Append(str, Concatenation("{\\small \n\\section*{", GAPDocTexts.d.Colophon, "}\n")); # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(l[1].count{[1..3]}), "}\n")); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; Append(str,"\\newpage\n\n"); end; ## this allows line breaks in URL strings s for use with \texttt{s} by ## inserting some "}\discretionary{}{}{}\texttt{" GAPDoc2LaTeXProcs.URLBreaks := function(s) local pos, ss, old; # not after :// pos := PositionSublist(s, "://"); if pos = fail then pos := Minimum(3, Length(s)); else pos := pos + 2; fi; ss := s{[1..pos]}; old := pos; pos := Position(s, '/', old); while pos <> fail and pos+3 < Length(s) do Append(ss, s{[old+1..pos]}); Append(ss, "}\\discretionary {}{}{}\\texttt{"); old := pos; pos := Position(s, '/', old); od; Append(ss, s{[old+1..Length(s)]}); return ss; end; ## ~ and # characters are correctly escaped ## arg: r, str[, pre] GAPDoc2LaTeXProcs.Link := GAPDoc2LaTeXContent; GAPDoc2LaTeXProcs.LinkText := GAPDoc2LaTeXContent; GAPDoc2LaTeXProcs.URL := function(arg) local r, str, pre, rr, txt, s; r := arg[1]; str := arg[2]; if Length(arg)>2 then pre := arg[3]; else pre := ""; fi; rr := First(r.content, a-> a.name = "LinkText"); if rr <> fail then txt := ""; GAPDoc2LaTeXContent(rr, txt); rr := First(r.content, a-> a.name = "Link"); if rr = fail then Info(InfoGAPDoc, 1, "#W missing <Link> element for text ", txt, "\n"); s := "MISSINGLINK"; else s := ""; # must avoid recoding for first argument of \href GAPDoc2LaTeXProcs.recode := false; GAPDoc2LaTeXContent(rr, s); GAPDoc2LaTeXProcs.recode := true; fi; else s := ""; GAPDoc2LaTeXProcs.recode := false; GAPDoc2LaTeXContent(r, s); GAPDoc2LaTeXProcs.recode := true; if IsBound(r.attributes.Text) then txt := r.attributes.Text; else # need recode in second argument of \href txt := Encode(Unicode(s, "UTF-8"), GAPDoc2LaTeXProcs.Encoder); txt := Concatenation("\\texttt{", txt, "}"); fi; fi; Append(str, Concatenation("\\href{", pre, s, "} {", txt, "}")); end; GAPDoc2LaTeXProcs.Homepage := GAPDoc2LaTeXProcs.URL; GAPDoc2LaTeXProcs.Email := function(r, str) # we add the `mailto://' phrase GAPDoc2LaTeXProcs.URL(r, str, "mailto://"); end; ## the sectioning commands are just translated and labels are ## generated, if given as attribute GAPDoc2LaTeXProcs.ChapSect := function(r, str, sect) local posh, a, s; posh := Position(List(r.content, a-> a.name), "Heading"); # heading Append(str, Concatenation("\n\\", sect, "{")); s := ""; if posh <> fail then GAPDoc2LaTeXProcs.Heading1(r.content[posh], s); fi; Append(str, "\\textcolor{Chapter }{"); Append(str, s); Append(str, "}}"); # label for references if IsBound(r.attributes.Label) then Append(str, "\\label{"); Append(str, r.attributes.Label); Append(str, "}\n"); # save heading for "Text" style references to section GAPDoc2LaTeXProcs._labeledSections.(r.attributes.Label) := s; fi; # page number info for online help (no r.count below Ignore), # we also add a section number and page number independent label, # if available if IsBound(r.count) then Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}\n")); if IsBound(r.root.six) then ## a := First(r.root.six, x-> x[3] = r.count{[1..3]}); a := GAPDoc2LaTeXProcs.firstsix(r, r.count); if a <> fail and IsBound(a[7]) then Append(str, Concatenation("\\hyperdef{L}{", a[7], "}{}\n")); fi; fi; # the actual content Append(str, "{\n"); GAPDoc2LaTeXContent(r, str); Append(str, "}\n\n"); fi; end; ## this really produces the content of the heading GAPDoc2LaTeXProcs.Heading1 := function(r, str) GAPDoc2LaTeXContent(r, str); end; ## and this ignores the heading (for simpler recursion) GAPDoc2LaTeXProcs.Heading := function(r, str) end; GAPDoc2LaTeXProcs.Chapter := function(r, str) GAPDoc2LaTeXProcs.ChapSect(r, str, "chapter"); end; GAPDoc2LaTeXProcs.Appendix := function(r, str) if r.count[1] = "A" then Append(str, "\n\n\\appendix\n\n"); fi; GAPDoc2LaTeXProcs.ChapSect(r, str, "chapter"); end; GAPDoc2LaTeXProcs.Section := function(r, str) GAPDoc2LaTeXProcs.ChapSect(r, str, "section"); end; GAPDoc2LaTeXProcs.Subsection := function(r, str) GAPDoc2LaTeXProcs.ChapSect(r, str, "subsection"); end; ## table of contents, the job is completely delegated to LaTeX GAPDoc2LaTeXProcs.TableOfContents := function(r, str) # page number info for online help Append(str, Concatenation("\\def\\contentsname{", GAPDocTexts.d.Contents, "\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}}\n")); Append(str, "\n\\tableofcontents\n\\newpage\n\n"); end; ## bibliography, the job is completely delegated to LaTeX and BibTeX GAPDoc2LaTeXProcs.Bibliography := function(r, str) local dat, fname, t, b, st, a; # check if bib data are in BibXMLext format, in that case produce a # BibTeX file dat := r.attributes.Databases; dat := SplitString(dat, "", ", \n\t\b"); dat := Filtered(dat, a-> Length(a) > 3 and a{[Length(a)-3..Length(a)]} = ".xml"); dat := List(dat, a-> Filename(r.root.bibpath, a)); for fname in dat do b := ParseBibXMLextFiles(fname); b := List(b.entries, a-> RecBibXMLEntry(a, b.strings, "BibTeX")); WriteBibFile(Concatenation(fname, ".bib"), [b, [], []]); od; if IsBound(r.attributes.Style) then st := r.attributes.Style; else st := "alpha"; fi; # page number info for online help Append(str, Concatenation("\\def\\bibname{", GAPDocTexts.d.References, "\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}\n")); if IsBound(r.root.six) then ## a := First(r.root.six, x-> x[3] = r.count{[1..3]}); a := GAPDoc2LaTeXProcs.firstsix(r, r.count); if a <> fail and IsBound(a[7]) then Append(str, Concatenation("\\hyperdef{L}{", a[7], "}{}\n")); fi; fi; Append(str, "}\n"); Append(str, "\n\\bibliographystyle{"); Append(str, st); Append(str,"}\n\\bibliography{"); Append(str, r.attributes.Databases); Append(str, "}\n\n"); # toc entry Append(str, "\\addcontentsline{toc}{chapter}{"); Append(str, GAPDocTexts.d.References); Append(str, "}\n\n"); end; ## as default we normalize white space in text and split the result ## into lines (leading and trailing white space is also substituted ## by one space). GAPDoc2LaTeXProcs.PCDATA := function(r, str) local lines, i; if GAPDoc2LaTeXProcs.verbatimPCDATA then # no reformatting at all, used for <Alt Only="LaTeX"> content Append(str, r.content); return; fi; if Length(r.content)>0 and r.content[1] in WHITESPACE then Add(str, ' '); fi; lines := r.content; if GAPDoc2LaTeXProcs.recode = true then lines := Encode(Unicode(lines), GAPDoc2LaTeXProcs.Encoder); fi; lines := FormatParagraph(lines, "left"); if Length(lines)>0 then if r.content[Length(r.content)] in WHITESPACE then lines[Length(lines)] := ' '; else Unbind(lines[Length(lines)]); fi; fi; Append(str, lines); end; ## end of paragraph GAPDoc2LaTeXProcs.P := function(r, str) Append(str, "\n\n"); end; ## forced line break GAPDoc2LaTeXProcs.Br := function(r, str) Append(str, "\\\\\n"); end; ## generic function to get content and wrap by some markup GAPDoc2LaTeXProcs.WrapMarkup := function(r, str, pre, post) local s; s := ""; GAPDoc2LaTeXContent(r, s); Append(str, Concatenation(pre, s, post)); end; ## setting in typewriter GAPDoc2LaTeXProcs.WrapTT := function(r, str) GAPDoc2LaTeXProcs.WrapMarkup(r, str, "\\texttt{", "}"); end; ## GAP keywords GAPDoc2LaTeXProcs.K := function(r, str) GAPDoc2LaTeXProcs.WrapTT(r, str); end; ## verbatim GAP code GAPDoc2LaTeXProcs.C := function(r, str) GAPDoc2LaTeXProcs.WrapTT(r, str); end; ## file names GAPDoc2LaTeXProcs.F := function(r, str) GAPDoc2LaTeXProcs.WrapTT(r, str); end; ## argument names GAPDoc2LaTeXProcs.A := function(r, str) Append(str, "\\mbox{"); ## GAPDoc2LaTeXProcs.WrapTT(r, str); ## the \mdseries is necessary because there is no bold-sl which ## LaTeX substitutes by bold-normal, but we want medium-sl GAPDoc2LaTeXProcs.WrapMarkup(r, str, "\\texttt{\\mdseries\\slshape ", "}"); Append(str, "}"); end; ## simple maths GAPDoc2LaTeXProcs.M := function(r, str) local saveenc; Append(str, "$"); # here the input is already coded in LaTeX saveenc := GAPDoc2LaTeXProcs.Encoder; GAPDoc2LaTeXProcs.Encoder := "LaTeXleavemarkup"; GAPDoc2LaTeXContent(r, str); GAPDoc2LaTeXProcs.Encoder := saveenc; Append(str, "$"); end; ## in LaTeX same as <M> GAPDoc2LaTeXProcs.Math := GAPDoc2LaTeXProcs.M; ## displayed maths GAPDoc2LaTeXProcs.Display := function(r, str) local saveenc; if Length(str)>0 and str[Length(str)] <> '\n' then Add(str, '\n'); fi; Append(str, "\\["); saveenc := GAPDoc2LaTeXProcs.Encoder; GAPDoc2LaTeXProcs.Encoder := "LaTeXleavemarkup"; GAPDoc2LaTeXContent(r, str); GAPDoc2LaTeXProcs.Encoder := saveenc; Append(str, "\\]\n"); end; ## emphazised text GAPDoc2LaTeXProcs.Emph := function(r, str) local a; Append(str, "\\emph{"); GAPDoc2LaTeXContent(r, str); Append(str, "}"); end; ## quoted text GAPDoc2LaTeXProcs.Q := function(r, str) local a; Append(str, "``"); GAPDoc2LaTeXContent(r, str); Append(str, "''"); end; ## Package names GAPDoc2LaTeXProcs.Package := function(r, str) local a; Append(str, "\\textsf{"); GAPDoc2LaTeXContent(r, str); Append(str, "}"); end; ## menu items GAPDoc2LaTeXProcs.B := function(r, str) local a; Append(str, "\\textsc{"); GAPDoc2LaTeXContent(r, str); Append(str, "}"); end; GAPDoc2LaTeXProcs.verbcontent := function(r, delfirst) local cont; # here we cannot use recoding, fall back to SimplifiedUnicodeString (latin1) # first collect content without recoding or reformatting cont := GetTextXMLTree(r); if GAPDoc2LaTeXProcs.Options.InputEncoding = "latin1" then cont := Encode(SimplifiedUnicodeString(Unicode(cont), "latin1"), "latin1"); fi; cont := SplitString(cont, "\n", ""); # if first line has white space only, we remove it if delfirst and Length(cont) > 0 and ForAll(cont[1], x-> x in WHITESPACE) then cont := cont{[2..Length(cont)]}; fi; cont := Concatenation(List(cont, a-> Concatenation(" ", a, "\n"))); return cont; end; ## verbatim GAP session GAPDoc2LaTeXProcs.Verb := function(r, str) local cont, a, s; Append(str, "\n\\begin{verbatim}"); Append(str, GAPDoc2LaTeXProcs.verbcontent(r, false)); Append(str, "\\end{verbatim}\n"); end; GAPDoc2LaTeXProcs.ExampleLike := function(r, str, label, findprompts) local cont, comopt, comchars, sp, pos, c; cont := GAPDoc2LaTeXProcs.verbcontent(r, true); comopt := ""; if findprompts then comchars := ""; for c in Concatenation("!@|", LETTERS) do if not c in cont then Add(comchars, c); if Length(comchars) = 3 then break; fi; fi; od; if Length(comchars) = 3 then comopt := Concatenation("commandchars=",comchars,","); sp := SplitString(cont, "\n", ""); cont := ""; for r in sp do if Length(r) > 6 and r{[1..7]} = " gap> " then Append(cont, Concatenation(" ",comchars{[1]}, "gapprompt",comchars{[2]}, "gap>",comchars{[3]}," ",comchars{[1]},"gapinput", comchars{[2]},r{[8..Length(r)]},comchars{[3]},"\n")); elif Length(r) > 3 and r{[1..4]} = " > " then Append(cont, Concatenation(" ",comchars{[1]}, "gapprompt",comchars{[2]}, ">",comchars{[3]}," ",comchars{[1]},"gapinput", comchars{[2]},r{[5..Length(r)]},comchars{[3]},"\n")); elif Length(r) > 5 and r{[1..5]} = " brk" then pos := Position(r, '>'); Append(cont, Concatenation(" ",comchars{[1]}, "gapbrkprompt",comchars{[2]}, r{[3..pos]},comchars{[3]}," ",comchars{[1]},"gapinput", comchars{[2]},r{[pos+2..Length(r)]},comchars{[3]},"\n")); else Append(cont, r); Add(cont, '\n'); fi; od; fi; fi; Append(str, Concatenation("\n\\begin{Verbatim}[",comopt, "fontsize=\\small,", "frame=single,label=", label, "]\n")); Append(str, cont); Append(str, "\\end{Verbatim}\n"); end; ## log of session and GAP code is typeset the same way as <Example> GAPDoc2LaTeXProcs.Example := function(r, str) GAPDoc2LaTeXProcs.ExampleLike(r, str, GAPDocTexts.d.Example, true); end; GAPDoc2LaTeXProcs.Log := function(r, str) GAPDoc2LaTeXProcs.ExampleLike(r, str, GAPDocTexts.d.Log, true); end; GAPDoc2LaTeXProcs.Listing := function(r, str) if IsBound(r.attributes.Type) then GAPDoc2LaTeXProcs.ExampleLike(r, str, r.attributes.Type, false); else GAPDoc2LaTeXProcs.ExampleLike(r, str, "", false); fi; end; ## explicit labels GAPDoc2LaTeXProcs.Label := function(r, str) Append(str, "\\label{"); Append(str, r.attributes.Name); Append(str, "}"); end; ## citations GAPDoc2LaTeXProcs.Cite := function(r, str) Append(str, "\\cite"); if IsBound(r.attributes.Where) then Add(str, '['); Append(str, Encode(Unicode(r.attributes.Where), GAPDoc2LaTeXProcs.Encoder)); Add(str, ']'); fi; Add(str, '{'); Append(str, r.attributes.Key); Add(str, '}'); end; ## explicit index entries GAPDoc2LaTeXProcs.Subkey := GAPDoc2LaTeXContent; GAPDoc2LaTeXProcs.Index := function(r, str) local s, sub, a; s := ""; sub := ""; for a in r.content do if a.name = "Subkey" then GAPDoc2LaTeX(a, sub); else GAPDoc2LaTeX(a, s); fi; od; NormalizeWhitespace(s); NormalizeWhitespace(sub); if IsBound(r.attributes.Key) then s := Concatenation(r.attributes.Key, "@", s); fi; if Length(sub) > 0 then s := Concatenation(s, "!", sub); elif IsBound(r.attributes.Subkey) then s := Concatenation(s, "!", r.attributes.Subkey); fi; Append(str, "\\index{"); Append(str, s); Append(str, "}"); end; ## this produces an implicit index entry and a label entry GAPDoc2LaTeXProcs.LikeFunc := function(r, str, typ) local nam, namclean, lab, inam, i; Append(str, "\\noindent\\textcolor{FuncColor}{$\\triangleright$\\enspace\\texttt{"); nam := r.attributes.Name; namclean := GAPDoc2LaTeXProcs.DeleteUsBs(nam); # we allow _, \ and so on here nam := GAPDoc2LaTeXProcs.EscapeAttrVal(nam); Append(str, nam); if IsBound(r.attributes.Arg) then Append(str, "({\\mdseries\\slshape "); Append(str, GAPDoc2LaTeXProcs.EscapeAttrVal( NormalizedArgList(r.attributes.Arg))); Append(str, "})"); fi; # possible label if IsBound(r.attributes.Label) then lab := Concatenation("!", r.attributes.Label); else lab := ""; fi; # index entry # handle extremely long names if Length(nam) > GAPDoc2LaTeXProcs.MaxIndexEntryWidth then inam := nam{[1..3]}; for i in [4..Length(nam)-3] do if nam[i] in CAPITALLETTERS then Append(inam, "}\\-\\texttt{"); fi; Add(inam, nam[i]); od; Add(inam, nam[Length(nam)-2]); Add(inam, nam[Length(nam)-1]); Add(inam, nam[Length(nam)]); else inam := nam; fi; Append(str, Concatenation("\\index{", namclean, "@\\texttt{", inam, "}", lab, "}\n")); # label (if not given, the default is the Name) if IsBound(r.attributes.Label) then namclean := Concatenation(namclean, ":", r.attributes.Label); fi; Add(GAPDoc2LaTeXProcs._currentSubsection, namclean); Append(str, Concatenation("\\label{", namclean, "}\n")); # some hint about the type of the variable Append(str, "}\\hfill{\\scriptsize ("); Append(str, typ); Append(str, ")}}\\\\\n"); end; GAPDoc2LaTeXProcs.Func := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Func); end; GAPDoc2LaTeXProcs.Oper := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Oper); end; GAPDoc2LaTeXProcs.Constr := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Constr); end; GAPDoc2LaTeXProcs.Meth := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Meth); end; GAPDoc2LaTeXProcs.Filt := function(r, str) # r.attributes.Type could be "representation", "category", ... if IsBound(r.attributes.Type) then GAPDoc2LaTeXProcs.LikeFunc(r, str, r.attributes.Type); else GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Filt); fi; end; GAPDoc2LaTeXProcs.Prop := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Prop); end; GAPDoc2LaTeXProcs.Attr := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Attr); end; GAPDoc2LaTeXProcs.Var := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Var); end; GAPDoc2LaTeXProcs.Fam := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Fam); end; GAPDoc2LaTeXProcs.InfoClass := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.InfoClass); end; ## using the HelpData(.., .., "ref") interface GAPDoc2LaTeXProcs.ResolveExternalRef := function(bookname, label, nr) local info, match, res; info := HELP_BOOK_INFO(bookname); if info = fail then return fail; fi; match := Concatenation(HELP_GET_MATCHES(info, SIMPLE_STRING(label), true)); # maybe change, and check if there are matches to several subsections? #ssecs := List(match, i-> HELP_BOOK_HANDLER.(info.handler).HelpData(info, # match[i][2], "ref")[7]); if Length(match) < nr then return fail; fi; res := GetHelpDataRef(info, match[nr][2]); res[1] := SubstitutionSublist(res[1], " (not loaded): ", ": ", "one"); return res; end; GAPDoc2LaTeXProcs.Ref := function(r, str) local funclike, int, txt, ref, lab, sectlike, slab; # function like cases funclike := [ "Func", "Oper", "Constr", "Meth", "Filt", "Prop", "Attr", "Var", "Fam", "InfoClass" ]; int := Intersection(funclike, NamesOfComponents(r.attributes)); if Length(int)>0 then txt := r.attributes.(int[1]); if IsBound(r.attributes.Label) then lab := Concatenation(txt, ":", r.attributes.Label); else lab := txt; fi; if IsBound(r.attributes.BookName) then slab := txt; if IsBound(r.attributes.Label) then slab := Concatenation(slab, " (", r.attributes.Label, ")"); fi; ref := GAPDoc2LaTeXProcs.ResolveExternalRef( r.attributes.BookName, slab, 1); if ref = fail then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); ref := Concatenation(" (", Encode(Unicode(lab), GAPDoc2LaTeXProcs.Encoder) , "???)"); else # the search text for online help including book name ref := Concatenation(" (\\textbf{", GAPDoc2LaTeXProcs.EscapeAttrVal(ref[1]), "})"); fi; else ref := Concatenation(" (\\ref{", GAPDoc2LaTeXProcs.DeleteUsBs(lab), "})"); fi; # delete ref, if pointing to current subsection if not IsBound(r.attributes.BookName) and IsBound(GAPDoc2LaTeXProcs._currentSubsection) and lab in GAPDoc2LaTeXProcs._currentSubsection then ref := ""; fi; Append(str, Concatenation("\\texttt{", GAPDoc2LaTeXProcs.EscapeAttrVal(txt), "}", ref)); return; fi; # section like cases sectlike := ["Chap", "Sect", "Subsect", "Appendix"]; int := Intersection(sectlike, NamesOfComponents(r.attributes)); if Length(int)>0 then txt := r.attributes.(int[1]); if IsBound(r.attributes.Label) then lab := r.attributes.Label; else lab := txt; fi; if IsBound(r.attributes.BookName) then ref := GAPDoc2LaTeXProcs.ResolveExternalRef( r.attributes.BookName, lab, 1); if ref = fail then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); ref := Concatenation(" (", lab, "???)"); else # the search text for online help including book name ref := Concatenation(" (\\textbf{", GAPDoc2LaTeXProcs.EscapeAttrVal(ref[1]), "})"); fi; elif IsBound(r.attributes.Style) and r.attributes.Style = "Text" then if IsBound(GAPDoc2LaTeXProcs._labeledSections.(lab)) then ref := Concatenation("\\hyperref[",lab,"]{`", StripBeginEnd( GAPDoc2LaTeXProcs._labeledSections.(lab), WHITESPACE), "'}"); else Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); ref := "`???'"; fi; else # with sectioning references Label must be given lab := r.attributes.(int[1]); #ref := Concatenation("\\ref{", GAPDoc2LaTeXProcs.EscapeAttrVal(lab), "}"); ref := Concatenation("\\ref{", lab, "}"); fi; Append(str, ref); return; fi; # neutral reference to a label if IsBound(r.attributes.BookName) then if IsBound(r.attributes.Label) then lab := r.attributes.Label; else lab := "_X_X_X"; fi; ref := GAPDoc2LaTeXProcs.ResolveExternalRef( r.attributes.BookName, lab, 1); if ref = fail then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); ref := Concatenation(" ", GAPDoc2LaTeXProcs.EscapeAttrVal(lab), "??? "); else # the search text for online help including book name ref := Concatenation(" \\textbf{", GAPDoc2LaTeXProcs.EscapeAttrVal(ref[1]), "}"); fi; else lab := r.attributes.Label; ref := Concatenation("\\ref{", GAPDoc2LaTeXProcs.EscapeAttrVal(lab), "}"); fi; Append(str, ref); return; end; # just process GAPDoc2LaTeXProcs.Address := function(r, str) GAPDoc2LaTeXContent(r, str); end; GAPDoc2LaTeXProcs.Description := function(r, str) Append(str, "\n\n"); GAPDoc2LaTeXContent(r, str); end; GAPDoc2LaTeXProcs.Returns := function(r, str) Append(str, Concatenation("\\textbf{\\indent ", GAPDocTexts.d.Returns, ":\\ }\n")); GAPDoc2LaTeXContent(r, str); Append(str,"\n\n"); end; GAPDoc2LaTeXProcs.ManSection := function(r, str) local funclike, f, lab, i, a; # if there is a Heading then handle as subsection if ForAny(r.content, a-> IsRecord(a) and a.name = "Heading") then GAPDoc2LaTeXProcs._currentSubsection := r.count{[1..3]}; GAPDoc2LaTeXProcs.ChapSect(r, str, "subsection"); Unbind(GAPDoc2LaTeXProcs._currentSubsection); return; fi; # function like elements funclike := [ "Func", "Oper", "Constr", "Meth", "Filt", "Prop", "Attr", "Var", "Fam", "InfoClass" ]; # heading comes from name of first function like element i := 1; while not r.content[i].name in funclike do i := i+1; od; f := r.content[i]; if IsBound(f.attributes.Label) then lab := Concatenation(" (", f.attributes.Label, ")"); else lab := ""; fi; Append(str, Concatenation("\n\n\\subsection{\\textcolor{Chapter }{", GAPDoc2LaTeXProcs.EscapeAttrVal(f.attributes.Name), lab, "}}\n")); # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}\\nobreak\n")); # label for references if IsBound(r.attributes.Label) then Append(str, "\\label{"); Append(str, r.attributes.Label); Append(str, "}\n"); # save heading for "Text" style references to section GAPDoc2LaTeXProcs._labeledSections.(r.attributes.Label) := Concatenation( GAPDoc2LaTeXProcs.EscapeAttrVal(f.attributes.Name), lab); fi; if IsBound(r.root.six) then ## a := First(r.root.six, x-> x[3] = r.count{[1..3]}); a := GAPDoc2LaTeXProcs.firstsix(r, r.count); if a <> fail and IsBound(a[7]) then Append(str, Concatenation("\\hyperdef{L}{", a[7], "}{}\n")); fi; fi; # to avoid references to local subsection in description: GAPDoc2LaTeXProcs._currentSubsection := r.count{[1..3]}; Append(str, "{"); GAPDoc2LaTeXContent(r, str); Append(str, "}\n\n"); Unbind(GAPDoc2LaTeXProcs._currentSubsection); end; GAPDoc2LaTeXProcs.Mark := function(r, str) Append(str, "\n\\item[{"); GAPDoc2LaTeXContent(r, str); Append(str, "}] "); end; GAPDoc2LaTeXProcs.Item := function(r, str) Append(str, "\n\\item "); GAPDoc2LaTeXContent(r, str); end; GAPDoc2LaTeXProcs.List := function(r, str) local item, type, a; if "Mark" in List(r.content, a-> a.name) then item := ""; type := "description"; else item := "\n\\item "; type := "itemize"; fi; Append(str, Concatenation("\n\\begin{", type, "}")); for a in r.content do if a.name = "Mark" then GAPDoc2LaTeXProcs.Mark(a, str); elif a.name = "Item" then Append(str, item); GAPDoc2LaTeXContent(a, str); fi; od; Append(str, Concatenation("\n\\end{", type, "}\n")); end; GAPDoc2LaTeXProcs.Enum := function(r, str) Append(str, "\n\\begin{enumerate}"); GAPDoc2LaTeXContent(r, str); Append(str, "\n\\end{enumerate}\n"); end; GAPDoc2LaTeXProcs.TheIndex := function(r, str) local a; # page number info for online help Append(str, Concatenation("\\def\\indexname{", GAPDocTexts.d.Index, "\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}\n")); if IsBound(r.root.six) then ## a := First(r.root.six, x-> x[3] = r.count{[1..3]}); a := GAPDoc2LaTeXProcs.firstsix(r, r.count); if a <> fail and IsBound(a[7]) then Append(str, Concatenation("\\hyperdef{L}{", a[7], "}{}\n")); fi; fi; Append(str, "}\n\n"); # toc entry Append(str, "\\cleardoublepage\n\\phantomsection\n"); Append(str, "\\addcontentsline{toc}{chapter}{"); Append(str, GAPDocTexts.d.Index); Append(str, "}\n"); Append(str, "\n\n\\printindex\n\n"); end; # like PCDATA GAPDoc2LaTeXProcs.EntityValue := GAPDoc2LaTeXProcs.PCDATA; GAPDoc2LaTeXProcs.Table := function(r, str) local cap; if (IsBound(r.attributes.Only) and r.attributes.Only <> "LaTeX") or (IsBound(r.attributes.Not) and r.attributes.Not = "LaTeX") then return; fi; # head part of table and tabular if IsBound(r.attributes.Label) then Append(str, "\\mbox{}\\label{"); Append(str, r.attributes.Label); Add(str, '}'); fi; Append(str, "\\begin{center}\n\\begin{tabular}{"); Append(str, r.attributes.Align); Add(str, '}'); # the rows of the table GAPDoc2LaTeXContent(r, str); # the trailing part with caption, if given Append(str, "\\end{tabular}\\\\[2mm]\n"); cap := Filtered(r.content, a-> a.name = "Caption"); if Length(cap) > 0 then GAPDoc2LaTeXProcs.Caption1(cap[1], str); fi; Append(str, "\\end{center}\n\n"); end; # do nothing, we call .Caption1 directly in .Table GAPDoc2LaTeXProcs.Caption := function(r, str) return; end; # here the caption text is produced GAPDoc2LaTeXProcs.Caption1 := function(r, str) Append(str, Concatenation("\\textbf{", GAPDocTexts.d.Table, ": }")); GAPDoc2LaTeXContent(r, str); end; GAPDoc2LaTeXProcs.HorLine := function(r, str) Append(str, "\\hline\n"); end; GAPDoc2LaTeXProcs.Row := function(r, str) local i, l; l := Filtered(r.content, a-> a.name = "Item"); for i in [1..Length(l)-1] do GAPDoc2LaTeXContent(l[i], str); Append(str, "&\n"); od; GAPDoc2LaTeXContent(l[Length(l)], str); Append(str, "\\\\\n"); end; GAPDoc2LaTeXProcs.Alt := function(r, str) local take, types; take := false; if IsBound(r.attributes.Only) then NormalizeWhitespace(r.attributes.Only); types := SplitString(r.attributes.Only, "", " ,"); if "LaTeX" in types or "BibTeX" in types then take := true; GAPDoc2LaTeXProcs.recode := false; GAPDoc2LaTeXProcs.verbatimPCDATA := true; fi; fi; if IsBound(r.attributes.Not) then NormalizeWhitespace(r.attributes.Not); types := SplitString(r.attributes.Not, "", " ,"); if not "LaTeX" in types then take := true; fi; fi; if take then GAPDoc2LaTeXContent(r, str); fi; GAPDoc2LaTeXProcs.recode := true; GAPDoc2LaTeXProcs.verbatimPCDATA := false; end; # copy a few entries with two element names GAPDoc2LaTeXProcs.E := GAPDoc2LaTeXProcs.Emph; GAPDoc2LaTeXProcs.Keyword := GAPDoc2LaTeXProcs.K; GAPDoc2LaTeXProcs.Code := GAPDoc2LaTeXProcs.C; GAPDoc2LaTeXProcs.File := GAPDoc2LaTeXProcs.F; GAPDoc2LaTeXProcs.Button := GAPDoc2LaTeXProcs.B; GAPDoc2LaTeXProcs.Arg := GAPDoc2LaTeXProcs.A; GAPDoc2LaTeXProcs.Quoted := GAPDoc2LaTeXProcs.Q; GAPDoc2LaTeXProcs.Par := GAPDoc2LaTeXProcs.P;