package com.noticeditorteam.noticeditor.io;
import com.noticeditorteam.noticeditor.exceptions.ExportException;
import com.noticeditorteam.noticeditor.model.NoticeItem;
import com.noticeditorteam.noticeditor.model.NoticeTree;
import com.noticeditorteam.noticeditor.model.NoticeTreeItem;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javafx.scene.control.TreeItem;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.pegdown.PegDownProcessor;
/**
* Export notices to html.
*
* @author aNNiMON
*/
public class HtmlExportStrategy implements ExportStrategy {
private PegDownProcessor processor;
private Map<NoticeTreeItem, String> filenames;
public void setProcessor(PegDownProcessor processor) {
this.processor = processor;
}
@Override
public boolean export(File destDir, NoticeTree notice) {
filenames = new HashMap<>();
try {
exportToHtmlPages(notice, destDir, "index");
return true;
} catch (IOException ioe) {
throw new ExportException(ioe);
}
}
/**
* Save item as HTML pages. Root item will be saved to index.html
*
* @param item node to recursively save
* @param dir directory to save
* @param filename name of the file without extension
*/
private void exportToHtmlPages(NoticeTreeItem item, File dir, String filename) throws IOException {
Document doc = Jsoup.parse(getClass().getResourceAsStream("/resources/export_template.html"), null, "");
generatePage(item, doc);
File file = new File(dir, filename + ".html");
IOUtil.writeContent(file, doc.outerHtml());
if (item.isBranch()) {
for (TreeItem<NoticeItem> obj : item.getInternalChildren()) {
NoticeTreeItem child = (NoticeTreeItem) obj;
exportToHtmlPages(child, dir, generateFilename(child));
}
}
}
/**
* Save tree to HTML pages. Root item saved to index.html
*
* @param tree tree to save
* @param dir directory to save
* @param filename name of the file without extension
*/
private void exportToHtmlPages(NoticeTree tree, File dir, String filename) throws IOException {
exportToHtmlPages((NoticeTreeItem) tree.getRoot(), dir, filename);
}
private void generatePage(NoticeTreeItem note, Document doc) {
doc.title(note.getTitle());
doc.select("#notice_title").first().text(note.getTitle());
Element data = doc.select("#content").first();
if (note.isBranch()) {
Element list = doc.createElement("div").addClass("list-group");
for (TreeItem<NoticeItem> treeItem : note.getInternalChildren()) {
NoticeTreeItem child = (NoticeTreeItem) treeItem;
Element item = doc.createElement("div").addClass("list-group-item");
generateIcon(child, item);
item.appendElement("a").attr("href", generateFilename(child) + ".html")
.text(child.getTitle())
.appendElement("br");
list.appendChild(item);
}
data.appendChild(list);
} else {
data.html(processor.markdownToHtml(note.getContent()));
}
}
private void generateIcon(NoticeTreeItem child, Element item) {
if (child.isBranch()) {
item.appendElement("span").addClass("glyphicon glyphicon-folder-open");
} else {
switch (child.getStatus()) {
case NoticeItem.STATUS_IMPORTANT:
item.appendElement("span").addClass("glyphicon glyphicon-pushpin important");
break;
default:
item.appendElement("span").addClass("glyphicon glyphicon-pushpin normal");
}
}
}
private String generateFilename(NoticeTreeItem item) {
if (filenames.containsKey(item)) {
return filenames.get(item);
}
String filename = IOUtil.sanitizeFilename(item.getTitle());
if (filenames.containsValue(filename)) {
// solve collision
int counter = 1;
String newFileName = filename;
while (filenames.containsValue(newFileName)) {
newFileName = String.format("%s_(%d)", filename, counter++);
}
filename = newFileName;
}
filenames.put(item, filename);
return filename;
}
}