1 /***************************************************************************
2  *   copyright       : (C) 2003-2007 by Pascal Brachet                     *
3  *   addons by Frederic Devernay <frederic.devernay@m4x.org>               *
4  *   http://www.xm1math.net/texmaker/                                      *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  ***************************************************************************/
12 
13 #include "webpublishdialog.h"
14 #include "webpublishdialog_config.h"
15 #include "smallUsefulFunctions.h"
16 #include "utilsUI.h"
17 #include "filedialog.h"
18 
WebPublishDialog(QWidget * parent,WebPublishDialogConfig * aConfig,BuildManager * aBuildManager,QTextCodec * input_codec)19 WebPublishDialog::WebPublishDialog(QWidget *parent, WebPublishDialogConfig *aConfig, BuildManager  *aBuildManager, QTextCodec *input_codec)
20 	: QDialog(parent), config(aConfig), buildManager(aBuildManager), codec (input_codec)
21 {
22 	Q_ASSERT(aConfig);
23 	Q_ASSERT(aBuildManager);
24 	//Q_ASSERT(input_codec);
25 	setWindowTitle(tr("Convert to Html"));
26 	setModal(true);
27 	ui.setupUi(this);
28 	UtilsUi::resizeInFontHeight(this, 65, 35);
29 
30 	ui.alignmentcomboBox->insertItem(0, tr("Left"));
31 	ui.alignmentcomboBox->insertItem(1, tr("Center"));
32 	ui.alignmentcomboBox->insertItem(2, tr("Right"));
33 	ui.navigationBox->insertItem(0, tr("Icons"));
34 	ui.navigationBox->insertItem(1, tr("Page numbers"));
35 	ui.indexcomboBox->insertItem(0, tr("Yes"));
36 	ui.indexcomboBox->insertItem(1, tr("No"));
37 	connect(ui.quitButton, SIGNAL(clicked()), this, SLOT(accept()));
38 	connect(ui.LaunchButton, SIGNAL(clicked()), this, SLOT(proceedSlot()));
39 	connect(ui.inputfileButton, SIGNAL(clicked()), this, SLOT(browseSlot()));
40 	init();
41 }
42 
~WebPublishDialog()43 WebPublishDialog::~WebPublishDialog()
44 {
45 }
46 
accept()47 void WebPublishDialog::accept()
48 {
49 	applyusersettings();
50 	if (proc && proc->state() == QProcess::Running) {
51 		proc->kill();
52 		delete proc ;
53 	}
54 	QDialog::accept();
55 }
56 
init()57 void WebPublishDialog::init()
58 {
59 	ui.titleEdit->setText(config->title);
60 	ui.footnoteEdit->setText(config->address);
61 	ui.browserEdit->setText(config->browser);
62 	ui.contentEdit->setText(config->contentname);
63 	if (config->noindex) ui.indexcomboBox->setCurrentIndex(1);
64 	else ui.indexcomboBox->setCurrentIndex(0);
65 	if (config->align == "left") ui.alignmentcomboBox->setCurrentIndex(0);
66 	if (config->align == "center") ui.alignmentcomboBox->setCurrentIndex(1);
67 	if (config->align == "right") ui.alignmentcomboBox->setCurrentIndex(2);
68 	if (config->navigation == 1) ui.navigationBox->setCurrentIndex(0);
69 	else ui.navigationBox->setCurrentIndex(1);
70 	ui.widthspinBox->setValue(config->userwidth);
71 	ui.compilationspinBox->setValue(config->compil);
72 	ui.tocdepthspinBox->setValue(config->tocdepth);
73 	ui.startindexspinBox->setValue(config->startindex);
74 	maxwidth = 0;
75 	colorlink = "1 0 0";
76 	nb_pages = 0;
77 	nb_content_pages = 0;
78 	id_page = 1;
79 	depth = "\\{part\\}|\\{chapter\\}|\\{section\\}";
80 }
81 
convert(const QString & fileName)82 void WebPublishDialog::convert(const QString &fileName)
83 {
84 	ttwperr = false;
85 	errprocess = false;
86 	ui.messagetextEdit->clear();
87 	QString firstpage;
88 	QFileInfo fi(fileName);
89 	if (fi.exists() && fi.isReadable()) {
90 		workdir = fi.absolutePath();
91 		config->lastdir = workdir;
92 		base = fi.completeBaseName();
93 		if (workdir.endsWith("/")) 	htmldir = workdir + base + "_html";
94 		else htmldir = workdir + "/" + base + "_html";
95 		QDir HDir(htmldir);
96 		if (HDir.exists()) {
97 			QFileInfoList files = HDir.entryInfoList();
98 			if (!files.empty()) {
99 				for (int i = 0; i < files.size(); ++i) {
100 					QString fn = files.at(i).filePath();
101 					QFile f(fn);
102 					f.remove();
103 				}
104 			}
105 		} else {
106 			HDir.mkdir(htmldir);
107 		}
108 		copyDataFile("style.css", htmldir + "/style.css");
109 		copyDataFile("up.gif", htmldir + "/up.gif");
110 		copyDataFile("up_d.gif", htmldir + "/up_d.gif");
111 		copyDataFile("psheader.txt", workdir + "/psheader.txt");
112 		if (config->navigation == 1) {
113 			copyDataFile("next.gif", htmldir + "/next.gif");
114 			copyDataFile("next_d.gif", htmldir + "/next_d.gif");
115 			copyDataFile("prev.gif", htmldir + "/prev.gif");
116 			copyDataFile("prev_d.gif", htmldir + "/prev_d.gif");
117 		}
118 		if (config->title == "") config->title = base;
119 		if (config->tocdepth == 2) {
120 			depth = depth + "|\\{subsection\\}";
121 		} else if (config->tocdepth == 3) {
122 			depth = depth + "|\\{subsection\\}|\\{subsubsection\\}";
123 		}
124 		writepages("content");
125 		if (ttwperr || errprocess) return;
126 		if (!config->noindex) writepages("index");
127 		if (ttwperr || errprocess) return;
128 		clean();
129 		ui.messagetextEdit->append(tr("Conversion done.\nThe html files are located in the %1 directory.").arg(htmldir));
130 		if (!config->noindex) firstpage = htmldir + "/index.html";
131 		else firstpage = htmldir + "/page1.html";
132 		QFileInfo fip(firstpage);
133 		if (fip.exists() && fip.isReadable() && (!config->browser.isEmpty()) && (!errprocess)) {
134 			ui.messagetextEdit->append(tr("Running browser ."));
135 			proc = new QProcess(this);
136             connect(proc, SIGNAL(finished(int,QProcess::ExitStatus)), proc, SLOT(deleteLater())); //will free proc after the process has ended
137 			proc->setWorkingDirectory(workdir);
138 
139             proc->start(config->browser,QStringList(firstpage));
140 			if (!proc->waitForStarted(1000)) {
141 				ui.messagetextEdit->append(tr("Error") + " : " + tr("could not start the command"));
142 				errprocess = true;
143 			}
144 		}
145 	} else {
146 		ui.messagetextEdit->append(tr("Input file not found."));
147 	}
148 }
149 
closeEvent(QCloseEvent * ce)150 void WebPublishDialog::closeEvent(QCloseEvent *ce)
151 {
152 	if (proc && proc->state() == QProcess::Running) {
153 		proc->kill();
154 		delete proc ;
155 	}
156 	applyusersettings();
157 	ce->accept();
158 }
159 
160 //************************************
RunCommand(const QString & cmd,const QString & file,const bool waitendprocess,const char * stdErrSlot)161 void WebPublishDialog::RunCommand(const QString &cmd, const QString &file, const bool waitendprocess, const char *stdErrSlot)
162 {
163     ProcessX *proc = buildManager->firstProcessOfDirectExpansion(cmd, QFileInfo(file));
164 	this->proc = proc;
165 	ui.messagetextEdit->append(tr("  Running this command: ") + proc->getCommandLine());
166 	curLog = "";
167 	proc->setWorkingDirectory(workdir);
168 	if (stdErrSlot)	connect(proc, SIGNAL(readyReadStandardError()), this, stdErrSlot);
169 	else 	connect(proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutputForLog()));
170     connect(proc, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(SlotEndProcess(int)));
171 	proc->startCommand();
172 	if (!proc->waitForStarted(1000)) {
173 		ui.messagetextEdit->append(tr("Error") + " : " + tr("could not start the command"));
174 		errprocess = true;
175 	}
176 	procfinished = false;
177 	if (waitendprocess) {
178 		while (!procfinished) { //be carefully when changing this, its duplicated in imgProcess
179 			qApp->instance()->processEvents(QEventLoop::ExcludeUserInputEvents);
180 		}
181 	}
182 }
183 
SlotEndProcess(int err)184 void WebPublishDialog::SlotEndProcess(int err)
185 {
186 	if (err) {
187 		ui.messagetextEdit->append(tr("Error") + " : " + tr("a process has failed"));
188 		if (curLog != "") ui.messagetextEdit->append(curLog);
189 		errprocess = true;
190 	}
191 	procfinished = true;
192 }
193 
bboxProcess()194 void WebPublishDialog::bboxProcess()
195 {
196 	RunCommand("txs:///gs/[-q][-dBATCH][-dNOPAUSE][-sDEVICE=bbox]", workdir + "/page.ps", true, SLOT(readBboxOutput()));
197 }
198 
readBboxOutput()199 void WebPublishDialog::readBboxOutput()
200 {
201 	QRegExp rxbbox("%%BoundingBox:\\s*([0-9eE\\.\\-]+)\\s+([0-9eE\\.\\-]+)\\s+([0-9eE\\.\\-]+)\\s+([0-9eE\\.\\-]+)");
202 	QString line;
203 	QByteArray result = proc->readAllStandardError();
204 	QTextStream bbox(&result);
205 	while (!bbox.atEnd()) {
206 		line = bbox.readLine();
207 		if (rxbbox.indexIn(line) > -1) {
208 			QFile bboxf(workdir + "/bbox.txt");
209 			if (!bboxf.open(QIODevice::WriteOnly)) {
210 				fatalerror(workdir + "/bbox.txt" + " not found.");
211 				return;
212 			} else {
213 				QTextStream bboxts(&bboxf);
214 				bboxts << line;
215 				bboxf.close();
216 			}
217 		}
218 	}
219 }
220 
imgProcess(const QString & params,const QString & psFile)221 void WebPublishDialog::imgProcess(const QString &params, const QString &psFile)
222 {
223 	procfinished = false;
224 	RunCommand("txs:///gs/" + params, psFile, false, SLOT(readImgOutput())); //don't wait here, proceed until wait loop below
225 	QFile linkf(workdir + "/link.txt");
226 	if (!linkf.open(QIODevice::WriteOnly)) {
227 		fatalerror(workdir + "/link.txt" + " not found.");
228 		return;
229 	} else {
230 		QTextStream linkts(&linkf);
231 		linkts << "";
232 		linkf.close();
233 	}
234 	while (!procfinished) {
235 		qApp->instance()->processEvents(QEventLoop::ExcludeUserInputEvents);
236 	}
237 }
238 
readImgOutput()239 void WebPublishDialog::readImgOutput()
240 {
241 	QString line = QString(proc->readAllStandardOutput());
242 	QFile linkf(workdir + "/link.txt");
243 	if (!linkf.open(QIODevice::WriteOnly)) {
244 		fatalerror(workdir + "/link.txt" + " not found.");
245 		return;
246 	} else {
247 		QTextStream linkts(&linkf);
248 		linkts << line;
249 		linkf.close();
250 	}
251 }
252 
readOutputForLog()253 void WebPublishDialog::readOutputForLog()
254 {
255 	QByteArray result = proc->readAllStandardError();
256 	QString t = QString(result);
257 	t = t.simplified();
258 	if (!t.isEmpty()) curLog.append(t + "\n");
259 }
260 
copyDataFile(QString fileNameWithoutDir,QString to_file)261 void WebPublishDialog::copyDataFile(QString fileNameWithoutDir, QString to_file)
262 {
263 	QString fiName = findResourceFile(fileNameWithoutDir);
264 	if (fiName == "") return;
265 	QFile::remove(to_file);
266 	QFile::copy(fiName, to_file);
267 }
268 
removeFile(QString file)269 void WebPublishDialog::removeFile(QString file)
270 {
271 	if (QFile::exists(file)) {
272 		QFile fi(file);
273 		fi.remove();
274 	}
275 }
276 
277 //******************************************
header()278 QString WebPublishDialog::header()
279 {
280 	QString result = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'> \n";
281 	result += "<html>\n";
282 	result += "<head>\n";
283 	result += "<META NAME='Generator' CONTENT='TeXstudio (http://texstudio.sourceforge.net/)'>\n";
284 	result += "<title>" + config->title + "</title>\n";
285 	result += "<link rel=StyleSheet href='style.css' type='text/css'>\n";
286 	result += "</head>\n";
287 	result += "<body bgcolor='white'>\n";
288 	return result;
289 }
290 
footer()291 QString WebPublishDialog::footer()
292 {
293 	QString result = "<div align='" + config->align + "' id='address'> " + config->address + " </div>\n";
294 	result += "</body>\n";
295 	result += "</html>";
296 	return result;
297 }
298 
content_navigation(int page,int numpages,QString up_page)299 QString WebPublishDialog::content_navigation(int page, int numpages, QString up_page)
300 {
301 	QString result;
302 	QString leftcode = "";
303 	QString rightcode = "";
304 	QString upcode = "";
305 	int prev_page = page - 1;
306 	int next_page = page + 1;
307 	if (config->navigation == 1) {
308 		if (page > 1) {
309 			leftcode = "<A HREF='page" + QString::number(prev_page) + ".html'><IMG src='prev.gif' align='middle' border='0'></A>";
310 		} else {
311 			leftcode = "<IMG src='prev_d.gif' align='middle' border='0'>";
312 		}
313 
314 		if (page < numpages) {
315 			rightcode = "<A HREF='page" + QString::number(next_page) + ".html'><IMG src='next.gif' align='middle' border='0'></A>";
316 		} else {
317 			rightcode = "<IMG src='next_d.gif' align='middle' border='0'>" ;
318 		}
319 	} else {
320 		if (page > 1) {
321 			leftcode = "<A HREF='page" + QString::number(prev_page) + ".html'>&nbsp;" + QString::number(prev_page) + "/" + QString::number(nb_content_pages) + "&nbsp;<</A>" ;
322 		} else {
323 			leftcode = "&nbsp;";
324 		}
325 		if (page < numpages) {
326 			rightcode = "<A HREF='page" + QString::number(next_page) + ".html'>>&nbsp;" + QString::number(next_page) + "/" + QString::number(nb_content_pages) + "&nbsp;</A>" ;
327 		} else {
328 			rightcode = "&nbsp;";
329 		}
330 	}
331 	if (page > 0) {
332 		upcode = "<A HREF='" + up_page + "'><IMG src='up.gif' align='middle' border='0'></A>" ;
333 	} else {
334 		upcode = "<IMG src='up_d.gif' align='middle' border='0'>";
335 	}
336 	result = "<div id='navigation'>\n <table border=0 cellpadding=2 cellspacing=0 width='100%'>\n ";
337 	result += "<tr valign='middle'>\n ";
338 	result += "<td align='left' valign='middle' width='33%'>" + leftcode + "</td>\n";
339 	result += "<td align='center' valign='middle' width='34%'>" + upcode + "</td>\n";
340 	result += "<td align='right' valign='middle' width='33%'>" + rightcode + "</td>\n";
341 	result += "</tr>\n";
342 	result += "</table>\n";
343 	result += "</div>\n";
344 	return result;
345 }
346 
nbpagesps(QString psfile)347 int WebPublishDialog:: nbpagesps(QString psfile)
348 {
349 	QString line;
350 	QString captured = "0";
351 	bool ok;
352 	QFile f(psfile);
353 	QRegExp rx("^%%Pages:\\s+(-?\\d+)");
354 	if (!f.open(QIODevice::ReadOnly)) {
355 		fatalerror(psfile + " not found.");
356 		return 0;
357 	} else {
358 		QTextStream psts(&f);
359 		while (!psts.atEnd()) {
360 			line = psts.readLine();
361 			if (rx.indexIn(line) > -1) {
362 				captured = rx.cap(1);
363 				break;
364 			}
365 		}
366 		f.close();
367 		int result = captured.toInt(&ok);
368 		if (ok  && (result > 0)) {
369 			return result;
370 		} else {
371 			return 0;
372 		}
373 	}
374 }
375 
extractpage(QString psfile,int page)376 void WebPublishDialog::extractpage(QString psfile, int page)
377 {
378 	QString line;
379 
380 	QFile f(workdir + "/" + psfile);
381 	QRegExp rxpage("^%%Page:\\s+(-?\\d+)");
382 	QRegExp rxtrailer("^%%Trailer");
383 	QRegExp rx("^%%Pages:\\s+(-?\\d+)");
384 	if (!f.open(QIODevice::ReadOnly)) {
385 		fatalerror(psfile + " not found.");
386 		return;
387 	} else {
388 		QTextStream psts(&f);
389 		QFile outf(workdir + "/page.ps");
390 		if (!outf.open(QIODevice::WriteOnly)) {
391 			fatalerror("Can't open " + workdir + "/page.ps");
392 			return;
393 		} else {
394 			QTextStream outts(&outf);
395 			bool go = true;
396 			while (!psts.atEnd()) {
397 				line = psts.readLine();
398 				if (rxpage.indexIn(line) > -1) {
399 					int numpage = rxpage.cap(1).toInt();
400 					if (numpage == page) {
401 						line = "%%Page: 1 1";
402 						go = true;
403 					} else go = false;
404 				}
405 				if (rxtrailer.indexIn(line) > -1) go = true;
406 				if (rx.indexIn(line) > -1) line = "%%Pages: 1 0";
407 				if (go) outts << line + "\n";
408 			}
409 			outf.close();
410 		}
411 		f.close();
412 	}
413 }
414 
codepic(QString pic_name,QString map_name)415 QString WebPublishDialog::codepic(QString pic_name, QString map_name)
416 {
417 	QString result = "<div id='content' align='" + config->align + "'><IMG src='" + pic_name + "' align='middle' border='0'";
418 	if (map_name != "") result += " usemap='#" + map_name + "'";
419 	result += "></div>\n";
420 	return result;
421 }
422 
ps2gif(QString input,QString output,int id_page,int w,int h,int maxw)423 void WebPublishDialog::ps2gif(QString input, QString output, int id_page, int w, int h, int maxw)
424 {
425 	if (!errprocess) extractpage(input, id_page);
426 	if (ttwperr  || errprocess) return;
427 	float resolution = float(72 * config->userwidth) / maxw;
428 	float scale = float(config->userwidth) / maxw;
429 	int gx = int(w * resolution / 72 + 0.5);
430 	int gy = int(h * resolution / 72 + 0.5);
431 	QFile psf(workdir + "/page.ps");
432 	if (!psf.open(QIODevice::ReadOnly)) {
433 		fatalerror(workdir + "/page.ps" + " not found.");
434 		return;
435 	} else {
436 		QTextStream psts(&psf);
437 		QFile outf(workdir + "/tmp.ps");
438 		if (!outf.open(QIODevice::WriteOnly)) {
439 			fatalerror("Can't open " + workdir + "/tmp.ps");
440 			return;
441 		} else {
442 			QTextStream outts(&outf);
443 			bool flag = false;
444 			QString line;
445 			while (!psts.atEnd()) {
446 				line = psts.readLine();
447                 if (line.indexOf(QRegularExpression("^%%BoundingBox:\\s(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)/)"), 0) != -1) {
448 					outts << "%%BoundingBox: 0 0 " + QString::number(w) + " " + QString::number(h) + "\n";
449                 } else if ((!flag) && ((line.indexOf(QRegularExpression("^%%EndSetup"), 0) > -1) || (line.indexOf(QRegularExpression("^%%Page:"), 0) > -1))) {
450 					outts << line + "\n";
451 					outts << QString::number(x1) + " neg " + QString::number(y1) + " neg translate\n";
452 					flag = true;
453                 } else if (line.indexOf(QRegularExpression("/uscale\\s+([0-9eE\\.\\-]+)\\s+N"), 0) != -1) {
454 					outts << "/uscale " + QString::number(scale) + " N\n";
455 				} else {
456 					outts << line + "\n";
457 				}
458 			}
459 			psf.close();
460 			outf.close();
461 			if (w != 0) {
462 				if (!errprocess) imgProcess("[-q][-dSAFER -dBATCH -dNOPAUSE][-sDEVICE=png16m][-g" + QString::number(gx) + "x" + QString::number(gy) + "][-r" + QString::number(resolution) + "][-dTextAlphaBits=4][-dGraphicsAlphaBits=4][-sOutputFile=\"" + output + QString::number(id_page) + ".png\"]", workdir + "/tmp.ps");
463 				if (ttwperr || errprocess) return;
464 			} else {
465 				copyDataFile("blank.png", htmldir + "/" + output + QString::number(id_page) + ".png");
466 			}
467 			removeFile(workdir + "/page.ps");
468 			removeFile(workdir + "/tmp.ps");
469 			removeFile(workdir + "/tmp.ppm");
470 		}
471 	}
472 }
473 
writepages(QString mode)474 void WebPublishDialog::writepages(QString mode)
475 {
476 	bool match = false;
477 	bool ok;
478 	maxwidth = 1;
479 	QString line;
480 	QString captured1, captured2, captured3, captured4;
481 	x1box.clear();
482 	y1box.clear();
483 	x2box.clear();
484 	y2box.clear();
485 
486 	if (mode == "content") {
487 		QFile outf(workdir + "/" + base + "_" + mode + ".tex");
488 		if (!outf.open(QIODevice::WriteOnly)) {
489 			fatalerror(tr("Can't open") + " " + workdir + "/" + base + "_" + mode + ".tex");
490 			return;
491 		} else {
492 			QTextStream outts(&outf);
493 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
494             outts.setCodec(codec);
495 #endif
496 
497 			QFile texf(workdir + "/" + base + ".tex");
498 			if (!texf.open(QIODevice::ReadOnly)) {
499 				fatalerror(workdir + "/" + base + ".tex " + tr("not found") + ".");
500 				return;
501 			} else {
502 				QTextStream texts(&texf);
503 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
504                 texts.setCodec(codec);
505 #endif
506 				while (!texts.atEnd()) {
507 					line = texts.readLine();
508                     if (!match && (line.indexOf(QRegularExpression("^\\\\begin\\{document\\}"), 0) != -1)) {
509 						outts << "\\newbox\\bwk\\edef\\tempd#1pt{#1\\string p\\string t}\\tempd\\def\\nbextr#1pt{#1}\n";
510 						outts << "\\def\\npts#1{\\expandafter\\nbextr\\the#1\\space}\n";
511 						outts << "\\def\\ttwplink#1#2{\\special{ps:" + colorlink + " setrgbcolor}#2\\special{ps:0 0 0 setrgbcolor}\\setbox\\bwk=\\hbox{#2}\\special{ps:( linkto #1)\\space\\npts{\\wd\\bwk} \\npts{\\dp\\bwk} -\\npts{\\ht\\bwk} true\\space Cpos}}\n";
512 						match = true;
513 					}
514 					outts << line + "\n";
515 				}
516 				texf.close();
517 				outf.close();
518 				ui.messagetextEdit->append(tr("Compiling input file. Please wait..."));
519 				int counter = 1;
520 				while (counter <= config->compil) {
521 					if (!errprocess)
522 						RunCommand(BuildManager::CMD_LATEX, workdir + "/" + base + "_" + mode + ".tex", true);
523 					//RunCommand("latex -interaction=nonstopmode "+base+"_"+mode+".tex",true);
524 
525 					latexerror(workdir + "/" + base + "_" + mode + ".log");
526 					if (ttwperr  || errprocess) break;
527 					counter++;
528 				}
529 				if (ttwperr  || errprocess) return;
530 				QFile auxf(workdir + "/" + base + "_content.aux");
531 				if (!auxf.open(QIODevice::ReadOnly)) {
532 					fatalerror(mode + workdir + "/" + base + "_content.aux " + tr("not found") + ".");
533 					return;
534 				} else {
535 					QTextStream auxts(&auxf);
536 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
537                     auxts.setCodec(codec);
538 #endif
539 					QRegExp rx("\\\\newlabel\\{(.*)\\}\\{\\{.*\\}\\{(\\d+)\\}\\}");
540 					while (!auxts.atEnd()) {
541 						QString line = auxts.readLine();
542 						if (rx.indexIn(line) != -1) {
543 							QString captured1 = rx.cap(1);
544 							QString captured2 = rx.cap(2);
545 							loc[captured1] = "page" + captured2 + ".html";
546 						}
547 					}
548 					auxf.close();
549 				}
550 			}
551 		}
552 	} else if (mode == "index") {
553 		QFile outf(workdir + "/" + base + "_" + mode + ".tex");
554 		if (!outf.open(QIODevice::WriteOnly)) {
555 			fatalerror(tr("Can't open") + " " + workdir + "/" + base + "_" + mode + ".tex");
556 			return;
557 		} else {
558 			QTextStream outts(&outf);
559 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
560             outts.setCodec(codec);
561 #endif
562 			QFile texf(workdir + "/" + base + ".tex");
563 			if (!texf.open(QIODevice::ReadOnly)) {
564 				fatalerror(workdir + "/" + base + ".tex " + tr("not found") + ".");
565 				return;
566 			} else {
567 				QTextStream texts(&texf);
568 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
569                 texts.setCodec(codec);
570 #endif
571 				match = false;
572 				while (!texts.atEnd()) {
573 					line = texts.readLine();
574                     if (line.indexOf(QRegularExpression("^\\\\begin\\{document\\}"), 0) > -1) {
575 						match = true;
576 					}
577 					if (!match) {
578 						outts << line + "\n";
579 					}
580 				}
581 				texf.close();
582 				outts << "\\pagestyle{empty}\n";
583 				outts << "\\setcounter{tocdepth}{" + QString::number(config->tocdepth) + "} \n";
584 				outts << "\\newbox\\bwk\\edef\\tempd#1pt{#1\\string p\\string t}\\tempd\\def\\nbextr#1pt{#1}\n";
585 				outts << "\\def\\npts#1{\\expandafter\\nbextr\\the#1\\space}\n";
586 				outts << "\\def\\ttwplink#1#2{#2\\setbox\\bwk=\\vbox{#2}\\special{ps:( linkto #1)\\space\\npts{\\wd\\bwk} \\npts{\\dp\\bwk} -\\npts{\\ht\\bwk} false\\space Cpos}}\n";
587 				outts << "\\begin{document}\n";
588 				outts << "\\section*{" + config->contentname + "}\n";
589 				outts << "\\makeatletter\n\\parindent = 0.0 in\n";
590 				QFile auxf(workdir + "/" + base + "_content.aux");
591 				if (!auxf.open(QIODevice::ReadOnly)) {
592 					fatalerror(mode + workdir + "/" + base + "_content.aux " + tr("not found") + ".");
593 					return;
594 				} else {
595 					QTextStream auxts(&auxf);
596 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
597                     auxts.setCodec(codec);
598 #endif
599 					QRegExp rx("\\\\@writefile\\{toc\\}.*(" + depth + ").*\\{(\\d+)\\}\\}");
600 					while (!auxts.atEnd()) {
601 						line = auxts.readLine();
602 						if (rx.indexIn(line) > -1) {
603 							captured2 = rx.cap(2);
604 							id_page = captured2.toInt(&ok);
605                             line.remove(QRegularExpression("\\\\@writefile\\{toc\\}"));
606                             if (line.indexOf(QRegularExpression("\\\\numberline"), 0) > -1) {
607 								id_page = id_page + config->startindex - 1;
608 								outts << "\\ttwplink{page" + QString::number(id_page) + ".html}";
609 							} else {
610 								outts << "\\ttwplink{none}";
611 							}
612 							outts << line + "\n\n";
613 						}
614 					}
615 					auxf.close();
616 					outts << "\\end{document}" ;
617 					outf.close();
618 					if (!errprocess)
619 						RunCommand(BuildManager::CMD_LATEX, workdir + "/" + base + "_" + mode + ".tex", true);
620 					latexerror(workdir + "/" + base + "_" + mode + ".log");
621 					if (ttwperr  || errprocess) return;
622 				}
623 			}
624 		}
625 	}
626 	if (!errprocess)
627 		RunCommand("txs:///dvips/[-q " + config->dviopt + " -h psheader.txt]", workdir + "/" + base + "_" + mode + ".tex", true);
628 	//RunCommand("dvips -q "+dviopt+" -h psheader.txt -o "+base+"_"+mode+".ps "+base+"_"+mode+".dvi",true) ;
629 
630 	if (ttwperr || errprocess) return;
631 	QString link = "none";
632 	int nb_link = 0;
633 	int W, H;
634 	nb_pages = nbpagesps(workdir + "/" + base + "_" + mode + ".ps");
635 	if (ttwperr  || errprocess) return;
636 	id_page = 1;
637 	ui.messagetextEdit->append(tr("Scanning files. Please wait..."));
638 	while (id_page <= nb_pages) {
639 		if (!errprocess) extractpage(base + "_" + mode + ".ps", id_page);
640 		if (ttwperr  || errprocess) return;
641 		if (!errprocess) bboxProcess();
642 		if (ttwperr  || errprocess) return;
643 		QFile bboxf(workdir + "/bbox.txt");
644 		if (!bboxf.open(QIODevice::ReadOnly)) {
645 			fatalerror(workdir + "/bbox.txt " + tr("not found") + ".");
646 			return;
647 		} else {
648 			QTextStream bboxts(&bboxf);
649 			QRegExp rx("%%BoundingBox:\\s*([0-9eE\\.\\-]+)\\s+([0-9eE\\.\\-]+)\\s+([0-9eE\\.\\-]+)\\s+([0-9eE\\.\\-]+)");
650 			while (!bboxts.atEnd()) {
651 				QString line = bboxts.readLine();
652 				if (rx.indexIn(line) != -1) {
653 					captured1 = rx.cap(1);
654 					x1 = captured1.toInt(&ok);
655 					captured2 = rx.cap(2);
656 					y1 = captured2.toInt(&ok);
657 					captured3 = rx.cap(3);
658 					x2 = captured3.toInt(&ok);
659 					captured4 = rx.cap(4);
660 					y2 = captured4.toInt(&ok);
661 				}
662 			}
663 			bboxf.close();
664 			x1box.append(x1);
665 			y1box.append(y1);
666 			x2box.append(x2);
667 			y2box.append(y2);
668 			W = x2 - x1;
669 			if (W > maxwidth) {
670 				maxwidth = W ;
671 			}
672 		}
673 		removeFile(workdir + "/page.ps");
674 		removeFile(workdir + "/bbox.txt");
675 		id_page++;
676 	}
677 	if (mode == "content") {
678 		id_page = 1;
679 		nb_content_pages = nb_pages;
680 		while (id_page <= nb_pages) {
681 			ui.messagetextEdit->append(tr("Writing page") + " " + QString::number(id_page) + " " + tr("of") + " " + QString::number(nb_pages));
682 			x1 = x1box[id_page - 1];
683 			y1 = y1box[id_page - 1];
684 			x2 = x2box[id_page - 1];
685 			y2 = y2box[id_page - 1];
686 			W = x2 - x1;
687 			H = y2 - y1;
688 			ps2gif(base + "_" + mode + ".ps", htmldir + "/image", id_page, W, H, maxwidth);
689 			if (ttwperr || errprocess) return;
690 			QFile htmf(htmldir + "/page" + QString::number(id_page) + ".html");
691 			if (!htmf.open(QIODevice::WriteOnly)) {
692 				fatalerror(tr("Can't open") + " " + htmldir + "/page" + QString::number(id_page) + ".html");
693 				return;
694 			} else {
695 				QTextStream htmts(&htmf);
696 				htmts << header();
697 				if (config->noindex) {
698 					htmts << content_navigation(id_page, nb_pages, "page1.html");
699 				} else {
700 					htmts << content_navigation(id_page, nb_pages, "index.html");
701 				}
702 				QFile linkf(workdir + "/link.txt");
703 				if (!linkf.open(QIODevice::ReadOnly)) {
704 					fatalerror(workdir + "/link.txt" + " " + tr("not found") + ".");
705 					return;
706 				} else {
707 					QTextStream LINK(&linkf);
708 					QRegExp rx("x1=([0-9eE\\.\\-]+)\\s+y1=([0-9eE\\.\\-]+)\\s+x2=([0-9eE\\.\\-]+)\\s+y2=([0-9eE\\.\\-]+)\\s+linkto\\s+(.*)$");
709 					nb_link = 0 ;
710 					htmts << "<map name='carte" + QString::number(id_page) + "'>\n" ;
711 					while (!LINK.atEnd()) {
712 						line = LINK.readLine();
713 						if (rx.indexIn(line) > -1) {
714 							captured1 = rx.cap(1);
715 							x1 = int(captured1.toFloat(&ok) + 0.5);
716 							captured2 = rx.cap(2);
717 							y1 = int(captured2.toFloat(&ok) + 0.5);
718 							captured3 = rx.cap(3);
719 							x2 = int(captured3.toFloat(&ok) + 0.5);
720 							captured4 = rx.cap(4);
721 							y2 = int(captured4.toFloat(&ok) + 0.5);
722 							link = rx.cap(5);
723 							if (link != "none") {
724 								LinkMap::Iterator it = loc.find(link);
725 								if (it != loc.end()) {
726 									htmts << "<area shape='rect' coords='" + QString::number(x1) + "," + QString::number(y1) + "," + QString::number(x2) + "," + QString::number(y2) + "' href='" + it.value() + "' >\n"  ;
727 								} else {
728 									htmts << "<area shape='rect' coords='" + QString::number(x1) + "," + QString::number(y1) + "," + QString::number(x2) + "," + QString::number(y2) + "' href='" + link + "' >\n"  ;
729 								}
730 							}
731 							nb_link++;
732 						}
733 					}
734 					linkf.close();
735 					htmts << "</map>\n" ;
736 					if (nb_link > 0) {
737 						htmts << codepic("image" + QString::number(id_page) + ".png", "carte" + QString::number(id_page));
738 					} else {
739 						htmts << codepic("image" + QString::number(id_page) + ".png", "");
740 					}
741 					if (config->noindex) {
742 						htmts << content_navigation(id_page, nb_pages, "page1.html");
743 					} else {
744 						htmts << content_navigation(id_page, nb_pages, "index.html");
745 					}
746 					htmts << footer();
747 					htmf.close() ;
748 
749 				}
750 			}
751 			id_page++;
752 		}
753 	} else if (mode == "index") {
754 		ui.messagetextEdit->append(tr("Writing index page"));
755 		QFile htmf(htmldir + "/index.html");
756 		if (!htmf.open(QIODevice::WriteOnly)) {
757 			fatalerror(tr("Can't open") + " " + htmldir + "/index.html");
758 			return;
759 		} else {
760 			QTextStream htmts(&htmf);
761 			htmts << header();
762 			htmts << content_navigation(0, 1, "");
763 			id_page = 1;
764 			while (id_page <= nb_pages) {
765 				x1 = x1box[id_page - 1];
766 				y1 = y1box[id_page - 1];
767 				x2 = x2box[id_page - 1];
768 				y2 = y2box[id_page - 1];
769 				W = x2 - x1;
770 				H = y2 - y1;
771 				ps2gif(base + "_" + mode + ".ps", htmldir + "/" + mode + "image", id_page, W, H, maxwidth);
772 				if (ttwperr || errprocess) return;
773 				QFile linkf(workdir + "/link.txt");
774 				if (!linkf.open(QIODevice::ReadOnly)) {
775 					fatalerror(workdir + "/link.txt " + tr("not found") + ".");
776 					return;
777 				} else {
778 					QTextStream LINK(&linkf);
779 					QRegExp rx("x1=([0-9eE\\.\\-]+)\\s+y1=([0-9eE\\.\\-]+)\\s+x2=([0-9eE\\.\\-]+)\\s+y2=([0-9eE\\.\\-]+)\\s+linkto\\s+(.*)$");
780 					nb_link = 0 ;
781 					htmts << "<map name='carte" + QString::number(id_page) + "'>\n" ;
782 					while (!LINK.atEnd()) {
783 						line = LINK.readLine();
784 						if (rx.indexIn(line) > -1) {
785 							captured1 = rx.cap(1);
786 							x1 = int(captured1.toFloat(&ok) + 0.5);
787 							captured2 = rx.cap(2);
788 							y1 = int(captured2.toFloat(&ok) + 0.5);
789 							captured3 = rx.cap(3);
790 							x2 = int(captured3.toFloat(&ok) + 0.5);
791 							captured4 = rx.cap(4);
792 							y2 = int(captured4.toFloat(&ok) + 0.5);
793 							link = rx.cap(5);
794 							if (link != "none") {
795 								htmts << "<area shape='rect' coords='" + QString::number(x1) + "," + QString::number(y1) + "," + QString::number(x2) + "," + QString::number(y2) + "' href='" + link + "' >\n"  ;
796 							}
797 							nb_link++;
798 						}
799 					}
800 					linkf.close();
801 					htmts << "</map>\n" ;
802 				}
803 				id_page++;
804 			}
805 			id_page = 1;
806 			while (id_page <= nb_pages) {
807 				htmts << codepic(mode + "image" + QString::number(id_page) + ".png", "carte" + QString::number(id_page));
808 				id_page++;
809 			}
810 			htmts << content_navigation(0, 1, "");
811 			htmts << footer();
812 			htmf.close();
813 		}
814 	}
815 }
816 
fatalerror(QString msg)817 void WebPublishDialog::fatalerror(QString msg)
818 {
819 	clean();
820 	ui.messagetextEdit->append(tr("Fatal error : ") + msg);
821 	ttwperr = true;
822 }
823 
clean()824 void WebPublishDialog::clean()
825 {
826 	removeFile(workdir + "/psheader.txt");
827 	removeFile(workdir + "/link.txt");
828 	QStringList extension = QString(".tex,.log,.aux,.dvi,.lof,.lot,.bit,.idx,.glo,.bbl,.ilg,.toc,.ind,.ps").split(",");
829 	for (QStringList::Iterator it = extension.begin(); it != extension.end(); ++it) {
830 		removeFile(workdir + "/" + base + "_content" + *it);
831 		removeFile(workdir + "/" + base + "_index" + *it);
832 	}
833 }
834 
latexerror(QString logfile)835 void WebPublishDialog::latexerror(QString logfile)
836 {
837 	QRegExp rx("^!");
838 	QString line;
839 	QFile logf(logfile);
840 	if (!logf.open(QIODevice::ReadOnly)) {
841 		fatalerror(logfile + " " + tr("not found") + ".");
842 	} else {
843 		QTextStream LOG(&logf);
844 		bool ok = true;
845 		while (!LOG.atEnd()) {
846 			line = LOG.readLine();
847 			if (rx.indexIn(line) > -1) {
848 				ok = false;
849 			}
850 		}
851 		logf.close();
852 		if (!ok) fatalerror(tr("LaTeX errors detected."));
853 	}
854 }
855 
proceedSlot()856 void WebPublishDialog::proceedSlot()
857 {
858 	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
859 	ui.messagetextEdit->clear();
860 	applyusersettings();
861 	convert(ui.inputfileEdit->text());
862 	QApplication::restoreOverrideCursor();
863 }
864 
browseSlot()865 void WebPublishDialog::browseSlot()
866 {
867 	QString fn =  FileDialog::getOpenFileName(this, tr("Open File"), config->lastdir, tr("TeX files (*.tex);;All files (*.*)"));
868 	if (!fn.isEmpty()) {
869 		ui.inputfileEdit->setText(fn);
870 	}
871 }
872 
applyusersettings()873 void WebPublishDialog::applyusersettings()
874 {
875 	config->title = ui.titleEdit->text();
876 	config->address = ui.footnoteEdit->text();
877 	config->browser = ui.browserEdit->text();
878 	config->contentname = ui.contentEdit->text();
879 	if (ui.indexcomboBox->currentIndex() == 0) config->noindex = false;
880 	else config->noindex = true;
881 	if (ui.alignmentcomboBox->currentIndex() == 0) config->align = "left";
882 	if (ui.alignmentcomboBox->currentIndex() == 1) config->align = "center";
883 	if (ui.alignmentcomboBox->currentIndex() == 2) config->align = "right";
884 	if (ui.navigationBox->currentIndex() == 0) config->navigation = 1;
885 	else config->navigation = 0;
886 	config->userwidth = ui.widthspinBox->value();
887 	config->compil = ui.compilationspinBox->value();
888 	config->tocdepth = ui.tocdepthspinBox->value();
889 	config->startindex = ui.startindexspinBox->value();
890 }
891 
892 
893 
894 
895 //===================================================
896 // Config Management
897 //===================================================
898 
899 
readSettings(QSettings & settings)900 void WebPublishDialogConfig::readSettings(QSettings &settings)
901 {
902 	settings.beginGroup("qttwp");
903 	userwidth = settings.value("/userwidth", 700).toInt();
904 	compil = settings.value("/compil", 1).toInt();
905 	tocdepth = settings.value("/tocdepth", 2).toInt();
906 	startindex = settings.value("/startindex", 1).toInt();
907 	navigation = settings.value("/navigation", 1).toInt();
908 	noindex = settings.value("/noindex", false).toBool();
909 	title = settings.value("/title", "").toString();
910 	address = settings.value("/address", "").toString();
911 #if defined Q_WS_X11 || defined Q_OS_LINUX
912 	QString kdesession = ::getenv("KDE_FULL_SESSION");
913 	if (!kdesession.isEmpty()) browser = settings.value("/browser", "konqueror").toString();
914 	else browser = settings.value("/browser", "firefox").toString();
915 	//programdir=PREFIX"/share/texstudio";
916 #endif
917 #ifdef Q_OS_MAC
918 	browser = settings.value("/browser", "open").toString();
919 	//programdir="/Applications/texstudio.app/Contents/Resources";
920 #endif
921 #ifdef Q_OS_WIN32
922 	browser = settings.value("/browser", "\"C:/Program Files/Internet Explorer/IEXPLORE.EXE\"").toString();
923 	//programdir=QCoreApplication::applicationDirPath();
924 #endif
925 	contentname = settings.value("/contentname", "\\contentsname").toString();
926 	align = settings.value("/align", "center").toString();
927 	lastdir = settings.value("/lastdir", QDir::homePath()).toString();
928 	dviopt = settings.value("/dviopt", " -Ppk -V").toString();
929 
930 	settings.endGroup();
931 }
932 
933 //	applyusersettings();
saveSettings(QSettings & settings)934 void WebPublishDialogConfig::saveSettings(QSettings &settings)
935 {
936 	settings.beginGroup("qttwp");
937 	settings.setValue("userwidth", userwidth);
938 	settings.setValue("compil", compil);
939 	settings.setValue("tocdepth", tocdepth);
940 	settings.setValue("startindex", startindex);
941 	settings.setValue("navigation", navigation);
942 	settings.setValue("noindex", noindex);
943 	settings.setValue("title", title);
944 	settings.setValue("address", address);
945 	settings.setValue("browser", browser);
946 	settings.setValue("contentname", contentname);
947 	settings.setValue("align", align);
948 	settings.setValue("lastdir", lastdir);
949 	settings.setValue("dviopt", dviopt);
950 	settings.endGroup();
951 }
952 
953