package scrum.server.common; import ilarkesto.pdf.ACell; import ilarkesto.pdf.AImage; import ilarkesto.pdf.AParagraph; import ilarkesto.pdf.APdfContainerElement; import ilarkesto.pdf.ARow; import ilarkesto.pdf.ATable; import ilarkesto.pdf.FontStyle; import java.awt.Color; import scrum.client.wiki.AWikiElement; import scrum.client.wiki.Code; import scrum.client.wiki.EntityReference; import scrum.client.wiki.Header; import scrum.client.wiki.Highlight; import scrum.client.wiki.Image; import scrum.client.wiki.ItemList; import scrum.client.wiki.LineBreak; import scrum.client.wiki.Link; import scrum.client.wiki.Paragraph; import scrum.client.wiki.Pre; import scrum.client.wiki.Table; import scrum.client.wiki.TableCell; import scrum.client.wiki.TableRow; import scrum.client.wiki.Text; import scrum.client.wiki.WikiModel; import scrum.client.wiki.WikiParser; public class WikiToPdfConverter extends APdfCreator { private WikiModel model; private PdfContext pdfContext; public WikiToPdfConverter(WikiModel model, PdfContext pdfContext) { this.model = model; this.pdfContext = pdfContext; } @Override protected void build(APdfContainerElement parent) { for (AWikiElement element : model.getElements()) processElement(element, parent); } private void processElement(AWikiElement element, APdfContainerElement parent) { if (element instanceof Paragraph) { parent.nl(defaultFont); processParagraph((Paragraph) element, parent); return; } if (element instanceof Header) { parent.nl(defaultFont); processHeader((Header) element, parent); return; } if (element instanceof Pre) { parent.nl(defaultFont); processPre((Pre) element, parent); return; } if (element instanceof ItemList) { parent.nl(defaultFont); processItemList((ItemList) element, parent); return; } if (element instanceof Table) { parent.nl(defaultFont); processTable((Table) element, parent); return; } throw new RuntimeException("Unsupported Wiki-Element: " + element.getClass().getName()); } private void processTable(Table wikiTable, APdfContainerElement parent) { ATable pdfTable = parent.table(wikiTable.getColumnCount()); pdfTable.setWidth(null); pdfTable.setDefaultCellPadding(2f); for (TableRow wikiRow : wikiTable.getRows()) { ARow pdfRow = pdfTable.row(); for (TableCell wikiCell : wikiRow.getCells()) { ACell pdfCell = pdfRow.cell(); if (wikiCell.isHeader()) { pdfCell.setFontStyle(tableHeaderFont); pdfCell.setBackgroundColor(tableHeaderBackground); processParagraph(wikiCell.getParagraph(), pdfCell, tableHeaderFont); } else { processParagraph(wikiCell.getParagraph(), pdfCell); } } } pdfTable.createCellBorders(Color.GRAY, 0.2f); } private void processItemList(ItemList list, APdfContainerElement parent) { boolean ordered = list.isOrdered(); ATable table = parent.table(1, ordered ? 30 : 45); int counter = 0; for (ItemList.Item item : list.getItems()) { ARow row = table.row(); counter++; row.cell(ordered ? counter + "." : "-", defaultFont); ACell cell = row.cell(); processParagraph(item.getParagraph(), cell); if (item.containsList()) { cell.paragraph().nl(new FontStyle(defaultFont).setSize(0.7f)); processItemList(item.getList(), cell); } } } private void processPre(Pre pre, APdfContainerElement parent) { parent.paragraph().text(pre.getText(), codeFont); } private void processParagraph(Paragraph element, APdfContainerElement parent) { processParagraph(element, parent, defaultFont); } private void processParagraph(Paragraph element, APdfContainerElement parent, FontStyle font) { AParagraph paragraph = parent.paragraph(); for (AWikiElement paragraphElement : element.getElements()) { processParagraphElement(paragraphElement, paragraph, font); } } private void processHeader(Header element, APdfContainerElement parent) { parent.paragraph().text(element.getText(), headerFonts[element.getDepth() - 1]).nl(); } private void processParagraphElement(AWikiElement element, AParagraph parent, FontStyle fontStyle) { if (element instanceof Text) { processText((Text) element, parent, fontStyle); return; } if (element instanceof Highlight) { processHighlight((Highlight) element, parent, fontStyle); return; } if (element instanceof Code) { processCode((Code) element, parent); return; } if (element instanceof EntityReference) { processEntityReference((EntityReference) element, parent); return; } if (element instanceof Link) { processLink((Link) element, parent); return; } if (element instanceof Image) { processImage((Image) element, parent); return; } if (element instanceof LineBreak) { parent.nl(); return; } throw new RuntimeException("Unsupported Wiki-Paragraph-Element: " + element.getClass().getName()); } private void processImage(Image image, AParagraph parent) { AImage pdfImage = pdfContext.appendImage(parent, image); if (pdfImage == null) return; if (image.isThumb()) { if (image.isThumbAlignmentLeft()) { pdfImage.setAlignLeft(); } else { pdfImage.setAlignRight(); } pdfImage.setScaleByWidth(40f); } } private void processLink(Link link, AParagraph parent) { parent.text(link.getLabel(), defaultFont).text(" " + link.getHref(), referenceFont); } private void processEntityReference(EntityReference ref, AParagraph parent) { parent.text(ref.getLabel(), referenceFont); } private void processCode(Code code, AParagraph parent) { parent.text(code.getText(), codeFont); } private void processHighlight(Highlight highlight, AParagraph parent, FontStyle fontStyle) { FontStyle newFontStyle = new FontStyle(fontStyle); if (highlight.isEm()) newFontStyle.setItalic(true); if (highlight.isStrong()) newFontStyle.setBold(true); for (AWikiElement element : highlight.getElements()) { processParagraphElement(element, parent, newFontStyle); } } private void processText(Text text, AParagraph parent, FontStyle fontStyle) { parent.text(text.getText(), fontStyle); } public static void buildPdf(APdfContainerElement parent, String code, PdfContext pdfContext) { if (code == null) return; WikiParser parser = new WikiParser(code); WikiModel model = parser.parse(false); WikiToPdfConverter converter = new WikiToPdfConverter(model, pdfContext); converter.build(parent); } @Override protected String getFilename() { return "wiki"; } }