diff --git a/pipeline-braille-utils/css-utils/src/main/resources/xml/transform/block-translator-template.xsl b/pipeline-braille-utils/css-utils/src/main/resources/xml/transform/block-translator-template.xsl
index 4ea085e5c..275a9daf1 100644
--- a/pipeline-braille-utils/css-utils/src/main/resources/xml/transform/block-translator-template.xsl
+++ b/pipeline-braille-utils/css-utils/src/main/resources/xml/transform/block-translator-template.xsl
@@ -77,8 +77,8 @@
+ css:computed-properties($inline-properties, false(), $this)
+ [not(@value=css:initial-value(@name))]))"/>
diff --git a/pipeline-braille-utils/css/css-calabash/src/main/java/org/daisy/braille/css/calabash/CSSInlineStep.java b/pipeline-braille-utils/css/css-calabash/src/main/java/org/daisy/braille/css/calabash/CSSInlineStep.java
index 0b0765ace..1cc9e1c83 100755
--- a/pipeline-braille-utils/css/css-calabash/src/main/java/org/daisy/braille/css/calabash/CSSInlineStep.java
+++ b/pipeline-braille-utils/css/css-calabash/src/main/java/org/daisy/braille/css/calabash/CSSInlineStep.java
@@ -112,10 +112,12 @@ public void run() throws SaxonApiException {
XdmNode source = sourcePipe.read();
Document doc = (Document)DocumentOverNodeInfo.wrap(source.getUnderlyingNode());
URL defaultSheet = asURL(emptyToNull(getOption(_default_stylesheet, "")));
- resultPipe.write((new InlineCSSWriter(doc, runtime, defaultSheet)).getResult()); }
+ resultPipe.write((new InlineCSSWriter(doc, runtime, defaultSheet)).getResult());
+ }
catch (Exception e) {
logger.error("css:inline failed", e);
- throw new XProcException(step.getNode(), e); }
+ throw new XProcException(step.getNode(), e);
+ }
}
@Component(
@@ -202,7 +204,8 @@ else if (attr.getPrefix() != null)
addAttribute(new QName(attr.getPrefix(), attr.getNamespaceURI(), attr.getLocalName()), attr.getNodeValue());
else if ("style".equals(attr.getLocalName())) {}
else
- addAttribute(new QName(attr.getNamespaceURI(), attr.getLocalName()), attr.getNodeValue()); }
+ addAttribute(new QName(attr.getNamespaceURI(), attr.getLocalName()), attr.getNodeValue());
+ }
StringBuilder style = new StringBuilder();
NodeData brailleData = brailleStylemap.get((Element)node);
if (brailleData != null)
@@ -226,17 +229,20 @@ else if ("style".equals(attr.getLocalName())) {}
else
page = pages.get(pageProperty.toString());
if (page != null)
- insertPageStyle(style, page, pages.get("auto")); }
+ insertPageStyle(style, page, pages.get("auto"));
+ }
else if (isRoot) {
RulePage page = pages.get("auto");
if (page != null)
- insertPageStyle(style, page, null); }
- if (normalizeSpace(style).length() > 0) {
- addAttribute(_style, style.toString().trim()); }
+ insertPageStyle(style, page, null);
+ }
+ if (normalizeSpace(style).length() > 0)
+ addAttribute(_style, style.toString().trim());
receiver.startContent();
for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling())
traverse(child);
- addEndElement(); }
+ addEndElement();
+ }
else if (node.getNodeType() == Node.COMMENT_NODE)
addComment(node.getNodeValue());
else if (node.getNodeType() == Node.TEXT_NODE)
@@ -256,7 +262,8 @@ public void addStartElement(Element element) {
List namespaces = new ArrayList();
Iterators.addAll(namespaces, NamespaceIterator.iterateNamespaces(inode));
inscopeNS = Iterables.toArray(namespaces, NamespaceBinding.class);
- seenRoot = true; }
+ seenRoot = true;
+ }
receiver.setSystemId(element.getBaseURI());
addStartElement(new NameOfNode(inode), inode.getSchemaType(), inscopeNS);
}
@@ -282,14 +289,17 @@ private static void insertStyle(StringBuilder builder, NodeData nodeData) {
builder.append(termToString.apply(value));
else {
CSSProperty prop = nodeData.getProperty(key);
- builder.append(prop); }
- builder.append("; "); }
+ builder.append(prop);
+ }
+ builder.append("; ");
+ }
}
private static void insertPseudoStyle(StringBuilder builder, NodeData nodeData, Selector.PseudoDeclaration decl) {
if (builder.length() > 0 && !builder.toString().endsWith("} ")) {
builder.insert(0, "{ ");
- builder.append("} "); }
+ builder.append("} ");
+ }
builder.append(decl.isPseudoElement() ? "::" : ":").append(decl.value()).append(" { ");
insertStyle(builder, nodeData);
builder.append("} ");
@@ -298,7 +308,8 @@ private static void insertPseudoStyle(StringBuilder builder, NodeData nodeData,
private static void insertPageStyle(StringBuilder builder, RulePage rulePage, RulePage inheritFrom) {
if (builder.length() > 0 && !builder.toString().endsWith("} ")) {
builder.insert(0, "{ ");
- builder.append("} "); }
+ builder.append("} ");
+ }
builder.append("@page ");
String pseudo = rulePage.getPseudo();
if (pseudo != null && !"".equals(pseudo))
@@ -307,7 +318,8 @@ private static void insertPageStyle(StringBuilder builder, RulePage rulePage, Ru
List seen = new ArrayList();
for (Declaration decl : Iterables.filter(rulePage, Declaration.class)) {
seen.add(decl.getProperty());
- insertDeclaration(builder, decl); }
+ insertDeclaration(builder, decl);
+ }
if (inheritFrom != null)
for (Declaration decl : Iterables.filter(inheritFrom, Declaration.class))
if (!seen.contains(decl.getProperty()))
@@ -315,7 +327,8 @@ private static void insertPageStyle(StringBuilder builder, RulePage rulePage, Ru
seen.clear();
for (RuleMargin margin : Iterables.filter(rulePage, RuleMargin.class)) {
seen.add(margin.getMarginArea().value);
- insertMarginStyle(builder, margin); }
+ insertMarginStyle(builder, margin);
+ }
if (inheritFrom != null)
for (RuleMargin margin : Iterables.filter(inheritFrom, RuleMargin.class))
if (!seen.contains(margin.getMarginArea().value))
diff --git a/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/BrailleCSSDeclarationTransformer.java b/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/BrailleCSSDeclarationTransformer.java
index 2a0beacb1..522502edf 100644
--- a/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/BrailleCSSDeclarationTransformer.java
+++ b/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/BrailleCSSDeclarationTransformer.java
@@ -17,6 +17,7 @@
import org.daisy.braille.css.BrailleCSSProperty.Page;
import org.daisy.braille.css.BrailleCSSProperty.StringSet;
import org.daisy.braille.css.BrailleCSSProperty.TextIndent;
+import org.daisy.braille.css.BrailleCSSProperty.TextTransform;
import cz.vutbr.web.css.CSSFactory;
import cz.vutbr.web.css.CSSProperty;
@@ -281,6 +282,32 @@ private boolean processTextIndent(Declaration d,
d, properties, values);
}
+ @SuppressWarnings("unused")
+ private boolean processTextTransform(Declaration d,
+ Map properties, Map> values) {
+ if (d.size() == 1 && genericOneIdent(TextTransform.class, d, properties))
+ return true;
+
+ TermList list = tf.createList();
+ for (Term> t : d.asList()) {
+ if (t instanceof TermIdent) {
+ String value = ((TermIdent)t).getValue().toLowerCase();
+ if (!value.equals("none") && !value.equals("auto")
+ && !value.equals("uppercase") && !value.equals("lowercase"))
+ list.add(t);
+ }
+ else
+ return false;
+ }
+
+ if (list.isEmpty())
+ return false;
+
+ properties.put("text-transform", TextTransform.list_values);
+ values.put("text-transform", list);
+ return true;
+ }
+
/****************************************************************
* GENERIC METHODS
****************************************************************/
diff --git a/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/BrailleCSSProperty.java b/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/BrailleCSSProperty.java
index 0f84bbe10..7b673d5f8 100644
--- a/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/BrailleCSSProperty.java
+++ b/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/BrailleCSSProperty.java
@@ -239,4 +239,27 @@ public String toString() {
return text;
}
}
+
+ public enum TextTransform implements BrailleCSSProperty {
+ list_values(""), NONE("none"), AUTO("auto"), UPPERCASE("uppercase"), LOWERCASE("lowercase"), INHERIT("inherit");
+
+ private String text;
+
+ private TextTransform(String text) {
+ this.text = text;
+ }
+
+ public boolean inherited() {
+ return false;
+ }
+
+ public boolean equalsInherit() {
+ return this == INHERIT;
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+ }
}
diff --git a/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/SupportedBrailleCSS.java b/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/SupportedBrailleCSS.java
index ecb8c0204..91cabd3e2 100644
--- a/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/SupportedBrailleCSS.java
+++ b/pipeline-braille-utils/css/css-core/src/main/java/org/daisy/braille/css/SupportedBrailleCSS.java
@@ -32,6 +32,7 @@
import org.daisy.braille.css.BrailleCSSProperty.Page;
import org.daisy.braille.css.BrailleCSSProperty.StringSet;
import org.daisy.braille.css.BrailleCSSProperty.TextIndent;
+import org.daisy.braille.css.BrailleCSSProperty.TextTransform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,7 +44,7 @@ public class SupportedBrailleCSS implements SupportedCSS {
private static Logger log = LoggerFactory.getLogger(SupportedBrailleCSS.class);
- private static final int TOTAL_SUPPORTED_DECLARATIONS = 35;
+ private static final int TOTAL_SUPPORTED_DECLARATIONS = 36;
private static final TermFactory tf = CSSFactory.getTermFactory();
@@ -231,6 +232,8 @@ private void setSupportedCSS() {
embossedProperties.add("string-set");
props.put("content", Content.NONE);
embossedProperties.add("content");
+ props.put("text-transform", TextTransform.AUTO);
+ embossedProperties.add("text-transform");
/* ----------- */
/* media print */
diff --git a/pipeline-braille-utils/css/css-core/src/main/resources/xml/base.xsl b/pipeline-braille-utils/css/css-core/src/main/resources/xml/base.xsl
index 22b670cd4..1a266e091 100644
--- a/pipeline-braille-utils/css/css-core/src/main/resources/xml/base.xsl
+++ b/pipeline-braille-utils/css/css-core/src/main/resources/xml/base.xsl
@@ -409,6 +409,12 @@
+
+
+
+
+
+
@@ -456,6 +462,17 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/pipeline-braille-utils/css/css-core/src/main/resources/xml/braille-css.xsl b/pipeline-braille-utils/css/css-core/src/main/resources/xml/braille-css.xsl
index 078e1f33d..25bd0d6d4 100644
--- a/pipeline-braille-utils/css/css-core/src/main/resources/xml/braille-css.xsl
+++ b/pipeline-braille-utils/css/css-core/src/main/resources/xml/braille-css.xsl
@@ -51,6 +51,7 @@
'white-space',
'hyphens',
'size',
+ 'text-transform',
'font-style',
'font-weight',
'text-decoration',
@@ -89,6 +90,7 @@
re:exact(re:or(('normal','pre-wrap','pre-line'))),
re:exact(re:or(('auto','manual','none'))),
re:exact(concat('(',$css:NON_NEGATIVE_INTEGER_RE,')\s+(',$css:NON_NEGATIVE_INTEGER_RE,')')),
+ re:exact(re:or(($css:IDENT_LIST_RE,'none','auto','uppercase','lowercase'))),
re:exact(re:or(('normal','italic','oblique'))),
re:exact(re:or(('normal','bold','100','200','300','400','500','600','700','800','900'))),
re:exact(re:or(('none','underline','overline','line-through','blink'))),
@@ -130,6 +132,7 @@
'.*',
'.*',
'.*',
+ '.*',
'.*')"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pipeline-braille-utils/css/css-core/src/test/xspec/test_braille-css.xspec b/pipeline-braille-utils/css/css-core/src/test/xspec/test_braille-css.xspec
index 60dbef9b9..56237e9bf 100644
--- a/pipeline-braille-utils/css/css-core/src/test/xspec/test_braille-css.xspec
+++ b/pipeline-braille-utils/css/css-core/src/test/xspec/test_braille-css.xspec
@@ -322,4 +322,21 @@
+
+
+
+
+
+ <_ css:text-transform="bold">
+ <_>
+
+
+
+
+
+
+
+
+
+
diff --git a/pipeline-braille-utils/liblouis-utils/src/main/resources/xml/transform/liblouis-block-translate.xsl b/pipeline-braille-utils/liblouis-utils/src/main/resources/xml/transform/liblouis-block-translate.xsl
index 4828c5e6c..e4389d32a 100755
--- a/pipeline-braille-utils/liblouis-utils/src/main/resources/xml/transform/liblouis-block-translate.xsl
+++ b/pipeline-braille-utils/liblouis-utils/src/main/resources/xml/transform/liblouis-block-translate.xsl
@@ -15,8 +15,8 @@
-
+ select="css:computed-properties($inline-properties, true(), parent::*)"/>
+
diff --git a/pipeline-braille-utils/liblouis-utils/src/test/xspec/test_liblouis-block-translate.xspec b/pipeline-braille-utils/liblouis-utils/src/test/xspec/test_liblouis-block-translate.xspec
index 8622aa3b1..818eb7b19 100644
--- a/pipeline-braille-utils/liblouis-utils/src/test/xspec/test_liblouis-block-translate.xspec
+++ b/pipeline-braille-utils/liblouis-utils/src/test/xspec/test_liblouis-block-translate.xspec
@@ -23,4 +23,25 @@
+
+
+
+
+
+ foo bar
+
+
+
+
+
+
+
+
+ ⠋⠕⠕ ⠃⠜
+
+
+
+
+
+
diff --git a/pipeline-braille-utils/liblouis/liblouis-core/src/main/java/org/daisy/pipeline/braille/liblouis/impl/LiblouisJnaImpl.java b/pipeline-braille-utils/liblouis/liblouis-core/src/main/java/org/daisy/pipeline/braille/liblouis/impl/LiblouisJnaImpl.java
index 44cb5084e..f2eb13ef3 100644
--- a/pipeline-braille-utils/liblouis/liblouis-core/src/main/java/org/daisy/pipeline/braille/liblouis/impl/LiblouisJnaImpl.java
+++ b/pipeline-braille-utils/liblouis/liblouis-core/src/main/java/org/daisy/pipeline/braille/liblouis/impl/LiblouisJnaImpl.java
@@ -5,6 +5,7 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -91,11 +92,15 @@ public File[] invoke(String tableList, File base) {
logger.debug("Resolved to " + join(resolved, ","));
else
logger.error("Table could not be resolved");
- return resolved; }};
- Louis.getLibrary().lou_registerTableResolver(_tableResolver); }
+ return resolved;
+ }
+ };
+ Louis.getLibrary().lou_registerTableResolver(_tableResolver);
+ }
catch (Throwable e) {
logger.error("liblouis service could not be loaded", e);
- throw e; }
+ throw e;
+ }
}
@Deactivate
@@ -116,7 +121,9 @@ protected void bindLibrary(BundledNativePath path) {
if (libraryPath != null) {
Louis.setLibraryPath(asFile(libraryPath));
nativePath = path;
- logger.debug("Registering liblouis library: " + libraryPath); }}
+ logger.debug("Registering liblouis library: " + libraryPath);
+ }
+ }
}
protected void unbindLibrary(BundledNativePath path) {
@@ -194,10 +201,14 @@ private Iterable get(final URI[] table, String hyphenator, L
try {
translators = Optional.fromNullable(
new LiblouisTranslatorHyphenatorImpl(table)
- ).asSet(); }
+ ).asSet();
+ }
catch (CompilationException e) {
- logger.warn("Could not create translator for table: " + Arrays.toString(table), e); }
- break; }}
+ logger.warn("Could not create translator for table: " + Arrays.toString(table), e);
+ }
+ break;
+ }
+ }
String hyphenatorQuery = "(locale:" + locale + ")";
if (!"auto".equals(hyphenator))
hyphenatorQuery = hyphenatorQuery + "(hyphenator:" + hyphenator + ")";
@@ -208,18 +219,26 @@ private Iterable get(final URI[] table, String hyphenator, L
hyphenators.get(hyphenatorQuery),
new Function() {
public LiblouisTranslator apply(Hyphenator hyphenator) {
- try { return new LiblouisTranslatorImpl(table, hyphenator); }
+ try { return new LiblouisTranslatorImpl(table, hyphenator);
+ }
catch (CompilationException e) {
- logger.warn("Could not create translator for table: " + Arrays.toString(table), e); }
- return null; }}),
- Predicates.notNull())); }
+ logger.warn("Could not create translator for table: " + Arrays.toString(table), e);
+ }
+ return null;
+ }
+ }),
+ Predicates.notNull()));
+ }
try {
translators = Iterables.concat(
translators,
- Optional.fromNullable(new LiblouisTranslatorImpl(table)).asSet()); }
+ Optional.fromNullable(new LiblouisTranslatorImpl(table)).asSet());
+ }
catch (CompilationException e) {
- logger.warn("Could not create translator for table: " + Arrays.toString(table), e); }
- return translators; }
+ logger.warn("Could not create translator for table: " + Arrays.toString(table), e);
+ }
+ return translators;
+ }
logger.debug("Could not resolve table: " + Arrays.toString(table));
return empty;
}
@@ -243,8 +262,12 @@ public Iterable delegate(String query) {
tableProvider.get(locale),
new Function>() {
public Iterable apply(URI[] table) {
- return LiblouisJnaImpl.this.get(table, hyphenator, locale); }}));
- return empty; }};
+ return LiblouisJnaImpl.this.get(table, hyphenator, locale);
+ }
+ }));
+ return empty;
+ }
+ };
public Iterable get(String query) {
return provider.get(query);
@@ -297,11 +320,20 @@ public String[] transform(String[] text, String[] cssStyle) {
byte[] typeform = new byte[cssStyle.length];
boolean[] hyphenate = new boolean[cssStyle.length];
for (int i = 0; i < cssStyle.length; i++) {
- Map style = CSS_PARSER.split(cssStyle[i]);
- typeform[i] = typeformFromInlineCSS(style);
+ Map style = new HashMap(CSS_PARSER.split(cssStyle[i]));
+ String val = style.remove("text-transform");
+ typeform[i] = Typeform.PLAIN;
+ if (val != null) {
+ text[i] = textFromTextTransform(text[i], val);
+ typeform[i] |= typeformFromTextTransform(val);
+ }
+ val = style.remove("hyphens");
hyphenate[i] = false;
- if (style.containsKey("hyphens") && "auto".equals(style.get("hyphens")))
- hyphenate[i] = true; }
+ if (val != null)
+ if ("auto".equals(val))
+ hyphenate[i] = true;
+ typeform[i] |= typeformFromInlineCSS(style);
+ }
return transform(text, typeform, hyphenate);
}
@@ -339,7 +371,8 @@ public String[] transform(String[] text, byte[] typeform, boolean[] hyphenate) {
boolean someNotHyphenate = false;
for (int i = 0; i < hyphenate.length; i++) {
if (hyphenate[i]) someHyphenate = true;
- else someNotHyphenate = true; }
+ else someNotHyphenate = true;
+ }
if (someHyphenate) {
byte[] autoHyphens = doHyphenate(_text);
if (someNotHyphenate) {
@@ -353,9 +386,13 @@ public String[] transform(String[] text, byte[] typeform, boolean[] hyphenate) {
for (int k = 0; k < unhyphenated[j].length() - 1; k++)
autoHyphens[i++] = 0;
if (i < autoHyphens.length)
- autoHyphens[i++] = 0; }}}
+ autoHyphens[i++] = 0;
+ }
+ }
+ }
for (int i = 0; i < autoHyphens.length; i++)
- positions[i] += autoHyphens[i]; }
+ positions[i] += autoHyphens[i];
+ }
byte[] _typeform = null;
for (byte b : typeform)
if (b != Typeform.PLAIN) {
@@ -363,11 +400,14 @@ public String[] transform(String[] text, byte[] typeform, boolean[] hyphenate) {
int i = 0;
while (unhyphenated[i].length() == 0) i++;
for (int j = 0; j < _typeform.length; j++) {
+ _typeform[j] = typeform[i];
if (positions != null && j < positions.length && (positions[j] & 4) == 4) {
i++;
- while (unhyphenated[i].length() == 0) i++; }
- _typeform[j] = typeform[i]; }
- break; }
+ while (unhyphenated[i].length() == 0) i++;
+ }
+ }
+ break;
+ }
try {
// Translate
@@ -388,7 +428,8 @@ public String[] transform(String[] text, byte[] typeform, boolean[] hyphenate) {
for (String s : SEGMENT_SPLITTER.split(braille)) {
rv[i++] = s;
while (i < text.length && unhyphenated[i].length() == 0)
- rv[i++] = ""; }
+ rv[i++] = "";
+ }
if (i == text.length)
return rv;
else {
@@ -407,9 +448,11 @@ public String[] transform(String[] text, byte[] typeform, boolean[] hyphenate) {
for (int j = 0; j < positions.length; j++) {
if ((positions[j] & 4) == 4) {
i++;
- while (i < text.length && unhyphenated[i].length() == 0) i++; }
+ while (i < text.length && unhyphenated[i].length() == 0) i++;
+ }
int n = (i % 31) + 1;
- positions[j] |= (byte)(n << 3); }
+ positions[j] |= (byte)(n << 3);
+ }
r = translator.translate(_text, positions, _typeform);
braille = r.getBraille();
outputPositions = r.getHyphenPositions();
@@ -425,7 +468,9 @@ public String[] transform(String[] text, byte[] typeform, boolean[] hyphenate) {
rv[i++] = b.toString();
b = new StringBuffer();
while (((n - i - 1) % 31) > 0)
- rv[i++] = ""; }}
+ rv[i++] = "";
+ }
+ }
b.append(braille.charAt(braille.length() - 1));
rv[i++] = b.toString();
while (i < text.length && unhyphenated[i].length() == 0)
@@ -433,9 +478,13 @@ public String[] transform(String[] text, byte[] typeform, boolean[] hyphenate) {
if (i == text.length)
return rv;
else
- throw new RuntimeException("Coding error"); }}}
+ throw new RuntimeException("Coding error");
+ }
+ }
+ }
catch (TranslationException e) {
- throw new RuntimeException(e); }
+ throw new RuntimeException(e);
+ }
}
protected byte[] doHyphenate(String text) {
@@ -446,9 +495,11 @@ protected byte[] doHyphenate(String text) {
public String display(String braille) {
try {
- return translator.display(braille); }
+ return translator.display(braille);
+ }
catch (TranslationException e) {
- throw new RuntimeException(e); }
+ throw new RuntimeException(e);
+ }
}
}
@@ -491,25 +542,30 @@ public String[] hyphenate(String text[]) {
for (String s : SEGMENT_SPLITTER.split(_text)) {
while (unhyphenated[i].length() == 0)
rv[i++] = "";
- rv[i++] = s; }
- while(i < text.length)
+ rv[i++] = s;
+ }
+ while (i < text.length)
rv[i++] = "";
- return rv; }
+ return rv;
+ }
}
@Override
protected byte[] doHyphenate(String text) {
- try { return translator.hyphenate(text); }
+ try {
+ return translator.hyphenate(text);
+ }
catch (TranslationException e) {
- throw new RuntimeException(e); }
+ throw new RuntimeException(e);
+ }
}
}
private final static Splitter.MapSplitter CSS_PARSER
= Splitter.on(';').omitEmptyStrings().withKeyValueSeparator(Splitter.on(':').limit(2).trimResults());
-
+
/**
- * @parameter cssStyle An inline CSS style
+ * @parameter style An inline CSS style
* @returns the corresponding typeform. Possible values are:
* - 0 = PLAIN
* - 1 = ITALIC (font-style: italic|oblique)
@@ -527,13 +583,61 @@ protected static byte typeformFromInlineCSS(Map style) {
for (String prop : style.keySet()) {
String value = style.get(prop);
if (prop.equals("font-style") && (value.equals("italic") || value.equals("oblique")))
- typeform += Typeform.ITALIC;
+ typeform |= Typeform.ITALIC;
else if (prop.equals("font-weight") && value.equals("bold"))
- typeform += Typeform.BOLD;
+ typeform |= Typeform.BOLD;
else if (prop.equals("text-decoration") && value.equals("underline"))
- typeform += Typeform.UNDERLINE;
+ typeform |= Typeform.UNDERLINE;
else
- logger.warn("Inline CSS property {} not supported", prop); }
+ logger.warn("Inline CSS property {} not supported", prop);
+ }
+ return typeform;
+ }
+
+ private final static Splitter TEXT_TRANSFORM_PARSER = Splitter.on(' ').omitEmptyStrings().trimResults();
+
+ /**
+ * @parameter text The text to be transformed.
+ * @parameter textTransform A text-transform value as a space separated list of keywords.
+ * @returns the transformed text, or the original text if no transformations were performed.
+ */
+ protected static String textFromTextTransform(String text, String textTransform) {
+ for (String tt : TEXT_TRANSFORM_PARSER.split(textTransform)) {
+ if (tt.equals("uppercase"))
+ text = text.toUpperCase();
+ else if (tt.equals("lowercase"))
+ text = text.toLowerCase();
+ else
+ logger.warn("text-transform: {} not supported", tt);
+ }
+ return text;
+ }
+
+ /**
+ * @parameter textTransform A text-transform value as a space separated list of keywords.
+ * @returns the corresponding typeform. Possible values are:
+ * - 0 = PLAIN
+ * - 1 = ITALIC (louis-ital)
+ * - 2 = BOLD (louis-bold)
+ * - 4 = UNDERLINE (louis-under)
+ * - 8 = COMPUTER (louis-comp)
+ * These values can be added for multiple emphasis.
+ * @see http://liblouis.googlecode.com/svn/documentation/liblouis.html#lou_translateString
+ */
+ protected static byte typeformFromTextTransform(String textTransform) {
+ byte typeform = Typeform.PLAIN;
+ for (String tt : TEXT_TRANSFORM_PARSER.split(textTransform)) {
+ if (tt.equals("louis-ital"))
+ typeform |= Typeform.ITALIC;
+ else if (tt.equals("louis-bold"))
+ typeform |= Typeform.BOLD;
+ else if (tt.equals("louis-under"))
+ typeform |= Typeform.UNDERLINE;
+ else if (tt.equals("louis-comp"))
+ typeform |= Typeform.COMPUTER;
+ else
+ logger.warn("text-transform: {} not supported", tt);
+ }
return typeform;
}
diff --git a/pipeline-braille-utils/liblouis/liblouis-core/src/test/java/org/daisy/pipeline/braille/liblouis/impl/LiblouisJnaImplTest.java b/pipeline-braille-utils/liblouis/liblouis-core/src/test/java/org/daisy/pipeline/braille/liblouis/impl/LiblouisJnaImplTest.java
index c4f046c5f..04fbe29cd 100644
--- a/pipeline-braille-utils/liblouis/liblouis-core/src/test/java/org/daisy/pipeline/braille/liblouis/impl/LiblouisJnaImplTest.java
+++ b/pipeline-braille-utils/liblouis/liblouis-core/src/test/java/org/daisy/pipeline/braille/liblouis/impl/LiblouisJnaImplTest.java
@@ -13,4 +13,26 @@ public void testTypeformFromInlineCSS() {
LiblouisJnaImpl.typeformFromInlineCSS(
" text-decoration: underline ;font-weight: bold ; hyphens:auto; color: #FF00FF "));
}
+
+ @Test
+ public void testTextFromTextTransform() {
+ assertEquals("IK BEN MOOS",
+ LiblouisJnaImpl.textFromTextTransform("Ik ben Moos",
+ " uppercase "));
+ assertEquals("ik ben moos",
+ LiblouisJnaImpl.textFromTextTransform("Ik ben Moos",
+ " lowercase "));
+ assertEquals("ik ben moos",
+ LiblouisJnaImpl.textFromTextTransform("Ik ben Moos",
+ " uppercase lowercase "));
+ assertEquals("Ik ben Moos",
+ LiblouisJnaImpl.textFromTextTransform("Ik ben Moos",
+ " foo bar "));
+ }
+
+ @Test
+ public void testTypeformFromTextTransform() {
+ assertEquals(Typeform.BOLD + Typeform.UNDERLINE,
+ LiblouisJnaImpl.typeformFromTextTransform(" louis-bold ital louis-under foo "));
+ }
}