diff --git a/CHANGELOG.md b/CHANGELOG.md index 03c37bafa..80d00a7b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- new built-in function stringToBase64 + ### Changed - fj-doc-maven-plugin, init, flavour : quarkus-version set to 3.29.2 across all the modules diff --git a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Background.kt b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Background.kt index c4b4845df..3ac65461c 100644 --- a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Background.kt +++ b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Background.kt @@ -10,8 +10,8 @@ class Background : HelperDSL.TagWithText( "background" ) { * Creates a new default Image instance. * @return the new instance. */ - fun image( init: Image.() -> Unit = {} ): Image { - return initTag(Image(), init); + fun image( text: String = "", init: Image.() -> Unit = {} ): Image { + return initTag(Image(text), init); } diff --git a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Body.kt b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Body.kt index 056c3efb9..f4248d7f4 100644 --- a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Body.kt +++ b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Body.kt @@ -31,8 +31,8 @@ class Body : HelperDSL.TagWithText( "body" ) { * Creates a new default Image instance. * @return the new instance. */ - fun image( init: Image.() -> Unit = {} ): Image { - return initTag(Image(), init); + fun image( text: String = "", init: Image.() -> Unit = {} ): Image { + return initTag(Image(text), init); } /** * Creates a new default Phrase instance. diff --git a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Cell.kt b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Cell.kt index 85f44df26..02d451875 100644 --- a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Cell.kt +++ b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Cell.kt @@ -24,8 +24,8 @@ class Cell : HelperDSL.TagWithText( "cell" ) { * Creates a new default Image instance. * @return the new instance. */ - fun image( init: Image.() -> Unit = {} ): Image { - return initTag(Image(), init); + fun image( text: String = "", init: Image.() -> Unit = {} ): Image { + return initTag(Image(text), init); } /** * Creates a new default Phrase instance. diff --git a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Footer.kt b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Footer.kt index cbdd2fdab..2dac1a94b 100644 --- a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Footer.kt +++ b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Footer.kt @@ -17,8 +17,8 @@ class Footer : HelperDSL.TagWithText( "footer" ) { * Creates a new default Image instance. * @return the new instance. */ - fun image( init: Image.() -> Unit = {} ): Image { - return initTag(Image(), init); + fun image( text: String = "", init: Image.() -> Unit = {} ): Image { + return initTag(Image(text), init); } /** * Creates a new default Phrase instance. diff --git a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/FooterExt.kt b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/FooterExt.kt index d0e71d154..25d983109 100644 --- a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/FooterExt.kt +++ b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/FooterExt.kt @@ -24,8 +24,8 @@ class FooterExt : HelperDSL.TagWithText( "footer-ext" ) { * Creates a new default Image instance. * @return the new instance. */ - fun image( init: Image.() -> Unit = {} ): Image { - return initTag(Image(), init); + fun image( text: String = "", init: Image.() -> Unit = {} ): Image { + return initTag(Image(text), init); } /** * Creates a new default Phrase instance. diff --git a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Header.kt b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Header.kt index e880f3048..8dbdd760b 100644 --- a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Header.kt +++ b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Header.kt @@ -17,8 +17,8 @@ class Header : HelperDSL.TagWithText( "header" ) { * Creates a new default Image instance. * @return the new instance. */ - fun image( init: Image.() -> Unit = {} ): Image { - return initTag(Image(), init); + fun image( text: String = "", init: Image.() -> Unit = {} ): Image { + return initTag(Image(text), init); } /** * Creates a new default Phrase instance. diff --git a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/HeaderExt.kt b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/HeaderExt.kt index 19cb10189..699834215 100644 --- a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/HeaderExt.kt +++ b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/HeaderExt.kt @@ -24,8 +24,8 @@ class HeaderExt : HelperDSL.TagWithText( "header-ext" ) { * Creates a new default Image instance. * @return the new instance. */ - fun image( init: Image.() -> Unit = {} ): Image { - return initTag(Image(), init); + fun image( text: String = "", init: Image.() -> Unit = {} ): Image { + return initTag(Image(text), init); } /** * Creates a new default Phrase instance. diff --git a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Image.kt b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Image.kt index c29d7fcbb..cfcd5495a 100644 --- a/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Image.kt +++ b/fj-doc-base-kotlin/src/main/java/org/fugerit/java/doc/base/kotlin/dsl/Image.kt @@ -5,7 +5,15 @@ package org.fugerit.java.doc.base.kotlin.dsl * * This class will provide function to handle all image attributes and kids */ -class Image : HelperDSL.TagWithText( "image" ) { +class Image( text: String = "" ) : HelperDSL.TagWithText( "image" ) { + + init { setText(text) } + /** + * Function to set text content for this element. + */ + + fun setText( value: String ) { addKid( HelperDSL.TextElement( value ) ) } + /** * Function handling url attribute of the Image with specific check on type. diff --git a/fj-doc-base/src/main/docs/doc_xsd_config_ref.html b/fj-doc-base/src/main/docs/doc_xsd_config_ref.html index 369654e89..e69ec17d5 100644 --- a/fj-doc-base/src/main/docs/doc_xsd_config_ref.html +++ b/fj-doc-base/src/main/docs/doc_xsd_config_ref.html @@ -410,6 +410,7 @@

Reference xsd documentation for Venus - Fugerit An image to include in the document (roughly comparable to a HTML 'image' element) + mixed diff --git a/fj-doc-base/src/main/java/org/fugerit/java/doc/base/model/DocImage.java b/fj-doc-base/src/main/java/org/fugerit/java/doc/base/model/DocImage.java index 3eb14b37b..c61f9e19d 100644 --- a/fj-doc-base/src/main/java/org/fugerit/java/doc/base/model/DocImage.java +++ b/fj-doc-base/src/main/java/org/fugerit/java/doc/base/model/DocImage.java @@ -31,6 +31,7 @@ The Apache Software Foundation (http://www.apache.org/). import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; @@ -82,7 +83,9 @@ public static Collection getAcceptedImageTypes() { @Getter @Setter private String alt; @Getter @Setter private int align; - + + @Getter @Setter private String content = ""; + public String getResolvedBase64() { return SafeFunction.get( () -> { String res = this.getBase64(); @@ -94,7 +97,13 @@ public String getResolvedBase64() { } public String getResolvedText() { - return SafeFunction.get( () -> new String( resolveImage( this ) ) ); + return SafeFunction.get( () -> { + if ( StringUtils.isEmpty( this.content ) ) { + return new String( resolveImage( this ) ); + } else { + return this.content; + } + }); } public String getResolvedType() { @@ -134,6 +143,8 @@ public static byte[] resolveImage( DocImage img ) throws IOException { data = Base64Helper.decodeBase64String( base64 ); } else if ( path != null ) { data = byteResolverHelper( path ); + } else if ( StringUtils.isNotEmpty( img.getContent() ) ) { + data = img.getContent().getBytes( StandardCharsets.UTF_8 ); } else { throw new IOException( "Null path provided!" ); } diff --git a/fj-doc-base/src/main/java/org/fugerit/java/doc/base/parser/DocParserContext.java b/fj-doc-base/src/main/java/org/fugerit/java/doc/base/parser/DocParserContext.java index 29d33c762..4e432c981 100644 --- a/fj-doc-base/src/main/java/org/fugerit/java/doc/base/parser/DocParserContext.java +++ b/fj-doc-base/src/main/java/org/fugerit/java/doc/base/parser/DocParserContext.java @@ -120,6 +120,9 @@ public void handleText( String text ) { } else if ( this.currentElement instanceof DocInfo ) { DocInfo docInfo = (DocInfo)this.currentElement; docInfo.getContent().append( text ); + } else if ( this.currentElement instanceof DocImage ) { + DocImage docImage = (DocImage)this.currentElement; + docImage.setContent( docImage.getContent()+text ); } } } diff --git a/fj-doc-base/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-base/reflect-config.json b/fj-doc-base/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-base/reflect-config.json index 399864159..30b81b6e6 100644 --- a/fj-doc-base/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-base/reflect-config.json +++ b/fj-doc-base/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-base/reflect-config.json @@ -1140,6 +1140,9 @@ }, { "name" : "getClass", "parameterTypes" : [ ] + }, { + "name" : "getContent", + "parameterTypes" : [ ] }, { "name" : "getId", "parameterTypes" : [ ] @@ -1188,6 +1191,9 @@ }, { "name" : "setBase64", "parameterTypes" : [ "java.lang.String" ] + }, { + "name" : "setContent", + "parameterTypes" : [ "java.lang.String" ] }, { "name" : "setId", "parameterTypes" : [ "java.lang.String" ] diff --git a/fj-doc-base/src/main/resources/config/doc-2-1.xsd b/fj-doc-base/src/main/resources/config/doc-2-1.xsd index e6817940b..177a21b3b 100644 --- a/fj-doc-base/src/main/resources/config/doc-2-1.xsd +++ b/fj-doc-base/src/main/resources/config/doc-2-1.xsd @@ -6,7 +6,7 @@ * * @project : fj-doc-base * @creation : 2023-08-18 - * @version : 2.1.0-rc.3 (2025-03-22) + * @version : 2.1.0-rc.4 (2025-11-19) * * XSD for fugerit doc configuration */ @@ -408,7 +408,7 @@ An image to include in the document (roughly comparable to a HTML 'image' element) - + diff --git a/fj-doc-base/src/test/java/test/org/fugerit/java/doc/base/model/TestDocImage.java b/fj-doc-base/src/test/java/test/org/fugerit/java/doc/base/model/TestDocImage.java index 0981dbbec..0b04565bc 100644 --- a/fj-doc-base/src/test/java/test/org/fugerit/java/doc/base/model/TestDocImage.java +++ b/fj-doc-base/src/test/java/test/org/fugerit/java/doc/base/model/TestDocImage.java @@ -6,11 +6,13 @@ import lombok.extern.slf4j.Slf4j; +import java.io.IOException; + @Slf4j class TestDocImage extends HelperDocT { @Test - void testElement1() { + void testElement1() throws IOException { DocImage image = new DocImage(); image.setUrl( DocImage.TYPE_JPG ); Assertions.assertEquals( DocImage.TYPE_JPG, image.getResolvedType() ); @@ -22,6 +24,12 @@ void testElement1() { image.setUrl( "cl://txt/test.txt" ); Assertions.assertEquals( "test text", image.getResolvedText() ); log.info( "accepted types : {}", DocImage.getAcceptedImageTypes() ); + String altTest = "alt test"; + image.setContent( altTest ); + Assertions.assertEquals( altTest, image.getResolvedText() ); + image.setUrl( null ); + image.setBase64( null ); + Assertions.assertEquals( altTest.length(), DocImage.resolveImage( image ).length ); } } diff --git a/fj-doc-base/src/test/resources/coverage/template/macro/html_element.ftl b/fj-doc-base/src/test/resources/coverage/template/macro/html_element.ftl index 4beb610b4..9833be9da 100644 --- a/fj-doc-base/src/test/resources/coverage/template/macro/html_element.ftl +++ b/fj-doc-base/src/test/resources/coverage/template/macro/html_element.ftl @@ -55,8 +55,8 @@ <#if docImage.align = 2> <#assign imageAlign="style='display: block; margin-left: auto; margin-right: auto;'"/> - - ${imageAlign!''} <#if (docImage.alt)??> alt="${docImage.alt}" ${imageScaling} src="data:image/png;base64, ${docImage.resolvedBase64}" /> + + ${imageAlign!''} <#if (docImage.alt)??> alt="${docImage.alt}" ${imageScaling} src="data:image/png;base64, <#if docImage.content?has_content>${docImage.content}<#else>${docImage.resolvedBase64}" /> <#macro handleList docList> diff --git a/fj-doc-base/src/test/resources/coverage/xml/default_doc.xml b/fj-doc-base/src/test/resources/coverage/xml/default_doc.xml index 2ae032f76..ae4f18876 100644 --- a/fj-doc-base/src/test/resources/coverage/xml/default_doc.xml +++ b/fj-doc-base/src/test/resources/coverage/xml/default_doc.xml @@ -40,7 +40,7 @@
- +
Name Surname diff --git a/fj-doc-base/src/test/resources/coverage/xml/default_doc_alt.xml b/fj-doc-base/src/test/resources/coverage/xml/default_doc_alt.xml index fc70804a2..a75a12a39 100644 --- a/fj-doc-base/src/test/resources/coverage/xml/default_doc_alt.xml +++ b/fj-doc-base/src/test/resources/coverage/xml/default_doc_alt.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://javacoredoc.fugerit.org https://www.fugerit.org/data/java/doc/xsd/doc-2-1.xsd" > @@ -29,7 +29,9 @@ My sample title -
+ ]]> + +
Name Surname diff --git a/fj-doc-freemarker/src/main/java/org/fugerit/java/doc/freemarker/config/FreeMarkerConfigStep.java b/fj-doc-freemarker/src/main/java/org/fugerit/java/doc/freemarker/config/FreeMarkerConfigStep.java index bfc0ad8a5..037688151 100644 --- a/fj-doc-freemarker/src/main/java/org/fugerit/java/doc/freemarker/config/FreeMarkerConfigStep.java +++ b/fj-doc-freemarker/src/main/java/org/fugerit/java/doc/freemarker/config/FreeMarkerConfigStep.java @@ -153,6 +153,7 @@ public int process(DocProcessContext context, DocProcessData data) throws Except map.put(CleanTextFun.DEFAULT_NAME, new CleanTextFun()); map.put(FormatLocalDateTimeFun.DEFAULT_NAME, new FormatLocalDateTimeFun()); map.put(Base64ToStringFun.DEFAULT_NAME, new Base64ToStringFun()); + map.put(StringToBase64Fun.DEFAULT_NAME, new StringToBase64Fun()); } return res; } diff --git a/fj-doc-freemarker/src/main/java/org/fugerit/java/doc/freemarker/fun/StringToBase64Fun.java b/fj-doc-freemarker/src/main/java/org/fugerit/java/doc/freemarker/fun/StringToBase64Fun.java new file mode 100644 index 000000000..da85226d8 --- /dev/null +++ b/fj-doc-freemarker/src/main/java/org/fugerit/java/doc/freemarker/fun/StringToBase64Fun.java @@ -0,0 +1,23 @@ +package org.fugerit.java.doc.freemarker.fun; + +import freemarker.template.SimpleScalar; +import freemarker.template.TemplateMethodModelEx; +import freemarker.template.TemplateModelException; +import freemarker.template.TemplateScalarModel; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.List; + +public class StringToBase64Fun implements TemplateMethodModelEx { + + public static final String DEFAULT_NAME = "stringToBase64"; + + @Override + public Object exec(@SuppressWarnings("rawtypes") List arguments) throws TemplateModelException { + FMFunHelper.checkParameterNumber( arguments, 1 ); + String content = ((TemplateScalarModel)arguments.get( 0 )).getAsString(); + return new SimpleScalar( Base64.getEncoder().encodeToString( content.getBytes( StandardCharsets.UTF_8 ) ) ); + } + +} diff --git a/fj-doc-freemarker/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-freemarker/reflect-config.json b/fj-doc-freemarker/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-freemarker/reflect-config.json index e58590f4c..2fb1d88e7 100644 --- a/fj-doc-freemarker/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-freemarker/reflect-config.json +++ b/fj-doc-freemarker/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-freemarker/reflect-config.json @@ -2029,6 +2029,42 @@ "name" : "wait", "parameterTypes" : [ "long", "int" ] } ] +}, { + "name" : "org.fugerit.java.doc.freemarker.fun.StringToBase64Fun", + "methods" : [ { + "name" : "", + "parameterTypes" : [ ] + }, { + "name" : "equals", + "parameterTypes" : [ "java.lang.Object" ] + }, { + "name" : "exec", + "parameterTypes" : [ "java.util.List" ] + }, { + "name" : "getClass", + "parameterTypes" : [ ] + }, { + "name" : "hashCode", + "parameterTypes" : [ ] + }, { + "name" : "notify", + "parameterTypes" : [ ] + }, { + "name" : "notifyAll", + "parameterTypes" : [ ] + }, { + "name" : "toString", + "parameterTypes" : [ ] + }, { + "name" : "wait", + "parameterTypes" : [ ] + }, { + "name" : "wait", + "parameterTypes" : [ "long" ] + }, { + "name" : "wait", + "parameterTypes" : [ "long", "int" ] + } ] }, { "name" : "org.fugerit.java.doc.freemarker.fun.TextWrapFun", "methods" : [ { diff --git a/fj-doc-freemarker/src/main/resources/fj_doc_freemarker_config/template/macro/html_element.ftl b/fj-doc-freemarker/src/main/resources/fj_doc_freemarker_config/template/macro/html_element.ftl index 49eb49d82..f7f39cc04 100644 --- a/fj-doc-freemarker/src/main/resources/fj_doc_freemarker_config/template/macro/html_element.ftl +++ b/fj-doc-freemarker/src/main/resources/fj_doc_freemarker_config/template/macro/html_element.ftl @@ -65,7 +65,7 @@ <#assign imageAlign="style='display: block; margin-left: auto; margin-right: auto;'"/> - ${imageAlign!''} <#if (docImage.alt)??> alt="${docImage.alt}" ${imageScaling} src="data:image/png;base64, ${docImage.resolvedBase64}" /> + ${imageAlign!''} <#if (docImage.alt)??> alt="${docImage.alt}" ${imageScaling} src="data:image/png;base64, <#if docImage.content?has_content>${docImage.content}<#else>${docImage.resolvedBase64}" /> diff --git a/fj-doc-freemarker/src/test/resources/fj_doc_test/freemarker-doc-process_alt.xml b/fj-doc-freemarker/src/test/resources/fj_doc_test/freemarker-doc-process_alt.xml index 91c4f9eca..a5066e3c8 100644 --- a/fj-doc-freemarker/src/test/resources/fj_doc_test/freemarker-doc-process_alt.xml +++ b/fj-doc-freemarker/src/test/resources/fj_doc_test/freemarker-doc-process_alt.xml @@ -26,6 +26,7 @@ + diff --git a/fj-doc-freemarker/src/test/resources/fj_doc_test/template/test_01.ftl b/fj-doc-freemarker/src/test/resources/fj_doc_test/template/test_01.ftl index 0f89f4be3..b290cd597 100644 --- a/fj-doc-freemarker/src/test/resources/fj_doc_test/template/test_01.ftl +++ b/fj-doc-freemarker/src/test/resources/fj_doc_test/template/test_01.ftl @@ -63,6 +63,8 @@ base64ToString ${base64ToString('VEVTVA==')} + stringToBase64 ${stringToBase64('TEST')} + italic ${messageFormat()} diff --git a/fj-doc-guide/src/main/docs/asciidoc/chapters/04_1_doc_freemarker_config.adoc b/fj-doc-guide/src/main/docs/asciidoc/chapters/04_1_doc_freemarker_config.adoc index 4d78d42f9..d0d44c77c 100644 --- a/fj-doc-guide/src/main/docs/asciidoc/chapters/04_1_doc_freemarker_config.adoc +++ b/fj-doc-guide/src/main/docs/asciidoc/chapters/04_1_doc_freemarker_config.adoc @@ -209,6 +209,16 @@ NOTE: When using *skipfm* no FreeMarker template syntax should be used in the te | formats a LocalDate, LocalTime or LocalDateTime | (1) - the date/time to format, (2) - the format pattern +| base64ToString +| org.fugerit.java.doc.freemarker.fun.​Base64ToStringFun +| converts a base64 to string +| (1) - base64 to convert to string + +| stringToBase64 +| org.fugerit.java.doc.freemarker.fun.​StringToBase64Fun +| converts a string to base64 +| (1) - the string to convert + |======================================================================================================================================== NOTE: These functions can all be loaded at once with the config step attribute _load-bundled-functions="true"_. \ No newline at end of file diff --git a/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeHandler.java b/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeHandler.java index 0b6b85456..6ed0530b6 100644 --- a/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeHandler.java +++ b/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeHandler.java @@ -2,6 +2,7 @@ import java.io.*; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; @@ -46,6 +47,8 @@ public class PdfFopTypeHandler extends FreeMarkerFopTypeHandler { public static final DocTypeHandler HANDLER = new PdfFopTypeHandler(); + public static final DocTypeHandler HANDLER_UTF8 = new PdfFopTypeHandler( StandardCharsets.UTF_8 ); + public static final String ATT_FOP_CONFIG_MODE = "fop-config-mode"; public static final String ATT_FOP_CONFIG_MODE_DEFAULT = "default"; public static final String ATT_FOP_CONFIG_MODE_CLASS_LOADER = "classloader"; diff --git a/fj-doc-mod-fop/src/main/resources/fj_doc_mod_fop_config/fm-fop-process-config.xml b/fj-doc-mod-fop/src/main/resources/fj_doc_mod_fop_config/fm-fop-process-config.xml index e5084e926..45847ae0d 100644 --- a/fj-doc-mod-fop/src/main/resources/fj_doc_mod_fop_config/fm-fop-process-config.xml +++ b/fj-doc-mod-fop/src/main/resources/fj_doc_mod_fop_config/fm-fop-process-config.xml @@ -26,6 +26,7 @@ + diff --git a/fj-doc-mod-fop/src/main/resources/fj_doc_mod_fop_config/template/macro/doc_element.ftl b/fj-doc-mod-fop/src/main/resources/fj_doc_mod_fop_config/template/macro/doc_element.ftl index 5fe96a1d8..4f3c9a4f8 100644 --- a/fj-doc-mod-fop/src/main/resources/fj_doc_mod_fop_config/template/macro/doc_element.ftl +++ b/fj-doc-mod-fop/src/main/resources/fj_doc_mod_fop_config/template/macro/doc_element.ftl @@ -56,7 +56,7 @@ <#macro handleImage docImage> > <#if docImage.svg> - fox:alt-text="${docImage.alt}" xmlns:svg="http://www.w3.org/2000/svg">${base64ToString(docImage.resolvedBase64)} + fox:alt-text="${docImage.alt}" xmlns:svg="http://www.w3.org/2000/svg"><#if docImage.content?has_content>${docImage.content}<#else>${base64ToString(docImage.resolvedBase64)} <#else> <#if (docImage.scaling)??> <#assign imageScaling="height='${docImage.scaling}%' content-height='${docImage.scaling}%' content-width='scale-to-fit' scaling='uniform' width='${docImage.scaling}%'"/> diff --git a/fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestIssue580SpecialCharacters.java b/fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestIssue580SpecialCharacters.java new file mode 100644 index 000000000..277641264 --- /dev/null +++ b/fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestIssue580SpecialCharacters.java @@ -0,0 +1,62 @@ +package test.org.fugerit.java.doc.mod.fop; + +import lombok.extern.slf4j.Slf4j; +import org.fugerit.java.core.lang.helpers.ClassHelper; +import org.fugerit.java.core.xml.dom.DOMIO; +import org.fugerit.java.doc.base.config.DocInput; +import org.fugerit.java.doc.base.config.DocOutput; +import org.fugerit.java.doc.base.config.DocTypeHandler; +import org.fugerit.java.doc.base.config.DocTypeHandlerDefault; +import org.fugerit.java.doc.mod.fop.PdfFopTypeHandler; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.w3c.dom.Element; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +@Slf4j +class TestIssue580SpecialCharacters { + + private static final String PATH_XML_SAMPLE = "issue/gh580/sample-gh580.xml"; + + private static final String PATH_XML_SAMPLE_ALT_FONT = "issue/gh580/sample-gh580-alt-font.xml"; + + private File testWorker( DocTypeHandler handler, String xmlPath, String outputPath ) throws Exception { + log.info( "xml path : {}, handler: {}, type: {}", xmlPath, handler.getClass().getName(), handler.getType() ); + File outputFile = new File( outputPath ); + log.info( "output file: {}, delete : {}", outputFile.getAbsolutePath(), outputFile.delete() ); + try (Reader reader = new InputStreamReader( ClassHelper.loadFromDefaultClassLoader(xmlPath) ); + OutputStream os = new FileOutputStream( outputFile ) ) { + handler.handle( DocInput.newInput( handler.getType(), reader ), DocOutput.newOutput( os ) ); + } + return outputFile; + } + + /* + * working example using SVG : + * + */ + @Test + void testGeneratedPdf() throws Exception { + DocTypeHandler handler = PdfFopTypeHandler.HANDLER_UTF8; + File outputFile = this.testWorker( handler, PATH_XML_SAMPLE, "target/issue-gh580.pdf" ); + Assertions.assertTrue( outputFile.exists() ) ; + } + + /* + * working example using DejaVu Font https://dejavu-fonts.github.io/ + */ + @Test + void testGeneratedPdfWithAlternateFont() throws Exception { + DocTypeHandlerDefault handler = new PdfFopTypeHandler(StandardCharsets.UTF_8); + String xmlConfig = "\n"; + Element element = DOMIO.loadDOMDoc( xmlConfig ).getDocumentElement(); + handler.configure( element ); + File outputFile = this.testWorker( handler, PATH_XML_SAMPLE_ALT_FONT, "target/issue-gh580-alt-font.pdf" ); + Assertions.assertTrue( outputFile.exists() ) ; + } + +} diff --git a/fj-doc-mod-fop/src/test/resources/issue/gh580/DejaVuSans.ttf b/fj-doc-mod-fop/src/test/resources/issue/gh580/DejaVuSans.ttf new file mode 100644 index 000000000..e5f7eecce Binary files /dev/null and b/fj-doc-mod-fop/src/test/resources/issue/gh580/DejaVuSans.ttf differ diff --git a/fj-doc-mod-fop/src/test/resources/issue/gh580/fop-config-issue-580.xml b/fj-doc-mod-fop/src/test/resources/issue/gh580/fop-config-issue-580.xml new file mode 100644 index 000000000..34f7a4ff3 --- /dev/null +++ b/fj-doc-mod-fop/src/test/resources/issue/gh580/fop-config-issue-580.xml @@ -0,0 +1,35 @@ + + + + true + + + true + + + . + + + . + + + + + + + + + + + + + + 72 + + 72 + + + + + \ No newline at end of file diff --git a/fj-doc-mod-fop/src/test/resources/issue/gh580/sample-gh580-alt-font.xml b/fj-doc-mod-fop/src/test/resources/issue/gh580/sample-gh580-alt-font.xml new file mode 100644 index 000000000..2b9804259 --- /dev/null +++ b/fj-doc-mod-fop/src/test/resources/issue/gh580/sample-gh580-alt-font.xml @@ -0,0 +1,21 @@ + + + + + + 10;10;10;30 + Basic example alt font + fj doc venus sample source xml + fugerit79 + it + true + DejaVuSans + + + Sample special characters reproducer ■ □ ■ □ with font DejaVuSans + + + \ No newline at end of file diff --git a/fj-doc-mod-fop/src/test/resources/issue/gh580/sample-gh580.xml b/fj-doc-mod-fop/src/test/resources/issue/gh580/sample-gh580.xml new file mode 100644 index 000000000..0e9503baa --- /dev/null +++ b/fj-doc-mod-fop/src/test/resources/issue/gh580/sample-gh580.xml @@ -0,0 +1,21 @@ + + + + + 10;10;10;30 + Basic example + fj doc venus sample source xml + fugerit79 + it + true + + + Sample special characters reproducer ■ □ ■ □ + Working POC with SVG : + ]]> + + + \ No newline at end of file