1 package org.daisy.pipeline.asciimathml.calabash.impl; 2 3 import java.io.StringReader; 4 import java.io.StringWriter; 5 import java.util.Map; 6 7 import javax.xml.transform.dom.DOMSource; 8 import javax.xml.transform.OutputKeys; 9 import javax.xml.transform.stream.StreamResult; 10 import javax.xml.transform.stream.StreamSource; 11 import javax.xml.transform.Transformer; 12 import javax.xml.transform.TransformerFactory; 13 14 import com.xmlcalabash.core.XProcRuntime; 15 import com.xmlcalabash.io.WritablePipe; 16 import com.xmlcalabash.library.DefaultStep; 17 import com.xmlcalabash.runtime.XAtomicStep; 18 19 import net.sf.saxon.s9api.QName; 20 import net.sf.saxon.s9api.SaxonApiException; 21 22 import org.daisy.common.xproc.calabash.XProcStep; 23 import org.daisy.common.xproc.calabash.XProcStepProvider; 24 import org.daisy.common.xproc.XProcMonitor; 25 import org.daisy.pipeline.asciimathml.ASCIIMathML; 26 27 import org.osgi.service.component.annotations.Component; 28 29 import org.slf4j.Logger; 30 import org.slf4j.LoggerFactory; 31 32 import org.w3c.dom.Element; 33 34 @Component( 35 name = "px:asciimathml", 36 service = { XProcStepProvider.class }, 37 property = { "type:String={http://www.daisy.org/ns/pipeline/xproc}asciimathml" } 38 ) 39 public class ASCIIMathMLProvider implements XProcStepProvider { 40 41 @Override 42 public XProcStep newStep(XProcRuntime runtime, XAtomicStep step, XProcMonitor monitor, Map<String,String> properties) { 43 return new ASCIIMathMLStep(runtime, step); 44 } 45 46 private static class ASCIIMathMLStep extends DefaultStep implements XProcStep { 47 48 private static final Logger logger = LoggerFactory.getLogger(ASCIIMathMLStep.class); 49 50 private static final QName _asciimath = new QName("asciimath"); 51 52 private WritablePipe result; 53 54 private ASCIIMathMLStep(XProcRuntime runtime, XAtomicStep step) { 55 super(runtime, step); 56 } 57 58 @Override 59 public void setOutput(String port, WritablePipe pipe) { 60 result = pipe; 61 } 62 63 @Override 64 public void reset() { 65 result.resetWriter(); 66 } 67 68 @Override 69 public void run() throws SaxonApiException { 70 super.run(); 71 try { 72 String ascii = getOption(_asciimath).getString().replaceAll("^`", "").replaceAll("`$", ""); 73 logger.info("Translating `" + ascii + "` to MathML ..."); 74 result.write(runtime.getProcessor().newDocumentBuilder().build( 75 new StreamSource(new StringReader(Serializer.serialize(ASCIIMathML.convert(ascii)))))); } 76 catch (Throwable e) { 77 throw XProcStep.raiseError(e, step); } 78 } 79 } 80 81 private static class Serializer { 82 private static Transformer transformer; 83 private static String serialize(Element element) { 84 try { 85 if (transformer == null) { 86 transformer = TransformerFactory.newInstance().newTransformer(); 87 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); } 88 StringWriter writer = new StringWriter(); 89 transformer.transform(new DOMSource(element), new StreamResult(writer)); 90 return writer.toString(); } 91 catch (Exception e) { 92 throw new RuntimeException(e); } 93 } 94 } 95 }