1   package org.daisy.pipeline.tts;
2   
3   import java.net.URI;
4   import java.net.URISyntaxException;
5   import java.util.ArrayList;
6   import java.util.Collection;
7   
8   import org.daisy.pipeline.tts.SSMLMarkSplitter.Chunk;
9   
10  import com.xmlcalabash.util.TreeWriter;
11  
12  import net.sf.saxon.s9api.Axis;
13  import net.sf.saxon.s9api.Processor;
14  import net.sf.saxon.s9api.QName;
15  import net.sf.saxon.s9api.XdmNode;
16  import net.sf.saxon.s9api.XdmNodeKind;
17  import net.sf.saxon.s9api.XdmSequenceIterator;
18  
19  /**
20   * This splitter assumes that the input SSML is built in such a way that it is
21   * easy to be split, i.e. the marks will always be located right under the
22   * sentence to split.
23   */
24  public class StructuredSSMLSplitter implements SSMLMarkSplitter {
25  
26  	private Processor mProc;
27  	private static final QName sNode = new QName("http://www.w3.org/2001/10/synthesis", "s");
28  
29  	public StructuredSSMLSplitter(Processor proc) {
30  		mProc = proc;
31  	}
32  	
33  	@Override
34  	public Collection<Chunk> split(XdmNode sentence) {
35  		ArrayList<Chunk> chunks = new ArrayList<Chunk>();
36  
37  		URI docURI = null;
38  		try {
39  			docURI = new URI("http://tmp");
40  		} catch (URISyntaxException e) {
41  		}
42  		
43  		String leftMarkName = null;
44  		String rightMarkName = null;
45  		XdmSequenceIterator iter = sentence.axisIterator(Axis.CHILD);
46  		boolean mark = false;
47  		while (iter.hasNext()){
48  			TreeWriter tw = new TreeWriter(mProc);
49  			tw.startDocument(docURI);
50  			tw.startContent();
51  			tw.addStartElement(sNode);
52  			mark = false;
53  			while (iter.hasNext()) {
54  				XdmNode elt = (XdmNode) iter.next();
55  				if (elt.getNodeKind() == XdmNodeKind.ELEMENT && "mark".equals(elt.getNodeName().getLocalName())){
56  					leftMarkName = rightMarkName;
57  					rightMarkName = elt.getAttributeValue(new QName("name"));
58  					mark = true;
59  					break;
60  				}
61  				else
62  					tw.addSubtree(elt);
63  			}
64  			if (!iter.hasNext() && !mark){
65  				leftMarkName = rightMarkName;
66  			}
67  			tw.addEndElement();
68  			tw.endDocument();
69  			chunks.add(new Chunk(tw.getResult(), leftMarkName));
70  		}
71  		if (mark){
72  			//last node is a mark
73  			TreeWriter tw = new TreeWriter(mProc);
74  			tw.startDocument(docURI);
75  			tw.startContent();
76  			tw.addStartElement(sNode);
77  			tw.addEndElement();
78  			tw.endDocument();
79  			chunks.add(new Chunk(tw.getResult(), rightMarkName));
80  		}
81  		
82  		
83  		return chunks;
84  	}
85  }