1-- © 2008 David Given.
2-- WordGrinder is licensed under the MIT open source license. See the COPYING
3-- file in this distribution for the full text.
4
5-----------------------------------------------------------------------------
6-- The exporter itself.
7
8local function unhtml(s)
9	s = s:gsub("&", "&")
10	s = s:gsub("<", "&lt;")
11	s = s:gsub(">", "&gt;")
12	return s
13end
14
15local style_tab =
16{
17	["H1"] = {pre=false, list=false,
18		on='<h1>', off='</h1>'},
19	["H2"] = {pre=false, list=false,
20		on='<h2>', off='</h2>'},
21	["H3"] = {pre=false, list=false,
22		on='<h3>', off='</h3>'},
23	["H4"] = {pre=false, list=false,
24		on='<h4>', off='</h4>'},
25	["P"] =  {pre=false, list=false,
26		on='<p>', off='</p>'},
27	["L"] =  {pre=false, list=true,
28		on='<li style="list-style-type: none;">', off='</li>'},
29	["LB"] = {pre=false, list=true,
30		on='<li>', off='</li>'},
31	["Q"] =  {pre=false, list=false,
32		on='<blockquote>', off='</blockquote>'},
33	["V"] =  {pre=false, list=false,
34		on='<blockquote>', off='</blockquote>'},
35	["RAW"] = {pre=false, list=false,
36		on='', off=''},
37	["PRE"] = {pre=true, list=false,
38		on='<pre>', off='</pre>'}
39}
40
41local function callback(writer, document)
42	local settings = DocumentSet.addons.htmlexport
43	local currentpara = nil
44	local islist = false
45
46	function changepara(newpara)
47		local currentstyle = style_tab[currentpara]
48		local newstyle = style_tab[newpara]
49
50		if (newpara ~= currentpara) or
51			not newpara or
52			not currentstyle.pre or
53			not newstyle.pre
54		then
55			if currentstyle then
56				writer(currentstyle.off)
57			end
58			writer("\n")
59
60			if (not newstyle or not newstyle.list) and islist then
61				writer("</ul>\n")
62				islist = false
63			end
64			if (newstyle and newstyle.list) and not islist then
65				writer("<ul>\n")
66				islist = true
67			end
68
69			if newstyle then
70				writer(newstyle.on)
71			end
72			currentpara = newpara
73		else
74			writer("\n")
75		end
76	end
77
78	return ExportFileUsingCallbacks(document,
79	{
80		prologue = function()
81			writer('<html xmlns="http://www.w3.org/1999/xhtml"><head>\n')
82			writer('<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>\n')
83			writer('<meta name="generator" content="WordGrinder '..VERSION..'"/>\n')
84			writer('<title>', unhtml(document.name), '</title>\n')
85			writer('</head><body>\n')
86		end,
87
88		rawtext = function(s)
89			writer(s)
90		end,
91
92		text = function(s)
93			writer(unhtml(s))
94		end,
95
96		notext = function(s)
97			if (currentpara ~= "PRE") then
98				writer('<br/>')
99			end
100		end,
101
102		italic_on = function()
103			writer(settings.italic_on)
104		end,
105
106		italic_off = function()
107			writer(settings.italic_off)
108		end,
109
110		underline_on = function()
111			writer(settings.underline_on)
112		end,
113
114		underline_off = function()
115			writer(settings.underline_off)
116		end,
117
118		bold_on = function()
119			writer(settings.bold_on)
120		end,
121
122		bold_off = function()
123			writer(settings.bold_off)
124		end,
125
126		list_start = function()
127		end,
128
129		list_end = function()
130		end,
131
132		paragraph_start = function(style)
133			changepara(style)
134		end,
135
136		paragraph_end = function(style)
137		end,
138
139		epilogue = function()
140			changepara(nil)
141			writer('</body>\n')
142			writer('</html>\n')
143		end
144	})
145end
146
147function Cmd.ExportHTMLFile(filename)
148	return ExportFileWithUI(filename, "Export HTML File", ".html",
149		callback)
150end
151
152-----------------------------------------------------------------------------
153-- Addon registration. Set the HTML export settings.
154
155do
156	local function cb()
157		DocumentSet.addons.htmlexport = DocumentSet.addons.htmlexport or {
158			underline_on = "<u>",
159			underline_off = "</u>",
160			italic_on = "<i>",
161			italic_off = "</i>"
162		}
163
164		local s = DocumentSet.addons.htmlexport
165		s.bold_on = s.bold_on or "<b>"
166		s.bold_off = s.bold_off or "</b>"
167	end
168
169	AddEventListener(Event.RegisterAddons, cb)
170end
171
172-----------------------------------------------------------------------------
173-- Configuration user interface.
174
175function Cmd.ConfigureHTMLExport()
176	local settings = DocumentSet.addons.htmlexport
177
178	local underline_on_textfield =
179		Form.TextField {
180			x1 = 16, y1 = 1,
181			x2 = -1, y2 = 1,
182			value = settings.underline_on
183		}
184
185	local underline_off_textfield =
186		Form.TextField {
187			x1 = 16, y1 = 3,
188			x2 = -1, y2 = 3,
189			value = settings.underline_off
190		}
191
192	local italic_on_textfield =
193		Form.TextField {
194			x1 = 16, y1 = 5,
195			x2 = -1, y2 = 5,
196			value = settings.italic_on
197		}
198
199	local italic_off_textfield =
200		Form.TextField {
201			x1 = 16, y1 = 7,
202			x2 = -1, y2 = 7,
203			value = settings.italic_off
204		}
205
206	local bold_on_textfield =
207		Form.TextField {
208			x1 = 16, y1 = 9,
209			x2 = -1, y2 = 9,
210			value = settings.bold_on
211		}
212
213	local bold_off_textfield =
214		Form.TextField {
215			x1 = 16, y1 = 11,
216			x2 = -1, y2 = 11,
217			value = settings.bold_off
218		}
219
220	local dialogue =
221	{
222		title = "Configure HTML Export",
223		width = Form.Large,
224		height = 13,
225		stretchy = false,
226
227		["KEY_^C"] = "cancel",
228		["KEY_RETURN"] = "confirm",
229		["KEY_ENTER"] = "confirm",
230
231		Form.Label {
232			x1 = 1, y1 = 1,
233			x2 = 32, y2 = 1,
234			align = Form.Left,
235			value = "Underline on:"
236		},
237		underline_on_textfield,
238
239		Form.Label {
240			x1 = 1, y1 = 3,
241			x2 = 32, y2 = 3,
242			align = Form.Left,
243			value = "Underline off:"
244		},
245		underline_off_textfield,
246
247		Form.Label {
248			x1 = 1, y1 = 5,
249			x2 = 32, y2 = 5,
250			align = Form.Left,
251			value = "Italics on:"
252		},
253		italic_on_textfield,
254
255		Form.Label {
256			x1 = 1, y1 = 7,
257			x2 = 32, y2 = 7,
258			align = Form.Left,
259			value = "Italics off:"
260		},
261		italic_off_textfield,
262
263		Form.Label {
264			x1 = 1, y1 = 9,
265			x2 = 32, y2 = 9,
266			align = Form.Left,
267			value = "Bold on:"
268		},
269		bold_on_textfield,
270
271		Form.Label {
272			x1 = 1, y1 = 11,
273			x2 = 32, y2 = 11,
274			align = Form.Left,
275			value = "Bold off:"
276		},
277		bold_off_textfield,
278	}
279
280	while true do
281		local result = Form.Run(dialogue, RedrawScreen,
282			"SPACE to toggle, RETURN to confirm, CTRL+C to cancel")
283		if not result then
284			return false
285		end
286
287		settings.underline_on = underline_on_textfield.value
288		settings.underline_off = underline_off_textfield.value
289		settings.italic_on = italic_on_textfield.value
290		settings.italic_off = italic_off_textfield.value
291		settings.bold_on = bold_on_textfield.value
292		settings.bold_off = bold_off_textfield.value
293		return true
294	end
295
296	return false
297end
298