
Book(title) :=
[
WriteString("Creating Book ");
WriteString(title);NewLine();

 plain["Title"] := title;
];

AddBody(text):=
[
  currentBody[2] := currentBody[2]:text;
  GarbageCollect();
  True;
/*TODO remove?
plain["Chapters"][currentChapter]["Body"]:=
    plain["Chapters"][currentChapter]["Body"] : text;
*/
];

Chapter(title):=
[
GarbageCollect();
WriteString("  Creating Chapter ");
WriteString(title);NewLine();
  currentChapter:=title;
  currentChapterIndex++;
  currentSectionIndex:=0;
  plain["Chapters"][currentChapter]:={};
  plain["Chapters"][currentChapter]["Sections"]:={};
  plain["Chapters"][currentChapter]["Body"]:="";

currentBody := Assoc("Body",plain["Chapters"][currentChapter]);

  plain["Chapters"][currentChapter]["Index"]:=currentChapterIndex;
  plain["Chapters"][currentChapter]["Intro"]:=HtmlTag(chapter, title);
  plain["Chapters"][currentChapter]["Commands"]:={};

/*TODO remove? AddAnchor(ChapterTag(currentChapterIndex)); */
];

ChapterIntro(text) :=
[
  plain["Chapters"][currentChapter]["Intro"] :=
     plain["Chapters"][currentChapter]["Intro"] : text : newline;
];

Bodied("ChapterIntro", 60000);

AddAnchor(aAnchor):=
[
  AddBody(HtmlAnchor()aAnchor);
  plain["Chapters"][currentChapter]["Commands"] :=
     Concat(plain["Chapters"][currentChapter]["Commands"], 
            {{ChapterLink(aAnchor), ""}});
];

SectionTag(chapterIndex,sectionIndex):=
  "c" : String(chapterIndex) : "s" : String(sectionIndex) ;

ChapterTag(chapterIndex):=
  "c" : String(chapterIndex) ;

Section(title):=
[
WriteString("    Creating Section ");
WriteString(title);NewLine();

  currentSectionIndex++;
  plain["Chapters"][currentChapter]["Sections"][title]:=
    currentSectionIndex;
  AddBody(HtmlAnchor()SectionTag(currentChapterIndex,currentSectionIndex));
  AddBody(HtmlTag(section,"<HR>":title));
];

CmdDescription(cmd, desc) :=
[
  AddBody(HtmlAnchor() cmd);
  AddBody(HtmlAnchor() ToLowerCase(cmd));	// add a lowercase version for easier help
  SubSection(cmd : " -- " : desc);
  plain["Chapters"][currentChapter]["Commands"] :=
     Concat(plain["Chapters"][currentChapter]["Commands"], 
            {{ChapterLink(cmd), desc}});
];   

ChapterLink(aLink) := 
  HtmlLink(aLink, plain["BaseName"] : "chapter" 
                                    : String(currentChapterIndex) : ".html",
           aLink, "Chapters");

SubSection(title):=
[
/*
WriteString("      Sub section ");
WriteString(title);NewLine();
*/
  AddBody(HtmlTag(subsection,"<HR>":title));
];

Topical(title):=
[
  AddBody(HtmlTag(topical,title));
];


Text(text):=
[
  AddBody(text : newline);
];


Blurb(text):=
[
  plain["Blurb"]:=text;
];

HtmlCommand(command):=
[
HtmlTable(3,"90%",
"<TR>" : "<TD WIDTH=100% bgcolor=e0e0e0>" : "<PRE>" : command : "</PRE></TR>"
         );
];

HtmlTerm(term):= ("<B><TT>" : EscapeLtGt(term) : "</TT></B>");

HtmlEmphasis(word) := ("<I>" : word : "</I>");

HtmlBreak():="<P>  </P>";


Enumerate(body):=
[
  "<UL>" : body : "</UL>";
];
Bodied("Enumerate",2);

Itemize(body):=
[
  "<UL>" : body : "</UL>";
];
Bodied("Itemize",2);

Item(body):=
[
  "<LI>" : body;
];
Bodied("Item",1);





Bodied("Book",60000);

Bodied("Title",60000);
Bodied("Author",60000);

Bodied("Chapter",60000);

Bodied("Section",60000);
Bodied("SubSection",60000);
Bodied("Topical",60000);
Bodied("Text",60000);

Bodied("Blurb",60000);
Bodied("DocumentationComment",60000);


RuleBase("WriteItem",{item});
Rule("WriteItem",1,1,IsString(item)) WriteString(item);
Rule("WriteItem",1,2,True) Write(item);

WriteList(list):=
[
  ForEach(item,list)
  [
    WriteItem(item);
  ];
];


InitBooks():=
[
  site["Books"]:={};
];

SelectBook(book):=
[
  plain:=site["Books"][book];
];

InitBook(basename):=
[
  /* create a new book */
  site["Books"][basename]:={};
  SelectBook(basename);
  plain["BaseName"]:=basename;
  plain["Chapters"] := {};
  plain["Body"]:="";
  plain["Blurb"]:="";
  currentChapterIndex:=0;
  currentSectionIndex:=0;
];



SimpleSectionsIndex(filename,chapter,sections):=
[
  Local(bl,section,index);
  bl:="";
  index:=plain["Chapters"][chapter]["Index"];

  ForEach(section,sections)
  [
    bl := bl:HtmlTag(bullet,
                     HtmlLink(section,filename,SectionTag(index,
    plain["Chapters"][chapter]["Sections"][section]),""));
  ];
  bl;
];


SimpleChapterIndex(filename,chapters):=
[
  Local(bl,chapter);
  bl:="";
  ForEach(chapter,chapters)
  [
    bl := bl:HtmlTag(bullet,
    HtmlLink(chapter,filename,
       ChapterTag(plain["Chapters"][chapter]["Index"]),""));
      );
    sections:=AssocIndices(plain["Chapters"][chapter]["Sections"]);
    if (sections != {})
    [
      bl:=bl : HtmlTag(bullets,SimpleSectionsIndex(filename,chapter,sections));
    ];
  ];
  bl;
];


FramedSectionsIndex(filename,chapter,sections):=
[
  Local(bl,section,index);
  bl:="";
/*  sections:=AssocIndices(plain["Chapters"][chapter]["Sections"]); */
  index:=plain["Chapters"][chapter]["Index"];

  ForEach(section,sections)
  [
    bl := bl:HtmlTag(bullet,
                     HtmlLink(section,filename,SectionTag(index,
    plain["Chapters"][chapter]["Sections"][section]),"Chapters"));
  ];
  bl;
];

FramedChapterIndex(chapters):=
[
  Local(bl,chapter);
  bl:="";
  ForEach(chapter,chapters)
  [
    Local(file,index);
    index:=plain["Chapters"][chapter]["Index"];
    file:=plain["BaseName"] : "chapter" : String(index) : ".html";
    bl := bl:HtmlTag(bullet,
    HtmlLink(chapter,file,
       ChapterTag(plain["Chapters"][chapter]["Index"]),"Chapters"));
      );

    sections:=AssocIndices(plain["Chapters"][chapter]["Sections"]);
    if (sections != {})
    [
      bl:=bl : HtmlTag(bullets,FramedSectionsIndex(file,chapter,sections));
    ];
  ];
  bl;
];


/* hier */

GroupBooks(first,second):=
[
  site["Books"][first]["Chapters"] :=
    Concat(site["Books"][second]["Chapters"], site["Books"][first]["Chapters"]);
];


EmitHtmlSimple():=
[
  Local(filename);
  filename:=plain["BaseName"] : ".html";

WriteString("Writing ");
WriteString(filename);
NewLine();

  ToFile(HtmlFile(filename))
  [
    Local(bodytext,chapter,chapters,pcc);
    bodytext:="";
    chapters:=AssocIndices(plain["Chapters"]);
    bodytext:=bodytext : HtmlTag(book,plain["Title"]);
  
    bodytext:= bodytext : HtmlTag(bullets,SimpleChapterIndex(filename,chapters));
  
    ForEach(chapter,chapters)
    [
      pcc := plain["Chapters"][chapter];	
      bodytext:=bodytext : (HtmlAnchor() ChapterTag(pcc["Index"]))
                : ChapterHeader(pcc["Commands"]) : pcc["Intro"] : pcc["Body"] 
                : "<p>  </P><HR>";
      GarbageCollect();
    ];

    WriteString(
      HtmlTag(html,
              HtmlTitle(plain["Title"]) :
              HtmlTag(font,HtmlTag(body,bodytext)) /*hier*/
             ) );
  ];
];

EmitHtmlFramed():=
[
  Local(chapter,chapters);
  chapters:=AssocIndices(plain["Chapters"]);

  ToFile(HtmlFile(plain["BaseName"] : "manual.html"))
  [
    WriteString(

    HtmlTag(html,
        HtmlFrameSetCols("240,*",
          HtmlFrameSetRows("110,*",
            HtmlFrame("manicon.html","") : 
            HtmlFrame(plain["BaseName"] : "chapters.html","")
                  ) :
          HtmlFrame(plain["BaseName"] : "chapter1.html","Chapters")
                )
           )
    );
  ];


WriteString("Writing ");
WriteString(plain["BaseName"]);
NewLine();

  ToFile(HtmlFile(plain["BaseName"] : "chapters.html"))
    WriteString(
      HtmlTag(html,
      HtmlTag(font,HtmlTag(indexbody,
                HtmlTag(bullets,FramedChapterIndex(chapters)))
               ) ) );

  ForEach(chapter,chapters)
  [
    Local(pcc,file,index,str,keyword);
    pcc := plain["Chapters"][chapter];
    index := pcc["Index"];
    file := plain["BaseName"] : "chapter" : String(index) : ".html";
    str := HtmlAnchor() ChapterTag(index);
    str := str : ChapterHeader(pcc["Commands"]);
    str := str : pcc["Intro"] : "<p> </p>" : newline;
    If (pcc["Commands"] != {}, 
        str := str : ChapterTOC(pcc["Commands"]));
    str := str : pcc["Body"];
    str := HtmlTitle(chapter) : newline : HtmlTag(body, HtmlTag(font, str));
    ToFile(HtmlFile(file)) WriteString(HtmlTag(html, str));
    GarbageCollect();
  ];
];

10 # ChapterHeader({}) <-- "";
20 # ChapterHeader(_alist) <--
[
  Local(str, keyword);
  str := Head(alist)[1];
  ForEach(keyword, Tail(alist))
    str := str : ", " : keyword[1];
  str := str : "." : newline;
];

ChapterTOC(alist) :=
[
  Local(str, flag, keyword);
  flag := True;
  ForEach(keyword, alist) 
     flag := flag And (keyword[2] = "");
  If (flag, 
      str := "", /* If there are no descriptions, a TOC has no use */
      [
        str := "<CENTER><TABLE>";
       	str := str : newline;	
       	ForEach(keyword, alist)
       	  str := str : "<TR BGCOLOR=#E0E0E0>" : newline
       		     : "<TD>" : keyword[1] : "</TD>" : newline
       		     : "<TD>" : keyword[2] : "</TD>" : newline
       		     : "</TR>" : newline;
       	str := str : "</TABLE></CENTER>" : newline;
      ]);
];

BookList():=
[
  Local(book,books,bl);
  bl:="";
  books:=AssocIndices(site["Books"]);
  ForEach(book,books)
  [
    Local(bookinfo);
    bookinfo:=site["Books"][book];

    bl:= bl : 
     "<TR>" : "<TD bgcolor=e0e0e0><FONT face=\"Verdana, Arial, Helvetica, sans-serif\" size=\"3\">
     " : HtmlLink(bookinfo["Title"],book:"manual.html","","_top") :
/*     " or " : HtmlLink(" (single file) ",bookinfo["BaseName"]:".html","","_top") : */
     "</TR><TR>" : "<TD bgcolor=ffffff><FONT face=\"Verdana, Arial, Helvetica, sans-serif\" size=\"3\">
     " : bookinfo["Blurb"] :"</TR>";
  ];
  bl;
];


EmitBookIndex():=
[
WriteString("Creating book index"); NewLine();
  ToFile(HtmlFile("books.html"))
  [
    WriteString(
      HtmlTag(html,
              HtmlTitle("Yacas documentation") :
              HtmlTag(font,
              "<center><H1>Yacas documentation</H1></center>":
              HtmlTag(body,HtmlTable(3,"",
/*              HtmlCaption("Yacas documentation"): */
              BookList()))) /*hier*/
             )
    );
  ];
  True;
];


10 # SeeAlso({}) <-- True;
20 # SeeAlso(_list) <--
     [
	Local(item);
        AddBody(SeeAlso1(Head(list)));
	ForEach(item, Tail(list)) AddBody(", " : SeeAlso1(item));
	AddBody(".");
     ];

SeeAlso1(_seealso) <-- HtmlLink(seealso, "ref.html", seealso, "Chapters");

/*
SeeAlso(_list)<--
[
  ForEach(item,list)
  [
    AddBody(HtmlLink(item,"ref.html",item,"Chapters"):", ");
  ];
];
*/

BuiltIn() <-- AddBody("<h5 align=right>Internal function</h5>");
UnixSpecific() <-- AddBody("<h5 align=right>Unix-specific add-on</h5>");
MacSpecific() <-- AddBody("<h5 align=right>Macintosh-specific add-on</h5>");
MSWinSpecific() <-- AddBody("<h5 align=right>MS Windows-specific add-on</h5>");
StandardLib() <-- AddBody("<h5 align=right>Standard library</h5>");

/* alias for Load() that can be redefined */
IncludeFile(x) := [ Load(x); GarbageCollect(); ];

RuleBase("TeXMath", {x});
RuleBase("TeXMathD", {x});
RuleBase("TeXMathD", {x,y});

/* mathematical expressions */
TeXMath(x) := "<b>" : EscapeLtGt(ToString() Write(x)) : "</b>";
TeXMathD(x) := "
<p><center><b> " : EscapeLtGt(ToString() Write(x)) : " </b></center></p>
";
// special form: punctuation at the end of a displayed equation
TeXMathD(_x, _string) <-- "
<p><center><b> " : EscapeLtGt(ToString() Write(x)) : string : " </b></center></p>
";

HoldArg("TeXMath",x);
HoldArg("TeXMathD",x);

/* Replace all < and > characters in a string by &lt; and &gt; */
EscapeLtGtStrings := { {"<", "&lt;"}, {">", "&gt;"}, {"&", "&amp;"} };
EscapeLtGt(string) := [
	Local(i, result);
	result := "";
	For(i:=1, i<=Length(string), i++) result := result : If(EscapeLtGtStrings[string[i]] != Empty, EscapeLtGtStrings[string[i]], string[i]);
	result;
];

/* Convert ASCII-7 string to lowercase */
UCStrings :=
{
	{"A","a"},
	{"B","b"},
	{"C","c"},
	{"D","d"},
	{"E","e"},
	{"F","f"},
	{"G","g"},
	{"H","h"},
	{"I","i"},
	{"J","j"},
	{"K","k"},
	{"L","l"},
	{"M","m"},
	{"N","n"},
	{"O","o"},
	{"P","p"},
	{"Q","q"},
	{"R","r"},
	{"S","s"},
	{"T","t"},
	{"U","u"},
	{"V","v"},
	{"W","w"},
	{"X","x"},
	{"Y","y"},
	{"Z","z"},
};
LCStrings :=
{
	{"a","A"},
	{"b","B"},
	{"c","C"},
	{"d","D"},
	{"e","E"},
	{"f","F"},
	{"g","G"},
	{"h","H"},
	{"i","I"},
	{"j","J"},
	{"k","K"},
	{"l","L"},
	{"m","M"},
	{"n","N"},
	{"o","O"},
	{"p","P"},
	{"q","Q"},
	{"r","R"},
	{"s","S"},
	{"t","T"},
	{"u","U"},
	{"v","V"},
	{"w","W"},
	{"x","X"},
	{"y","Y"},
	{"z","Z"},
};
ToLowerCase(string) :=
[
	Local(i, result);
	result := "";
	For(i:=1, i<=Length(string), i++) result := result : If(UCStrings[string[i]] != Empty, UCStrings[string[i]], string[i]);
	result;
];
