diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/context/StyleReference.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/context/StyleReference.java
index 0faabf21b..b2a9a623c 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/context/StyleReference.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/context/StyleReference.java
@@ -27,6 +27,7 @@
import java.util.List;
import java.util.logging.Level;
+import com.openhtmltopdf.css.sheet.FontFaceRule;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -281,7 +282,7 @@ public void removeStyle(Element e) {
}
}
- public List getFontFaceRules() {
+ public List getFontFaceRules() {
return _matcher.getFontFaceRules();
}
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/newmatch/Matcher.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/newmatch/Matcher.java
index 869d6b68f..e8caefd70 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/newmatch/Matcher.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/newmatch/Matcher.java
@@ -34,10 +34,7 @@
import com.openhtmltopdf.css.extend.AttributeResolver;
import com.openhtmltopdf.css.extend.StylesheetFactory;
import com.openhtmltopdf.css.extend.TreeResolver;
-import com.openhtmltopdf.css.sheet.MediaRule;
-import com.openhtmltopdf.css.sheet.PageRule;
-import com.openhtmltopdf.css.sheet.Ruleset;
-import com.openhtmltopdf.css.sheet.Stylesheet;
+import com.openhtmltopdf.css.sheet.*;
import com.openhtmltopdf.util.Util;
import com.openhtmltopdf.util.XRLog;
@@ -61,7 +58,7 @@ public class Matcher {
private Set _visitElements;
private List _pageRules;
- private List _fontFaceRules;
+ private List _fontFaceRules;
public Matcher(
TreeResolver tr, AttributeResolver ar, StylesheetFactory factory, List stylesheets, String medium) {
@@ -71,7 +68,7 @@ public Matcher(
_styleFactory = factory;
_pageRules = new ArrayList();
- _fontFaceRules = new ArrayList();
+ _fontFaceRules = new ArrayList();
docMapper = createDocumentMapper(stylesheets, medium);
}
@@ -125,7 +122,7 @@ public PageInfo getPageCascadedStyle(String pageName, String pseudoPage) {
return new PageInfo(props, style, marginBoxes);
}
- public List getFontFaceRules() {
+ public List getFontFaceRules() {
return _fontFaceRules;
}
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/FSDOMMutator.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/FSDOMMutator.java
new file mode 100644
index 000000000..86b9f899a
--- /dev/null
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/FSDOMMutator.java
@@ -0,0 +1,8 @@
+package com.openhtmltopdf.extend;
+
+/**
+ * Allows to modify the HTML document DOM after it has been parsed
+ */
+public interface FSDOMMutator {
+ void mutateDocument(org.w3c.dom.Document document);
+}
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Layer.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Layer.java
index 06e4386fb..401571ef6 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Layer.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Layer.java
@@ -434,7 +434,7 @@ protected List applyTranform(RenderingContext c, Box box) {
* We must apply the top/bottom margins from the previous pages, otherwise
* our transform center is wrong.
*/
- for (int i = 0; i < c.getPageNo(); i++) {
+ for (int i = 0; i < c.getPageNo() && i < getPages().size(); i++) {
RectPropertySet prevMargin = getPages().get(i).getMargin(c);
relTranslateY += prevMargin.top() + prevMargin.bottom();
}
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/outputdevice/helper/BaseRendererBuilder.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/outputdevice/helper/BaseRendererBuilder.java
new file mode 100644
index 000000000..f3af0908b
--- /dev/null
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/outputdevice/helper/BaseRendererBuilder.java
@@ -0,0 +1,355 @@
+package com.openhtmltopdf.outputdevice.helper;
+
+import com.openhtmltopdf.bidi.BidiReorderer;
+import com.openhtmltopdf.bidi.BidiSplitterFactory;
+import com.openhtmltopdf.extend.*;
+import com.openhtmltopdf.layout.Layer;
+import org.w3c.dom.Document;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Baseclass for all RendererBuilders (PDF and Java2D), has all common settings
+ */
+@SuppressWarnings("unchecked")
+public abstract class BaseRendererBuilder {
+ public static final float PAGE_SIZE_LETTER_WIDTH = 8.5f;
+ public static final float PAGE_SIZE_LETTER_HEIGHT = 11.0f;
+ public static final PageSizeUnits PAGE_SIZE_LETTER_UNITS = PageSizeUnits.INCHES;
+ protected final List _domMutators = new ArrayList();
+ protected HttpStreamFactory _httpStreamFactory;
+ protected FSCache _cache;
+ protected FSUriResolver _resolver;
+ protected String _html;
+ protected String _baseUri;
+ protected Document _document;
+ protected SVGDrawer _svgImpl;
+ protected SVGDrawer _mathmlImpl;
+ protected String _replacementText;
+ protected FSTextBreaker _lineBreaker;
+ protected FSTextBreaker _charBreaker;
+ protected FSTextTransformer _unicodeToUpperTransformer;
+ protected FSTextTransformer _unicodeToLowerTransformer;
+ protected FSTextTransformer _unicodeToTitleTransformer;
+ protected BidiSplitterFactory _splitter;
+ protected BidiReorderer _reorderer;
+ protected boolean _textDirection = false;
+ protected Float _pageWidth;
+ protected Float _pageHeight;
+ protected boolean _isPageSizeInches;
+ protected String _uri;
+ protected File _file;
+ protected boolean _testMode = false;
+ protected int _initialPageNumber;
+ protected short _pagingMode = Layer.PAGED_MODE_PRINT;
+ protected FSObjectDrawerFactory _objectDrawerFactory;
+ protected String _preferredTransformerFactoryImplementationClass = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
+
+ /**
+ * Add a DOM mutator to this builder. DOM mutators allow to modify the DOM
+ * before it is rendered. e.g. LaTeXDOMMutator can be used to translate latex
+ * text within a <latex> node to HTMl and MathML.
+ *
+ * @param domMutator
+ * the DOM Mutator
+ * @return this for method chaining
+ */
+ public TFinalClass addDOMMutator(FSDOMMutator domMutator) {
+ _domMutators.add(domMutator);
+ return (TFinalClass) this;
+ }
+
+ /**
+ * This method should be considered advanced and is not required for most
+ * setups. Set a preferred implementation class for use as
+ * javax.xml.transform.TransformerFactory. Use null to let a default
+ * implementation class be used. The default is
+ * "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl". This
+ * seems to work with most systems but not JBoss Wildfly and related setups. In
+ * this case you can use null to let the container use whatever
+ * TransformerFactory it has available.
+ *
+ * @param transformerFactoryClass
+ * @return this for method chaining
+ */
+ public final TFinalClass useTransformerFactoryImplementationClass(String transformerFactoryClass) {
+ this._preferredTransformerFactoryImplementationClass = transformerFactoryClass;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * The default text direction of the document. LTR by default.
+ *
+ * @param textDirection
+ * @return this for method chaining
+ */
+ public final TFinalClass defaultTextDirection(TextDirection textDirection) {
+ this._textDirection = textDirection == TextDirection.RTL;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Whether to use test mode and output the PDF uncompressed. Turned off by
+ * default.
+ *
+ * @param mode
+ * @return this for method chaining
+ */
+ public final TFinalClass testMode(boolean mode) {
+ this._testMode = mode;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Provides an HttpStreamFactory implementation if the user desires to use an
+ * external HTTP/HTTPS implementation. Uses URL::openStream by default.
+ *
+ * @param factory
+ * @return
+ */
+ public final TFinalClass useHttpStreamImplementation(HttpStreamFactory factory) {
+ this._httpStreamFactory = factory;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Provides a uri resolver to resolve relative uris or private uri schemes.
+ *
+ * @param resolver
+ * @return
+ */
+ public final TFinalClass useUriResolver(FSUriResolver resolver) {
+ this._resolver = resolver;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Provides an external cache which can choose to cache items between runs, such
+ * as fonts or logo images.
+ *
+ * @param cache
+ * @return
+ */
+ public final TFinalClass useCache(FSCache cache) {
+ this._cache = cache;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Provides a text splitter to split text into directional runs. Does nothing by
+ * default.
+ *
+ * @param splitter
+ * @return
+ */
+ public final TFinalClass useUnicodeBidiSplitter(BidiSplitterFactory splitter) {
+ this._splitter = splitter;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Provides a reorderer to properly reverse RTL text. No-op by default.
+ *
+ * @param reorderer
+ * @return
+ */
+ public final TFinalClass useUnicodeBidiReorderer(BidiReorderer reorderer) {
+ this._reorderer = reorderer;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Provides a string containing XHTML/XML to convert to PDF.
+ *
+ * @param html
+ * @param baseUri
+ * @return
+ */
+ public final TFinalClass withHtmlContent(String html, String baseUri) {
+ this._html = html;
+ this._baseUri = baseUri;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Provides a w3c DOM Document acquired from an external source.
+ *
+ * @param doc
+ * @param baseUri
+ * @return
+ */
+ public final TFinalClass withW3cDocument(org.w3c.dom.Document doc, String baseUri) {
+ this._document = doc;
+ this._baseUri = baseUri;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Provides a URI to convert to PDF. The URI MUST point to a strict XHTML/XML
+ * document.
+ *
+ * @param uri
+ * @return
+ */
+ public final TFinalClass withUri(String uri) {
+ this._uri = uri;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Provides a file to convert to PDF. The file MUST contain XHTML/XML in UTF-8
+ * encoding.
+ *
+ * @param file
+ * @return this for method chaining
+ */
+ public final TFinalClass withFile(File file) {
+ this._file = file;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Uses the specified SVG drawer implementation.
+ *
+ * @param svgImpl the SVG implementation
+ * @return this for method chaining
+ */
+ public final TFinalClass useSVGDrawer(SVGDrawer svgImpl) {
+ this._svgImpl = svgImpl;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Use the specified MathML implementation.
+ *
+ * @param mathMlImpl the MathML implementation
+ * @return this for method chaining
+ */
+ public final TFinalClass useMathMLDrawer(SVGDrawer mathMlImpl) {
+ this._mathmlImpl = mathMlImpl;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * The replacement text to use if a character is cannot be renderered by any of
+ * the specified fonts. This is not broken across lines so should be one or zero
+ * characters for best results. Also, make sure it can be rendered by at least
+ * one of your specified fonts! The default is the # character.
+ *
+ * @param replacement the default replacement text
+ * @return this for method chaining
+ */
+ public final TFinalClass useReplacementText(String replacement) {
+ this._replacementText = replacement;
+ return (TFinalClass) this;
+ }
+
+ /**
+ * Specify the line breaker. By default a Java default BreakIterator line
+ * instance is used with US locale. Additionally, this is wrapped with
+ * UrlAwareLineBreakIterator to also break before the forward slash (/)
+ * character so that long URIs can be broken on to multiple lines.
+ *
+ * You may want to use a BreakIterator with a different locale (wrapped by
+ * UrlAwareLineBreakIterator or not) or a more advanced BreakIterator from icu4j
+ * (see the rtl-support module for an example).
+ *
+ * @param breaker
+ * @return
+ */
+ public final TFinalClass useUnicodeLineBreaker(FSTextBreaker breaker) {
+ this._lineBreaker = breaker;
+ return (TFinalClass)this;
+ }
+
+ /**
+ * Specify the character breaker. By default a break iterator character instance
+ * is used with US locale. Currently this is used when
+ * word-wrap: break-word
is in effect.
+ *
+ * @param breaker
+ * @return
+ */
+ public final TFinalClass useUnicodeCharacterBreaker(FSTextBreaker breaker) {
+ this._charBreaker = breaker;
+ return (TFinalClass)this;
+ }
+
+ /**
+ * Specify a transformer to use to upper case strings. By default
+ * String::toUpperCase(Locale.US)
is used.
+ *
+ * @param tr
+ * @return
+ */
+ public final TFinalClass useUnicodeToUpperTransformer(FSTextTransformer tr) {
+ this._unicodeToUpperTransformer = tr;
+ return (TFinalClass)this;
+ }
+
+ /**
+ * Specify a transformer to use to lower case strings. By default
+ * String::toLowerCase(Locale.US)
is used.
+ *
+ * @param tr
+ * @return
+ */
+ public final TFinalClass useUnicodeToLowerTransformer(FSTextTransformer tr) {
+ this._unicodeToLowerTransformer = tr;
+ return (TFinalClass)this;
+ }
+
+ /**
+ * Specify a transformer to title case strings. By default a best effort
+ * implementation (non locale aware) is used.
+ *
+ * @param tr
+ * @return
+ */
+ public final TFinalClass useUnicodeToTitleTransformer(FSTextTransformer tr) {
+ this._unicodeToTitleTransformer = tr;
+ return (TFinalClass)this;
+ }
+
+ /**
+ * Specifies the default page size to use if none is specified in CSS.
+ *
+ * @param pageWidth
+ * @param pageHeight
+ * @param units
+ * either mm or inches.
+ * @see {@link #PAGE_SIZE_LETTER_WIDTH}, {@link #PAGE_SIZE_LETTER_HEIGHT} and
+ * {@link #PAGE_SIZE_LETTER_UNITS}
+ * @return
+ */
+ public final TFinalClass useDefaultPageSize(float pageWidth, float pageHeight, PageSizeUnits units) {
+ this._pageWidth = pageWidth;
+ this._pageHeight = pageHeight;
+ this._isPageSizeInches = (units == PageSizeUnits.INCHES);
+ return (TFinalClass)this;
+ }
+
+ /**
+ * Set a factory for <object> drawers
+ *
+ * @param objectDrawerFactory
+ * Object Drawer Factory
+ * @return this for method chaining
+ */
+ public final TFinalClass useObjectDrawerFactory(FSObjectDrawerFactory objectDrawerFactory) {
+ this._objectDrawerFactory = objectDrawerFactory;
+ return (TFinalClass)this;
+ }
+
+ public enum TextDirection {
+ RTL, LTR;
+ }
+ public enum PageSizeUnits {
+ MM, INCHES
+ }
+ public enum FontStyle {
+ NORMAL, ITALIC, OBLIQUE
+ }
+}
diff --git a/openhtmltopdf-examples/pom.xml b/openhtmltopdf-examples/pom.xml
index ac5267a6e..9409350c5 100644
--- a/openhtmltopdf-examples/pom.xml
+++ b/openhtmltopdf-examples/pom.xml
@@ -59,6 +59,11 @@
openhtmltopdf-objects
${project.version}
+
+ com.openhtmltopdf
+ openhtmltopdf-latex-support
+ ${project.version}
+
com.vladsch.flexmark
diff --git a/openhtmltopdf-examples/src/main/java/com/openhtmltopdf/freemarker/FreeMarkerGenerator.java b/openhtmltopdf-examples/src/main/java/com/openhtmltopdf/freemarker/FreeMarkerGenerator.java
index 9a6e8b197..53c26d5b3 100644
--- a/openhtmltopdf-examples/src/main/java/com/openhtmltopdf/freemarker/FreeMarkerGenerator.java
+++ b/openhtmltopdf-examples/src/main/java/com/openhtmltopdf/freemarker/FreeMarkerGenerator.java
@@ -2,9 +2,12 @@
import com.openhtmltopdf.bidi.support.ICUBidiReorderer;
import com.openhtmltopdf.bidi.support.ICUBidiSplitter;
+import com.openhtmltopdf.latexsupport.LaTeXDOMMutator;
+import com.openhtmltopdf.mathmlsupport.MathMLDrawer;
import com.openhtmltopdf.objects.StandardObjectDrawerFactory;
import com.openhtmltopdf.pdfboxout.PdfBoxRenderer;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
+import com.openhtmltopdf.svgsupport.BatikSVGDrawer;
import com.openhtmltopdf.swing.NaiveUserAgent.DefaultUriResolver;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.*;
@@ -62,6 +65,9 @@ public byte[] generatePDF(String html) throws IOException {
builder.useUnicodeBidiReorderer(new ICUBidiReorderer());
builder.defaultTextDirection(PdfRendererBuilder.TextDirection.LTR);
builder.withHtmlContent(html, "/freemarker");
+ builder.useSVGDrawer(new BatikSVGDrawer());
+ builder.useMathMLDrawer(new MathMLDrawer());
+ builder.addDOMMutator(LaTeXDOMMutator.INSTANCE);
builder.useUriResolver(new DefaultUriResolver() {
@Override
public String resolveURI(String baseUri, String uri) {
@@ -85,7 +91,7 @@ public String resolveURI(String baseUri, String uri) {
try {
pdfBoxRenderer.layout();
pdfBoxRenderer.createPDF();
- } catch (Exception e) {
+ } finally {
pdfBoxRenderer.close();
}
outputStream.close();
diff --git a/openhtmltopdf-examples/src/main/java/com/openhtmltopdf/testcases/TestcaseRunner.java b/openhtmltopdf-examples/src/main/java/com/openhtmltopdf/testcases/TestcaseRunner.java
index 2ef2b18f7..90703f369 100644
--- a/openhtmltopdf-examples/src/main/java/com/openhtmltopdf/testcases/TestcaseRunner.java
+++ b/openhtmltopdf-examples/src/main/java/com/openhtmltopdf/testcases/TestcaseRunner.java
@@ -11,6 +11,8 @@
import javax.imageio.ImageIO;
+import com.openhtmltopdf.latexsupport.LaTeXDOMMutator;
+import com.openhtmltopdf.outputdevice.helper.BaseRendererBuilder;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.util.Charsets;
import org.w3c.dom.Element;
@@ -27,7 +29,6 @@
import com.openhtmltopdf.mathmlsupport.MathMLDrawer;
import com.openhtmltopdf.objects.StandardObjectDrawerFactory;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
-import com.openhtmltopdf.pdfboxout.PdfRendererBuilder.TextDirection;
import com.openhtmltopdf.render.DefaultObjectDrawerFactory;
import com.openhtmltopdf.render.RenderingContext;
import com.openhtmltopdf.svgsupport.BatikSVGDrawer;
@@ -105,10 +106,13 @@ public static void main(String[] args) throws Exception {
runTestCase("math-ml");
+ runTestCase("latex-sample");
+
/*
* Broken rotate() on the second page
*/
runTestCase("RepeatedTableTransformSample");
+
/* Add additional test cases here. */
}
@@ -171,9 +175,10 @@ private static void renderPDF(String html, OutputStream outputStream) throws Exc
PdfRendererBuilder builder = new PdfRendererBuilder();
builder.useUnicodeBidiSplitter(new ICUBidiSplitter.ICUBidiSplitterFactory());
builder.useUnicodeBidiReorderer(new ICUBidiReorderer());
- builder.defaultTextDirection(TextDirection.LTR);
+ builder.defaultTextDirection(BaseRendererBuilder.TextDirection.LTR);
builder.useSVGDrawer(new BatikSVGDrawer());
builder.useMathMLDrawer(new MathMLDrawer());
+ builder.addDOMMutator(LaTeXDOMMutator.INSTANCE);
builder.useObjectDrawerFactory(buildObjectDrawerFactory());
builder.withHtmlContent(html, TestcaseRunner.class.getResource("/testcases/").toString());
@@ -193,6 +198,8 @@ private static DefaultObjectDrawerFactory buildObjectDrawerFactory() {
private static void renderPNG(String html, final String filename) throws Exception {
Java2DRendererBuilder builder = new Java2DRendererBuilder();
builder.useSVGDrawer(new BatikSVGDrawer());
+ builder.useMathMLDrawer(new MathMLDrawer());
+ builder.addDOMMutator(LaTeXDOMMutator.INSTANCE);
builder.useObjectDrawerFactory(buildObjectDrawerFactory());
builder.withHtmlContent(html, TestcaseRunner.class.getResource("/testcases/").toString());
BufferedImagePageProcessor bufferedImagePageProcessor = new BufferedImagePageProcessor(
diff --git a/openhtmltopdf-examples/src/main/resources/freemarker/featuredocumentation.ftl b/openhtmltopdf-examples/src/main/resources/freemarker/featuredocumentation.ftl
index 23f8a1675..eb826de16 100644
--- a/openhtmltopdf-examples/src/main/resources/freemarker/featuredocumentation.ftl
+++ b/openhtmltopdf-examples/src/main/resources/freemarker/featuredocumentation.ftl
@@ -76,6 +76,15 @@
h1, h2, h3, h4 {
-fs-page-break-min-height: 4cm;
}
+
+ /* does not seem to work (yet?) */
+ #tocPlaceholder:after {
+ content:element(toc);
+ display:block;
+ min-height:20px;
+ min-width:20px;
+ border:2px solid black;
+ }
@@ -98,11 +107,33 @@
Page /
+[#assign tableOfContentHTML = ""]
+[#assign sectionAnchorCounter = 0]
+[#macro hn level]
+ [#assign sectionAnchorCounter = sectionAnchorCounter + 1]
+
+ [#local content][#nested][/#local]
+ ${content}
+ [#assign tableOfContentHTML]
+ ${tableOfContentHTML}
+ ${content}
+ [/#assign]
+[/#macro]
+[#macro h1][@hn 1][#nested][/@hn][/#macro]
+[#macro h2][@hn 2][#nested][/@hn][/#macro]
+[#macro h3][@hn 3][#nested][/@hn][/#macro]
+[#macro h4][@hn 4][#nested][/@hn][/#macro]
+
[#macro pomCode]
[#local content][#nested][/#local]
${content?trim?html}
[/#macro]
+[#macro javaCode]
+ [#local content][#nested][/#local]
+${content?trim?html}
+
+[/#macro]
[#macro htmlCode]
[#local content][#nested][/#local]
@@ -125,7 +156,9 @@
[/#macro]
-OpenHtmlToPdf Feature Documentation
+
+
+[@h1]OpenHtmlToPdf Feature Documentation[/@h1]
This documentation tries to show the advanced features of OpenHtmlToPdf. To generate the documentation a
@@ -136,7 +169,7 @@ IDEA IDE this is a very productive environment to build reports.
Please lookup the source of this document if you want to know some tricks not explicit mentioned in this documentation.
-Pagebreak Tuning
+[@h2]Pagebreak Tuning[/@h2]
In a perfect world [@htmlCode]style="page-break-inside: avoid"[/@htmlCode] would just work and all reports would look
beautiful. OpenHtmlToPdf tries its best to avoid a page break inside. But this is not always possible and also rather
@@ -153,7 +186,68 @@ Example:
[/@htmlCode]
-Objects
+[@h2]MathML & LaTeX[/@h2]
+To display math you can use MathML and latex. To do so you need the dependencies:
+
+[@pomCode]
+
+ com.openhtmltopdf
+ openhtmltopdf-mathml-support
+ ...
+
+
+ com.openhtmltopdf
+ openhtmltopdf-latex-support
+ ...
+
+[/@pomCode]
+
+If you don't use the LaTeX feature you don't need to include the openhtmltopdf-latex-support.
+You must activate the support in the Builder to use it:
+
+[@javaCode]
+builder.useMathMLDrawer(new MathMLDrawer());
+builder.addDOMMutator(LaTeXDOMMutator.INSTANCE);
+[/@javaCode]
+
+The LaTeX support translates a LaTeX fragment using SnuggleTeX to HTML+MathML, which is then
+rendered using the MathML support.
+
+[@htmlCodeAndExec]
+
+ This is a small inline formular: $$a^2 + b^2 = c^2$$. You can use many LaTeX
+ features and environments. The exact amount of supported features is depending on
+ StruggleTex and JEuclid which are the backing libraries for the LaTeX and MathML support.
+
+ $$\sum\limits_{i=1}^n i^2 = \frac{n(n+1)(2n+1)}{6}$$
+
+ $\prod\limits_{i=1}^n x = x^n$
+
+[/@htmlCodeAndExec]
+
+Here is some pure MathML:
+
+[@htmlCodeAndExec]
+
+
+ a
+ x
+
+
+ b
+ +
+ c
+
+
+
+
+
+
+If you are writing the document by hand it may be just simpler to use LaTeX:
+$$a x (b+c)$$
+[/@htmlCodeAndExec]
+
+[@h2]Objects[/@h2]
OpenHtmlToPdf comes with some builtin objects, which you can use to quickly create diagrams, add background PDF images
and so on. To use them include the openhtmltopdf-objects dependency in your pom:
@@ -166,7 +260,7 @@ and so on. To use them include the openhtmltopdf-objects dependency in your pom:
[/@pomCode]
-Merge Background PDF
+[@h3]Merge Background PDF[/@h3]
You can add a watermark / background to your document. To do so you should place
@@ -181,7 +275,7 @@ lower corner.
pdfpage : Page to import from the PDF file.
-JFreeGraph
+[@h3]JFreeGraph[/@h3]
For simple charts you can use the builtin objects for JFreeGraph. Note: You must specify the dependency to JFreeMarker
in your
@@ -198,7 +292,7 @@ POM, because it is declared as a optional dependency on openhtmltopdf-objects.
If you specify a URL for a data point then the segment in the diagram used for that datapoint is a link to that URL.
Note: This only works in Acrobat Reader, all other PDF Viewer ignore this feature.
-The Pie Diagram
+[@h4]The Pie Diagram[/@h4]
[@htmlCodeAndExec]
[/@htmlCodeAndExec]
-The Bar Diagram
+[@h4]The Bar Diagram[/@h4]
[@htmlCodeAndExec]
[/@htmlCodeAndExec]
+
+
+
+
Table of Content
+
+ ${tableOfContentHTML}
+
+