[FOray-commit] SF.net SVN: foray:[12280] trunk/foray/foray-fotree/src
Modular XSL-FO Implementation for Java.
Status: Alpha
Brought to you by:
victormote
|
From: <vic...@us...> - 2021-12-27 16:22:51
|
Revision: 12280
http://sourceforge.net/p/foray/code/12280
Author: victormote
Date: 2021-12-27 16:22:48 +0000 (Mon, 27 Dec 2021)
Log Message:
-----------
Conform to aXSL change: Add method to get the refined value of the text.
Modified Paths:
--------------
trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoText4a.java
trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoTextCharacters4a.java
trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoTextWords4a.java
Added Paths:
-----------
trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoRefinedText4a.java
trunk/foray/foray-fotree/src/test/java/org/foray/fotree/fo/obj/
trunk/foray/foray-fotree/src/test/java/org/foray/fotree/fo/obj/FoRefinedText4aTests.java
Added: trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoRefinedText4a.java
===================================================================
--- trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoRefinedText4a.java (rev 0)
+++ trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoRefinedText4a.java 2021-12-27 16:22:48 UTC (rev 12280)
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2021 The FOray Project.
+ * http://www.foray.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This work is in part derived from the following work(s), used with the
+ * permission of the licensor:
+ * Apache FOP, licensed by the Apache Software Foundation
+ *
+ */
+
+/*
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ * $LastChangedBy$
+ */
+
+package org.foray.fotree.fo.obj;
+
+import org.foray.common.primitive.XmlCharacterUtils;
+import org.foray.common.sequence.IntArrayBuilder;
+
+import org.axsl.common.sequence.IntSequencePlus;
+import org.axsl.common.value.LinefeedTreatment;
+import org.axsl.common.value.TextTransform;
+
+/**
+ * Wraps a sequence of characters and overlays it with the changes needed to convert it to the "refined" values for
+ * FO Tree.
+ */
+public class FoRefinedText4a implements CharSequence {
+
+ /** The wrapped raw text. */
+ private CharSequence wrapped;
+
+ /** The text-transform. */
+ private TextTransform textTransform;
+
+ /** The codepoint immediate before {@link #wrapped}. */
+ private int codepointBefore;
+
+ /** The sorted list of indexes that are deleted. */
+ private IntSequencePlus deleted;
+
+ /** The sorted list of indexes that are changed. This is parallel with {@link #deltas}. */
+ private IntSequencePlus changed;
+
+ /** The new values for indexes that are changed. This is parallel with {@link #changed}. */
+ private CharSequence deltas;
+
+ public FoRefinedText4a(final CharSequence wrapped, final LinefeedTreatment linefeedTreatment,
+ final TextTransform textTransform, final boolean whiteSpaceCollapse, final int codepointBefore,
+ final int codepointAfter) {
+ this.wrapped = wrapped;
+ this.textTransform = textTransform;
+ this.codepointBefore = codepointBefore;
+ final IntArrayBuilder deleted = new IntArrayBuilder();
+ final IntArrayBuilder changed = new IntArrayBuilder();
+ final StringBuilder deltas = new StringBuilder();
+
+ /* Apply linefeed-treatment. */
+ for (int index = 0; index < wrapped.length(); index ++) {
+ /* Check linefeed-treatment. */
+ final char raw = wrapped.charAt(index);
+ final char filtered = FoText4a.applyLinefeedTreatment(raw, linefeedTreatment);
+ if (filtered == FoTextCharacters4a.DISCARD_CHAR) {
+ deleted.append(index);
+ } else if (filtered != raw) {
+ changed.append(index);
+ deltas.append(filtered);
+ }
+ }
+
+ /* Ignore text-transform for now. It can be efficiently applied as the chars are read. */
+
+ /* Apply white-space-collapse. */
+ for (int index = 0; index < wrapped.length(); index ++) {
+ if (deleted.indexOf(index) > -1) {
+ /* Item at this index has already been deleted. Skip it. */
+ continue;
+ }
+
+ final int deltaIndex = changed.indexOf(index);
+ final char raw = deltaIndex > -1 ? deltas.charAt(deltaIndex) : wrapped.charAt(index);
+ final int charBefore = index == 0 ? codepointBefore : wrapped.charAt(index - 1);
+ final int charAfter = index == wrapped.length() - 1 ? codepointAfter : wrapped.charAt(index + 1);
+ final char filtered = FoText4a.applyWhiteSpaceCollapse(charBefore, raw, charAfter);
+ if (filtered == FoTextCharacters4a.DISCARD_CHAR) {
+ deleted.insertSortedUnique(index);
+ } else if (filtered != raw) {
+ final int changeIndex = changed.insertSortedUnique(index);
+ deltas.insert(changeIndex, filtered);
+ }
+ }
+
+ this.deleted = deleted.toIntArray().asPlus();
+ this.changed = changed.toIntArray().asPlus();
+ this.deltas = deltas.toString();
+ }
+
+ @Override
+ public int length() {
+ return this.wrapped.length() - this.deleted.length();
+ }
+
+ @Override
+ public char charAt(final int index) {
+ int realIndex = index;
+ if (this.deleted.length() > 0) {
+ int deletedIndex = 0;
+ while (this.deleted.intAt(deletedIndex) <= realIndex) {
+ realIndex ++;
+ deletedIndex ++;
+ }
+ }
+
+ if (this.deleted.binarySearch(realIndex) > -1) {
+ return FoTextCharacters4a.DISCARD_CHAR;
+ }
+ final int deltaIndex = this.changed.binarySearch(realIndex);
+ final char filteredChar = deltaIndex > -1 ? this.deltas.charAt(deltaIndex) : this.wrapped.charAt(realIndex);
+
+ /* Apply text-transform. */
+ if (this.textTransform == TextTransform.CAPITALIZE) {
+ final int codepointBefore = index == 0 ? this.codepointBefore : charAt(index - 1);
+ final boolean isFirstCharInWord = XmlCharacterUtils.isXMLWhitespace(codepointBefore);
+ return FoText4a.applyTextTransform(this.textTransform, isFirstCharInWord, filteredChar);
+
+ } else {
+ return FoText4a.applyTextTransformSimple(this.textTransform, filteredChar);
+ }
+ }
+
+ @Override
+ public CharSequence subSequence(final int start, final int end) {
+ final StringBuilder builder = new StringBuilder();
+ for (int index = start; index < end; index ++) {
+ final char c = charAt(index);
+ builder.append(c);
+ }
+ return builder;
+ }
+
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ for (int index = 0; index < length(); index ++) {
+ final char c = charAt(index);
+ builder.append(c);
+ }
+ return builder.toString();
+ }
+
+}
Property changes on: trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoRefinedText4a.java
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Rev
\ No newline at end of property
Modified: trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoText4a.java
===================================================================
--- trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoText4a.java 2021-12-27 13:32:48 UTC (rev 12279)
+++ trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoText4a.java 2021-12-27 16:22:48 UTC (rev 12280)
@@ -462,6 +462,25 @@
}
/**
+ * Applies text-transform to one character.
+ * Same as {@link #applyTextTransform(TextTransform, boolean, char)}, except doesn't handle the case of
+ * {@link TextTransform#CAPITALIZE}, which in many cases has more expensive preparation.
+ * @param textTransform The text-transform value to use.
+ * @param c The character to be converted.
+ * @return The converted character, or {@code c} if no conversion is performed.
+ */
+ public static char applyTextTransformSimple(final TextTransform textTransform, final char c) {
+ switch (textTransform) {
+ case UPPERCASE: return java.lang.Character.toUpperCase(c);
+ case LOWERCASE: return java.lang.Character.toLowerCase(c);
+ case CAPITALIZE: throw new UnsupportedOperationException("Use applyTextTransform for\"Capitalize.\"");
+ case NONE:
+ default:
+ return c;
+ }
+ }
+
+ /**
* <p>Applies white-space-collapse to one character of charArray.</p>
* <p>Per http://lists.w3.org/Archives/Public/xsl-editors/2002OctDec/0004, elements in previous or subsequent FOs
* should <em>not</em> be considered.</p>
@@ -480,13 +499,13 @@
/**
* Applies white-space-collapse to one char.
- * @param charBefore The character before c, or {@link AbstractCharacterSequence#DISCARD_CHAR} if there is none.
+ * @param codepointBefore The codepoint before c, or -1 if there is none.
* @param c The character being considered for conversion.
- * @param charAfter The character after c, or {@link AbstractCharacterSequence#DISCARD_CHAR} if there is none.
+ * @param codepointAfter The codepoint after c, or if there is none.
* @return {@link #DISCARD_CHAR} if the previous character is whitespace or if the next character is a line-feed.
* If neither of these is true, returns the original character.
*/
- public static char applyWhiteSpaceCollapse(final char charBefore, final char c, final char charAfter) {
+ public static char applyWhiteSpaceCollapse(final int codepointBefore, final char c, final int codepointAfter) {
if (! XmlCharacterUtils.isXMLWhitespace(c)) {
/* If it is not whitespace, nothing should change. */
return c;
@@ -495,11 +514,11 @@
/* If it is a linefeed, nothing should change. */
return c;
}
- if (charBefore != AbstractCharacterSequence.DISCARD_CHAR
- && XmlCharacterUtils.isXMLWhitespace(charBefore)) {
+ if (codepointBefore != AbstractCharacterSequence.DISCARD_CHAR
+ && XmlCharacterUtils.isXMLWhitespace(codepointBefore)) {
return FoTextCharacters4a.DISCARD_CHAR;
}
- if (charAfter == Basic_Latin_Block.CONTROL_LINE_FEED) {
+ if (codepointAfter == Basic_Latin_Block.CONTROL_LINE_FEED) {
return FoTextCharacters4a.DISCARD_CHAR;
}
return c;
Modified: trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoTextCharacters4a.java
===================================================================
--- trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoTextCharacters4a.java 2021-12-27 13:32:48 UTC (rev 12279)
+++ trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoTextCharacters4a.java 2021-12-27 16:22:48 UTC (rev 12280)
@@ -30,6 +30,7 @@
import org.foray.fotree.FoObj;
+import org.axsl.common.value.LinefeedTreatment;
import org.axsl.common.value.TextTransform;
import org.axsl.fotree.FoContext;
import org.axsl.fotree.FoVisitor;
@@ -476,4 +477,17 @@
return visitor.visit(this);
}
+ @Override
+ public CharSequence getRefinedText(final LinefeedTreatment linefeedTreatment, final TextTransform textTransform,
+ final boolean whiteSpaceCollapse, final int codepointBefore, final int codepointAfter) {
+ /* If none of the factors will result in any change, just return this. */
+ if (linefeedTreatment == LinefeedTreatment.PRESERVE
+ && textTransform == TextTransform.NONE
+ && whiteSpaceCollapse == false) {
+ return this;
+ }
+ return new FoRefinedText4a(this, linefeedTreatment, textTransform, whiteSpaceCollapse, codepointBefore,
+ codepointAfter);
+ }
+
}
Modified: trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoTextWords4a.java
===================================================================
--- trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoTextWords4a.java 2021-12-27 13:32:48 UTC (rev 12279)
+++ trunk/foray/foray-fotree/src/main/java/org/foray/fotree/fo/obj/FoTextWords4a.java 2021-12-27 16:22:48 UTC (rev 12280)
@@ -240,4 +240,17 @@
return this;
}
+ @Override
+ public CharSequence getRefinedText(final LinefeedTreatment linefeedTreatment, final TextTransform textTransform,
+ final boolean whiteSpaceCollapse, final int codepointBefore, final int codepointAfter) {
+ /* If none of the factors will result in any change, just return this. */
+ if (linefeedTreatment == LinefeedTreatment.PRESERVE
+ && textTransform == TextTransform.NONE
+ && whiteSpaceCollapse == false) {
+ return this;
+ }
+ return new FoRefinedText4a(this, linefeedTreatment, textTransform, whiteSpaceCollapse, codepointBefore,
+ codepointAfter);
+ }
+
}
Added: trunk/foray/foray-fotree/src/test/java/org/foray/fotree/fo/obj/FoRefinedText4aTests.java
===================================================================
--- trunk/foray/foray-fotree/src/test/java/org/foray/fotree/fo/obj/FoRefinedText4aTests.java (rev 0)
+++ trunk/foray/foray-fotree/src/test/java/org/foray/fotree/fo/obj/FoRefinedText4aTests.java 2021-12-27 16:22:48 UTC (rev 12280)
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2021 The FOray Project.
+ * http://www.foray.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This work is in part derived from the following work(s), used with the
+ * permission of the licensor:
+ * Apache FOP, licensed by the Apache Software Foundation
+ *
+ */
+
+/*
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ * $LastChangedBy$
+ */
+
+package org.foray.fotree.fo.obj;
+
+import org.axsl.common.value.LinefeedTreatment;
+import org.axsl.common.value.TextTransform;
+import org.axsl.unicode.block.Basic_Latin_Block;
+import org.axsl.unicode.block.General_Punctuation_Block;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests of {@link FoRefinedText4a}.
+ */
+public class FoRefinedText4aTests {
+
+ @Test
+ public void linefeedTreatment_Test_001() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(Basic_Latin_Block.CONTROL_LINE_FEED);
+ builder.append("Word1");
+ builder.append(Basic_Latin_Block.CONTROL_LINE_FEED);
+ builder.append("Word2");
+ builder.append(Basic_Latin_Block.CONTROL_LINE_FEED);
+ builder.append("Word3");
+ builder.append(Basic_Latin_Block.CONTROL_LINE_FEED);
+ final String input = builder.toString();
+ Assert.assertEquals(19, input.length());
+
+ /* Make the other factors neutral. */
+ final TextTransform textTransform = TextTransform.NONE;
+ final boolean whiteSpaceCollapse = false;
+
+ /* Test IGNORE. */
+ FoRefinedText4a out =
+ new FoRefinedText4a(input, LinefeedTreatment.IGNORE, textTransform, whiteSpaceCollapse, -1, -1);
+ Assert.assertEquals(15, out.length());
+ String expected = "Word1Word2Word3";
+ Assert.assertEquals(expected, out.toString());
+
+ /* Test PRESERVE. */
+ out = new FoRefinedText4a(input, LinefeedTreatment.PRESERVE, textTransform, whiteSpaceCollapse, -1, -1);
+ expected = input;
+ Assert.assertEquals(expected, out.toString());
+
+ /* Test TREAT_AS_SPACE. */
+ out = new FoRefinedText4a(input, LinefeedTreatment.TREAT_AS_SPACE, textTransform, whiteSpaceCollapse, -1, -1);
+ expected = " Word1 Word2 Word3 ";
+ Assert.assertEquals(expected, out.toString());
+
+ /* Test TREAT_AS_ZERO_WIDTH_SPACE. */
+ out = new FoRefinedText4a(input, LinefeedTreatment.TREAT_AS_ZERO_WIDTH_SPACE, textTransform, whiteSpaceCollapse,
+ -1, -1);
+ expected = input.replace(Basic_Latin_Block.CONTROL_LINE_FEED, General_Punctuation_Block.ZERO_WIDTH_SPACE);
+ Assert.assertEquals(expected, out.toString());
+ }
+
+}
Property changes on: trunk/foray/foray-fotree/src/test/java/org/foray/fotree/fo/obj/FoRefinedText4aTests.java
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Rev
\ No newline at end of property
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|