1 //
2 // Copyright (c) 2007, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 5 May 07 Brian Frank Creation
7 //
8
9 using compiler
10 using fandoc
11
12 **
13 ** FandocToHtmlGenerator generates an HTML file for a standalone fandoc file
14 **
15 class FandocToHtmlGenerator : HtmlGenerator
16 {
17
18 //////////////////////////////////////////////////////////////////////////
19 // Constructor
20 //////////////////////////////////////////////////////////////////////////
21
22 new make(DocCompiler compiler, Location loc, OutStream out, Doc doc)
23 : super(compiler, loc, out)
24 {
25 this.doc = doc
26 }
27
28 //////////////////////////////////////////////////////////////////////////
29 // Generator
30 //////////////////////////////////////////////////////////////////////////
31
32 override Str title()
33 {
34 title := doc.meta["title"]
35 if (title != null) return title
36 compiler.err("WARNING: Missing title", loc)
37 return super.title
38 }
39
override Void header()
41 {
42 out.print("<ul>\n")
43 out.print(" <li><a href='../index.html'>$docHome</a></li>\n")
44 out.print(" <li><a href='index.html'>$compiler.pod.name</a></li>\n")
45 out.print(" <li>$title</li>\n")
46 out.print("</ul>\n")
47 }
48
49 override Void content()
50 {
51 findPrevNext
52 prevNext
53 out.print("<h1 class='title'>$title</h1>\n")
54 doc.children.each |DocNode node| { node.write(this) }
55 prevNext
56 }
57
override Void sidebar()
59 {
60 // make a quick run thru to make sure we even
61 // have any headers for the content sidebar
62 temp := doc.children.find |DocNode node->Bool| { return node is Heading }
63 if (temp == null) return
64
65 // we found some so print them
66 out.print("<h2>Contents</h2>\n")
67 out.print("<ul>\n")
68 curLevel := 1
69 doc.children.each |DocNode node|
70 {
71 heading := node as Heading
72 if (heading != null)
73 {
74 id := heading.anchorId
75 if (heading.level > curLevel)
76 {
77 out.print("<li><ul>\n")
78 curLevel++
79 }
80 else if (heading.level < curLevel)
81 {
82 out.print("</ul></li>\n")
83 curLevel--
84 }
85
86 out.print("<li>")
87 if (id != null) out.print("<a href='#$id'>")
88 heading.children.each |DocNode n| { n.write(this) }
89 if (id != null) out.print("</a>")
90 out.print("</li>\n")
91 }
92 }
93 while (curLevel > 1)
94 {
95 out.print("</ul></li>\n")
96 curLevel--
97 }
98 out.print("</ul>\n")
99 }
100
101 Void prevNext()
102 {
103 if (prev == null && next == null) return
104 out.print("<div class='prevNext'>\n")
105 if (prev != null) out.print("<div class='prev'>< <a href='${prev}.html'>$prev</a></div>\n")
106 if (next != null) out.print("<div class='next'><a href='${next}.html'>$next</a> ></div>\n")
107 out.print("</div>\n")
108 }
109
110 Void findPrevNext()
111 {
112 if (compiler.fandocIndex == null) return
113
114 // give something easier to work with
115 index := [,]
116 for (i:=0; i<compiler.fandocIndex.size; i++)
117 {
118 v := compiler.fandocIndex[i]
119 if (v is Uri) index.push(v)
120 else if (v is Obj[]) index.push((v as Obj[])[0] as Uri)
121 }
122
123 // try to find prev/next
124 for (i:=0; i<index.size; i++)
125 if (title == index[i].toStr)
126 {
127 if (i > 0) prev = index[i-1]
128 if (i < index.size-1) next = index[i+1]
129 break;
130 }
131 }
132
133 //////////////////////////////////////////////////////////////////////////
134 // Fields
135 //////////////////////////////////////////////////////////////////////////
136
137 Doc doc
138 Uri prev // prev link if exists
139 Uri next // next link if exists
140
141 }
142