Commits

petermr  committed 93cf66b Draft

completed refactor - all classes now use actionX approach

  • Participants
  • Parent commits 2fd0771

Comments (0)

Files changed (89)

File src/main/java/org/xmlcml/svgplus/action/AbstractActionX.java

 		String[] ss = (s == null) ? null : s.split(CMLConstants.S_WHITEREGEX);
 		return (ss == null) ? null : Arrays.asList(ss);
 	}
+
+	public SemanticDocumentActionX getSemanticDocumentActionX() {
+		return semanticDocumentActionX;
+	}
 }

File src/main/java/org/xmlcml/svgplus/action/ChunkAnalyzerActionX.java

 import org.xmlcml.graphics.svg.SVGUtil;
 import org.xmlcml.svgplus.analyzer.ChunkAnalyzerX;
 import org.xmlcml.svgplus.analyzer.TextAnalyzerX;
-import org.xmlcml.svgplus.text.TextAnalyzer;
 import org.xmlcml.svgplus.tools.Chunk;
 
 public class ChunkAnalyzerActionX extends PageActionX {

File src/main/java/org/xmlcml/svgplus/action/FigureAnalyzerActionX.java

+package org.xmlcml.svgplus.action;
+
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import nu.xom.Node;
+
+import org.apache.log4j.Logger;
+import org.xmlcml.cml.base.CMLUtil;
+import org.xmlcml.graphics.svg.SVGElement;
+import org.xmlcml.graphics.svg.SVGUtil;
+import org.xmlcml.svgplus.analyzer.FigureAnalyzerX;
+import org.xmlcml.svgplus.analyzer.TextAnalyzerX;
+import org.xmlcml.svgplus.core.SVGPlusConstants;
+import org.xmlcml.svgplus.figure.Figure;
+import org.xmlcml.svgplus.figure.FigureFragment;
+import org.xmlcml.svgplus.figure.FigurePanel;
+import org.xmlcml.svgplus.tools.Chunk;
+import org.xmlcml.svgplus.util.GraphUtil;
+
+public class FigureAnalyzerActionX extends PageActionX {
+
+
+	private final static Logger LOG = Logger.getLogger(FigureAnalyzerActionX.class);
+	private String filename;
+
+	public FigureAnalyzerActionX(AbstractActionX actionElement) {
+		super(actionElement);
+	}
+
+	public final static String TAG ="figureAnalyzer";
+	private static final List<String> ATTNAMES = new ArrayList<String>();
+	
+	static final String ANALYZE_FRAGMENTS = "analyzeFragments";
+	static final String CREATE_FRAGMENTS = "createFragments";
+	final static String CREATE_WORDS_LINES = "createWordsLines";
+	static final String FRAGMENT_COLOURS = "clusterColours";
+	final static String FRAGMENT_MARGINS = "clusterMargins";
+	final static String LOCATION_STRATEGY = "locationStrategy";
+	final static String PANEL_SEPARATION = "panelSeparation";
+
+	static {
+		ATTNAMES.add(ANALYZE_FRAGMENTS);
+		ATTNAMES.add(CREATE_FRAGMENTS);
+		ATTNAMES.add(CREATE_WORDS_LINES);
+		ATTNAMES.add(FILENAME);
+		ATTNAMES.add(FRAGMENT_COLOURS);
+		ATTNAMES.add(FRAGMENT_MARGINS);
+		ATTNAMES.add(LOCATION_STRATEGY);
+		ATTNAMES.add(PANEL_SEPARATION);
+	}
+
+	/** constructor
+	 */
+	public FigureAnalyzerActionX() {
+		super(TAG);
+	}
+	
+    /**
+     * copy node .
+     *
+     * @return Node
+     */
+    public Node copy() {
+        return new FigureAnalyzerActionX(this);
+    }
+
+	/**
+	 * @return tag
+	 */
+	public String getTag() {
+		return TAG;
+	}
+
+	protected List<String> getAttributeNames() {
+		return ATTNAMES;
+	}
+
+	protected List<String> getRequiredAttributeNames() {
+		return Arrays.asList(new String[]{
+				LOCATION_STRATEGY,
+		});
+	}
+
+	@Override
+	public void run() {
+		FigureAnalyzerX figureAnalyzer = getPageEditor().ensureFigureAnalyzer();
+		figureAnalyzer.setLocationStrategy(getAndExpand(FigureAnalyzerActionX.LOCATION_STRATEGY));
+		List<Figure> figureList = figureAnalyzer.createFigures();
+		List<FigurePanel> panelList = figureAnalyzer.createPanelsUsingWhitespace();
+		filename = getFilename();
+		if (isTrue(FigureAnalyzerActionX.CREATE_WORDS_LINES)) {
+			TextAnalyzerX textAnalyzer = getPageEditor().ensureTextAnalyzer();
+			for (FigurePanel figurePanel : panelList) {
+				List<SVGElement> elements = SVGUtil.getQuerySVGElements(figurePanel, ".");
+				textAnalyzer.analyzeSingleWordsOrLines(elements);
+			}
+		}
+		if (isTrue(FigureAnalyzerActionX.ANALYZE_FRAGMENTS)) {
+			figureAnalyzer.createFragmentsInsidePanelsForAllFigures();
+			analyzeFigures(figureList);
+			for (Figure figure : figureList) {
+				CMLUtil.outputQuietly(figure.getFigureAnalysis(), new File(filename+"."+figure.getId()+SVGPlusConstants.XML), 1);
+			}
+		}
+		for (Chunk figure : figureList) {
+			GraphUtil.writeFileAsSVGSVGWithMouse(filename+"."+figure.getId()+SVGPlusConstants.SVG, figure);
+		}
+	}
+
+	private void analyzeFigures(List<Figure> figureList) {
+		LOG.trace("Figures: "+figureList.size());
+		for (int i = 0; i < figureList.size(); i++) {
+			Figure figure = figureList.get(i);
+			List<FigurePanel> panelList = figure.getFigurePanelList();
+			if (panelList != null) {
+				LOG.trace("   Panels: "+panelList.size());
+				for (int j = 0; j < panelList.size(); j++) {
+					FigurePanel panel = panelList.get(j);
+					List<FigureFragment> fragmentList = panel.getFragmentList();
+					LOG.trace("      Fragments: "+fragmentList.size());
+					for (int k = 0; k < fragmentList.size(); k++) {
+						FigureFragment fragment = fragmentList.get(k);
+						fragment.analyzePrimitives();
+					}
+				}
+			}
+			figure.getFigureAnalysis();
+		}
+		
+	}
+
+}

File src/main/java/org/xmlcml/svgplus/action/PageEditorX.java

 import org.xmlcml.svgplus.core.SVGPlusConstants;
 import org.xmlcml.svgplus.figure.Figure;
 import org.xmlcml.svgplus.table.Table;
-import org.xmlcml.svgplus.tools.PageChunkSplitterAnalyzer;
 
 import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
 	}
 
 	private void applyBrowserScale() {
-		List<SVGElement> gList = SVGUtil.getQuerySVGElements(svgPage, ".//svg:g[@id='"+PageChunkSplitterAnalyzer.TOP_CHUNK+"']");
+		List<SVGElement> gList = SVGUtil.getQuerySVGElements(svgPage, ".//svg:g[@id='"+PageChunkSplitterAnalyzerX.TOP_CHUNK+"']");
 		if (gList.size() != 1) {
 			LOG.error("should have one topChunk G");
 		} else {

File src/main/java/org/xmlcml/svgplus/analyzer/FigureAnalyzerX.java

 		return panelList;
 	}
 
-	void createFragmentsInsidePanelsForAllFigures() {
+	public void createFragmentsInsidePanelsForAllFigures() {
 		for (Figure figure : figureList) {
 			figure.createFragmentsInsidePanels();
 		}

File src/main/java/org/xmlcml/svgplus/analyzer/TextAnalyzerX.java

 		this.createHTML = createHTML;
 	}
 
-	SimpleFont ensureSimpleFont() {
+	public SimpleFont ensureSimpleFont() {
 		if (this.simpleFont == null) {
 			simpleFont = pageEditorX.getSemanticDocumentAction().getSimpleFont();
 			if (this.simpleFont == null) {

File src/main/java/org/xmlcml/svgplus/command/AbstractAction.java

-package org.xmlcml.svgplus.command;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import nu.xom.Element;
-import nu.xom.Elements;
-
-import org.apache.log4j.Logger;
-import org.xmlcml.cml.base.CMLConstants;
-import org.xmlcml.graphics.svg.SVGSVG;
-import org.xmlcml.svgplus.core.SemanticDocumentAction;
-
-/** generated by an AbstractActionElement
- * contains the attribute logic because some commands have different actions
- *  
- * @author pm286
- *
- */
-public abstract class AbstractAction {
-
-	private final static Logger LOG = Logger.getLogger(AbstractAction.class);
-	
-	public final static Pattern VARIABLE_REF = Pattern.compile("\\$\\{([^\\{]*)\\}");
-	private static final String TRUE = "true";
-
-	protected AbstractActionElement actionElement;
-	protected SemanticDocumentAction semanticDocumentAction; // so all subclasses can access this
-
-	public AbstractAction(AbstractActionElement actionElement) {
-		this.setActionElement(actionElement);
-	}
-
-	/** only used for constructing objects programmatically
-	 * 
-	 */
-	protected AbstractAction() {
-	}
-
-	/** execute the command
-	 * 
-	 */
-	public abstract void run();
-
-	public void setSemanticDocumentAction(SemanticDocumentAction semanticDocumentAction) {
-		this.semanticDocumentAction = semanticDocumentAction;
-	}
-	
-	public String getFilename() {
-		String filename = getAndExpand(AbstractActionElement.FILENAME);
-		if (filename != null) {
-			try {
-				filename = new File(filename).getCanonicalPath();
-			} catch (Exception e) {
-				throw new RuntimeException("Bad filename: "+filename);
-			}
-		}
-		return filename;
-	}
-
-	public String getName() {
-		return getAndExpand(AbstractActionElement.NAME);
-	}
-
-	public String getMark() {
-		return getAndExpand(AbstractActionElement.MARK);
-	}
-
-	protected String getAndExpand(String attName) {
-		String value = getActionElement().getAttributeValue(attName);
-		return expandVariables(value);
-	}
-
-	protected String getAndExpand(String attName, String defaultValue) {
-		String value = getValue(attName, defaultValue);
-		return expandVariables(value);
-	}
-
-	protected String getValue(String attName, String defaultValue) {
-		String value = getActionElement().getAttributeValue(attName);
-		value = (value == null) ? defaultValue : value;
-		return value;
-	}
-
-	public String[] getDeleteNamespaces() {
-		String s = getAndExpand(AbstractActionElement.DELETE_NAMESPACES);
-		String[] ss = null;
-		if (s != null) {
-			ss = s.split(CMLConstants.S_WHITEREGEX);
-		}
-		return ss;
-	}
-
-	public Boolean getDebug() {
-		String  debugString = getAndExpand(AbstractActionElement.DEBUG);
-		return debugString == null ? null : TRUE.equalsIgnoreCase(debugString);
-	}
-
-	public String getFormat() {
-		return getAndExpand(AbstractActionElement.FORMAT);
-	}
-
-	public String getFormat(String defaultFormat) {
-		String format = getAndExpand(AbstractActionElement.FORMAT);
-		return format == null ? defaultFormat : format;
-	}
-
-	public String getLog() {
-		return getAndExpand(AbstractActionElement.LOGAT);
-	}
-
-	protected boolean isTrue(String attName) {
-		String val = getAndExpand(attName);
-		return new Boolean(val);
-	}
-
-	/** gets Integer from attribute
-	 * fails silently
-	 * 
-	 * @param name attributeName
-	 * @return
-	 */
-	protected Integer getInteger(String name) {
-		Integer ii = null;
-		String s = getAndExpand(name);
-		try {
-			ii = new Integer(s);
-		} catch (Exception e) {
-		}
-		return ii;
-	}
-
-	/** gets Integer from attribute
-	 * fails silently
-	 * 
-	 * @param name attributeName
-	 * @param defaultValue
-	 * @return
-	 */
-	protected Integer getInteger(String name, Integer defaultValue) {
-		Integer ii = getInteger(name);
-		return ii == null ? defaultValue : ii;
-	}
-
-	/** gets Long from attribute
-	 * fails silently
-	 * 
-	 * @param name attributeName
-	 * @return
-	 */
-	protected Long getLong(String name) {
-		Long ll = null;
-		String s = getAndExpand(name);
-		try {
-			ll = new Long(s);
-		} catch (Exception e) {
-		}
-		return ll;
-	}
-
-	/** gets Long from attribute
-	 * fails silently
-	 * 
-	 * @param name attributeName
-	 * @param defaultValue
-	 * @return
-	 */
-	protected Long getLong(String name, Long defaultValue) {
-		Long ii = getLong(name);
-		return ii == null ? defaultValue : ii;
-	}
-
-	/** gets Double from attribute
-	 * fails silently
-	 * 
-	 * @param name attributeName
-	 * @return
-	 */
-	protected Double getDouble(String name) {
-		Double dd = null;
-		String s = getAndExpand(name);
-		try {
-			dd = new Double(s);
-		} catch (Exception e) {
-		}
-		return dd;
-	}
-
-	/** gets Double from attribute
-	 * fails silently
-	 * 
-	 * @param name attributeName
-	 * @param defaultValue
-	 * @return
-	 */
-	protected Double getDouble(String name, Double defaultValue) {
-		Double dd = getDouble(name);
-		return dd == null ? defaultValue : dd;
-	}
-
-	public String getActionValue() {
-		return getAndExpand(AbstractActionElement.ACTION);
-	}
-
-	protected void debug(String string) {
-		if (AbstractActionElement.DEBUG.equals(getLog())) {
-			LOG.debug(string);
-		}
-	}
-
-	protected String expandVariables(String value) {
-		String val = null;
-		if (value != null) {
-			Matcher matcher = VARIABLE_REF.matcher(value);
-			StringBuilder sb = new StringBuilder();
-			int current = 0;
-			while (matcher.find()) {
-				int start = matcher.start();
-				sb.append(value.substring(current, start));
-				int end = matcher.end();
-				String name = matcher.group(1);
-				Object newValue = semanticDocumentAction.getVariable(name);
-				if (newValue == null) {
-					throw new RuntimeException("Cannot find variable: "+name+" in "+value);
-				}
-				if (newValue instanceof String || newValue instanceof File || newValue instanceof Number) {
-					sb.append(newValue.toString());
-				} else {
-					sb.append(newValue.getClass());
-				}
-				current = end;
-			}
-			sb.append(value.substring(current));
-			val = sb.toString();
-		}
-		return val;
-	}
-	
-	public void setActionElement(AbstractActionElement actionElement) {
-		this.actionElement = actionElement;
-	}
-
-	public String getCount() {
-		return getAndExpand(AbstractActionElement.COUNT);
-	}
-
-	public String getMessage() {
-		// don't expand this
-		return getActionElement().getAttributeValue(AbstractActionElement.MESSAGE);
-	}
-
-	public String getRegex() {
-		// don't expand this
-		return getActionElement().getAttributeValue(AbstractActionElement.REGEX);
-	}
-
-	/** gets skip attribute value or null
-	 * 
-	 * @return
-	 */
-	public String getSkip() {
-		String skip = getAndExpand(AbstractActionElement.SKIP_IF_EXISTS);
-		return skip;
-	}
-
-	/** splits the skip string by whitespace
-	 * 
-	 * @return empty list if missing
-	 */
-	public List<String> getSkipList() {
-		List<String> skipList = new ArrayList<String>();
-		String skip = getSkip();
-		if (skip != null) {
-			String[] skips = skip.split(CMLConstants.S_WHITEREGEX);
-			skipList = Arrays.asList(skips);
-		}
-		return skipList;
-	}
-
-	public Long getTimeout(long defaultTimeout) {
-		return getLong(AbstractActionElement.TIMEOUT);
-	}
-
-	public String getTitle() {
-		// don't expand this
-		return getActionElement().getAttributeValue(AbstractActionElement.TITLE);
-	}
-
-	public String getValue() {
-		return getAndExpand(PageActionElement.VALUE);
-	}
-
-	public String getXPath() {
-		return getAndExpand(AbstractActionElement.XPATH);
-	}
-
-	/**
-	 * get the commandElement that generated the action
-	 * @return
-	 */
-	public AbstractActionElement getActionElement() {
-		return this.actionElement;
-	}
-
-	protected List<AbstractAction> getChildActionList() {
-		Elements childElements = actionElement.getChildElements();
-		List<AbstractAction> childActionList = new ArrayList<AbstractAction>();
-		for (int i = 0; i < childElements.size(); i++) {
-			Element childActionElement = childElements.get(i);
-			if (!(childActionElement instanceof AbstractActionElement)) {
-				throw new RuntimeException("Element not allowed: "+childActionElement.toXML());
-			}
-			AbstractActionElement actionElement = (AbstractActionElement) childActionElement;
-			AbstractAction abstractAction = actionElement.getAction();
-			childActionList.add(abstractAction);
-		}
-		return childActionList;
-	}
-
-	protected void runChildActionList() {
-		List<AbstractAction> childActionList = getChildActionList();
-		if (childActionList.size() == 0) {
-			LOG.debug("*** No child actions given ***");
-		}
-		for (AbstractAction abstractAction : childActionList) {
-			LOG.trace("running: "+abstractAction);
-			// maybe put filter in here
-			abstractAction.run();
-		}
-	}
-
-	/** the variable is also available as protected
-	 * 
-	 * @return
-	 */
-	public SemanticDocumentAction getSemanticDocumentAction() {
-		if (semanticDocumentAction == null && this instanceof SemanticDocumentAction) {
-			semanticDocumentAction = (SemanticDocumentAction) this;
-		}
-		return semanticDocumentAction;
-	}
-
-	public SVGSVG getSVGPage() {
-		getSemanticDocumentAction();
-		PageEditor pageEditor = semanticDocumentAction.getPageEditor();
-		return pageEditor == null ? null : pageEditor.getSVGPage();
-	}
-}

File src/main/java/org/xmlcml/svgplus/command/AbstractActionElement.java

-package org.xmlcml.svgplus.command;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import nu.xom.Attribute;
-import nu.xom.Comment;
-import nu.xom.Element;
-import nu.xom.Node;
-import nu.xom.ProcessingInstruction;
-import nu.xom.Text;
-
-import org.apache.log4j.Logger;
-import org.xmlcml.cml.base.CMLUtil;
-import org.xmlcml.svgplus.core.SemanticDocumentElement;
-import org.xmlcml.svgplus.figure.FigureAnalyzerElement;
-
-public abstract class AbstractActionElement extends Element {
-
-	private static final Logger LOG = Logger.getLogger(AbstractActionElement.class);
-	
-	public static final String ACTION = "action";
-	public static final String DELETE_NAMESPACES = "deleteNamespaces";
-	public static final String FILENAME = "filename";
-	public static final String FORMAT = "format";
-	public static final String MARK = "mark";
-	public static final String DEBUG = "debug";
-	public static final String COUNT = "count";
-	public static final String LOGAT = "log";
-	public static final String MESSAGE = "message";
-	public static final String NAME = "name";
-	public static final String OUT_DIR = "outDir";
-	public static final String REGEX = "regex";
-	public static final String SKIP_IF_EXISTS = "skipIfExists";
-	public static final String TITLE = "title";
-	public static final String XPATH = "xpath";
-	public static final String MAX = "max";
-	public static final String TIMEOUT = "timeout";
-	
-	protected SemanticDocumentElement semanticDocumentElement;
-	protected AbstractAction abstractAction;
-
-	/** constructor.
-	 * 
-	 * @param name
-	 */
-	public AbstractActionElement(String name) {
-		super(name);
-		init();
-	}
-
-	public AbstractActionElement(AbstractActionElement actionElement) {
-		super(actionElement);
-	}
-	
-	protected void init() {
-		this.abstractAction = createAction();
-	}
-	
-	public AbstractAction getAction() {
-		return abstractAction;
-	}
-
-	/** check attributes */
-	protected abstract List<String> getAttributeNames();
-	protected abstract List<String> getRequiredAttributeNames();
-	
-	protected abstract AbstractAction createAction();
-
-	public void checkAttributes() {
-		List<String> allowedNames = getAttributeNames();
-		if (allowedNames == null) {
-			throw new RuntimeException("Must give some allowed attributes: "+this.getClass());
-		}
-		List<String> attNames = new ArrayList<String>();
-		for (int i = 0; i < this.getAttributeCount(); i++) {
-			String attName = this.getAttribute(i).getLocalName();
-			if (!allowedNames.contains(attName)) {
-				throw new RuntimeException("Unknown attribute : "+attName+" on "+this.getClass());
-			}
-			attNames.add(attName);
-		}
-		List<String> requiredNames = getRequiredAttributeNames();
-		if (requiredNames != null) {
-			for (String requiredName : requiredNames) {
-				if (!attNames.contains(requiredName)) {
-					throw new RuntimeException("Missing attribute : "+requiredName+" on "+this.getClass()+" // "+this.toXML());
-				}
-			}
-		}
-	}
-
-	/** copy constructor from non-subclassed elements
-	 */
-	public static AbstractActionElement createActionElement(Element element) {
-		AbstractActionElement newElement = null;
-		String tag = element.getLocalName();
-		LOG.trace("TAG "+tag);
-		if (tag == null || tag.equals("")) {
-			throw new RuntimeException("no tag");
-		} else if (tag.equals(AssertElement.TAG)) {
-			newElement = new AssertElement();
-		} else if (tag.equals(BoxDrawerElement.TAG)) {
-			newElement = new BoxDrawerElement();
-		} else if (tag.equals(BoxProcessorElement.TAG)) {
-			newElement = new BoxProcessorElement();
-		} else if (tag.equals(BreakElement.TAG)) {
-			newElement = new BreakElement();
-		} else if (tag.equals(ChunkAnalyzerElement.TAG)) {
-			newElement = new ChunkAnalyzerElement();
-		} else if (tag.equals(DebugElement.TAG)) {
-			newElement = new DebugElement();
-		} else if (tag.equals(DocumentIteratorElement.TAG)) {
-			newElement = new DocumentIteratorElement();
-		} else if (tag.equals(PageIteratorElement.TAG)) {
-			newElement = new PageIteratorElement();
-		} else if (tag.equals(DocumentWriterElement.TAG)) {
-			newElement = new DocumentWriterElement();
-		} else if (tag.equals(ElementStylerElement.TAG)) {
-			newElement = new ElementStylerElement();
-		} else if (tag.equals(FigureAnalyzerElement.TAG)) {
-			newElement = new FigureAnalyzerElement();
-		} else if (tag.equals(IncludeElement.TAG)) {
-			newElement = new IncludeElement();
-		} else if (tag.equals(NodeDeleterElement.TAG)) {
-			newElement = new NodeDeleterElement();
-		} else if (tag.equals(PageActionElement.TAG)) {
-			throw new RuntimeException("PageActionElement is abstract");
-		} else if (tag.equals(PageNormalizerElement.TAG)) {
-			newElement = new PageNormalizerElement();
-		} else if (tag.equals(VariableElement.TAG)) {
-			newElement = new VariableElement();
-		} else if (tag.equals(PageWriterElement.TAG)) {
-			newElement = new PageWriterElement();
-		} else if (tag.equals(PathNormalizerElement.TAG)) {
-			newElement = new PathNormalizerElement();
-//		} else if (tag.equals(PathElement.TAG)) {
-//			newElement = new PathElement();
-		} else if (tag.equals(SemanticDocumentElement.TAG)) {
-			newElement = new SemanticDocumentElement();
-		} else if (tag.equals(TextChunkerElement.TAG)) {
-			newElement = new TextChunkerElement();
-		} else if (tag.equals(VariableExtractorElement.TAG)) {
-			newElement = new VariableExtractorElement();
-		} else if (tag.equals(WhitespaceChunkerElement.TAG)) {
-			newElement = new WhitespaceChunkerElement();
-		} else {
-			throw new RuntimeException("unsupported element: "+tag);
-		}
-		if (newElement != null) {
-			CMLUtil.copyAttributes(element, newElement);
-	        createSubclassedChildren(element, newElement);
-	        ((AbstractActionElement)newElement).checkAttributes();
-		}
-        return newElement;
-		
-	}
-	
-	protected static void createSubclassedChildren(Element oldElement, AbstractActionElement newElement) {
-		if (oldElement != null) {
-			for (int i = 0; i < oldElement.getChildCount(); i++) {
-				Node node = oldElement.getChild(i);
-				Node newNode = null;
-				if (node instanceof Text) {
-					newNode = new Text(node.getValue());
-				} else if (node instanceof Comment) {
-					newNode = new Comment(node.getValue());
-				} else if (node instanceof ProcessingInstruction) {
-					newNode = new ProcessingInstruction((ProcessingInstruction) node);
-				} else if (node instanceof Element) {
-					newNode = createActionElement((Element) node);
-				} else {
-					throw new RuntimeException("Cannot create new node: "+node.getClass());
-				}
-				newElement.appendChild(newNode);
-			}
-		}
-	}
-
-	public String getName() {
-		return this.getAttributeValue(NAME);
-	}
-
-	public SemanticDocumentElement getSemanticDocumentElement() {
-		if (semanticDocumentElement == null) {
-			Element element = (Element) this.query("/*").get(0);
-			if (element instanceof SemanticDocumentElement) {
-				semanticDocumentElement = (SemanticDocumentElement) element;
-			}
-		}
-		return semanticDocumentElement;
-	}
-	
-	public String getString() {
-		StringBuilder sb = new StringBuilder();
-		sb.append(this.getLocalName()+"\n");
-		for (int i = 0; i < this.getAttributeCount(); i++) {
-			Attribute attribute = this.getAttribute(i);
-			sb.append(" "+attribute.getLocalName()+"='"+attribute.getValue()+"'");
-		}
-		sb.append("\n");
-		return sb.toString();
-	}
-	
-	public void debug(String msg) {
-		CMLUtil.debug(this, msg);
-	}
-
-}

File src/main/java/org/xmlcml/svgplus/command/AbstractPageAnalyzer.java

-package org.xmlcml.svgplus.command;
-
-import org.apache.log4j.Logger;
-import org.xmlcml.graphics.svg.SVGG;
-import org.xmlcml.graphics.svg.SVGSVG;
-import org.xmlcml.svgplus.core.SemanticDocumentAction;
-
-public abstract class AbstractPageAnalyzer {
-	
-	private final static Logger LOG = Logger.getLogger(AbstractPageAnalyzer.class);
-
-	protected SVGG svgg; // current svg:gelement
-	protected SemanticDocumentAction semanticDocumentAction;
-	protected PageEditor pageEditor;
-	
-	protected AbstractPageAnalyzer() {
-	}
-
-	protected AbstractPageAnalyzer(SemanticDocumentAction semanticDocumentAction) {
-		this();
-		this.semanticDocumentAction = semanticDocumentAction;
-		this.pageEditor = getPageEditor();
-	}
-	
-	public PageEditor getPageEditor() {
-		return semanticDocumentAction.getPageEditor();
-	}
-	
-	public SVGSVG getSVGPage() {
-		return getPageEditor().getSVGPage();
-	}
-
-}

File src/main/java/org/xmlcml/svgplus/command/AssertAction.java

-package org.xmlcml.svgplus.command;
-
-import java.io.FileInputStream;
-
-import nu.xom.Builder;
-import nu.xom.Element;
-import nu.xom.Nodes;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.log4j.Logger;
-import org.xmlcml.cml.base.CMLConstants;
-import org.xmlcml.cml.base.CMLUtil;
-import org.xmlcml.graphics.svg.SVGSVG;
-import org.xmlcml.svgplus.util.ToXML;
-
-public class AssertAction extends PageAction {
-
-	final static Logger LOG = Logger.getLogger(AssertAction.class);
-
-	public AssertAction(AbstractActionElement actionElement) {
-		super(actionElement);
-	}
-	
-	@Override
-	public void run() {
-		String message = getMessage() == null ? "" : getMessage();
-		String refFilename = getFilename();
-		String xpath = getXPath();
-		String name = getName();
-		String refValue = getValue();
-		if (refFilename != null) {
-			compareXML(message, refFilename, xpath, name);
-		} else if (xpath != null) {
-			testXPath(message, xpath, refValue);
-		} else if (name != null && refValue != null) {
-			testNameValue(name, refValue);
-		}
-	}
-
-
-	private void compareXML(String message, String filename, String xpath, String name) {
-		if (name != null) {
-			Object obj = semanticDocumentAction.getVariable(name);
-			if (obj == null) {
-				throw new RuntimeException("Cannot find object with name: "+name);
-			} else if (obj instanceof ToXML) {
-				assertTestAgainstXMLFile(message, filename, ((ToXML) obj).toXML());
-			} else if (obj instanceof Element) {
-				assertTestAgainstXMLFile(message, filename, (Element) obj);
-			} else if (obj instanceof String){
-				assertTestAgainstStringFile(message, filename, (String) obj);
-			} else {
-				throw new RuntimeException("Cannot compare objects of type: "+obj.getClass().getName());
-			}
-		}
-	}
-	
-	private void testXPath(String message, String xpath, String refValue) {
-		Nodes nodes = getSVGPage().query(xpath, CMLConstants.SVG_XPATH);
-		int nnode = nodes.size();
-		String expectedCountS = getCount();
-		int	expectedCount = getCountWithDefault();
-		if (expectedCount != 1) {
-			if (nnode != expectedCount) {
-				for (int i = 0; i < nnode; i++) {
-					LOG.trace(nodes.get(i).toXML());
-				}
-				fail(message+" expected "+expectedCount+" nodes from "+xpath+", found: "+nnode+" on "+getActionElement().toXML());
-			}
-		} else {
-			if (nnode != 1) {
-				fail(message+" expected 1 node from "+xpath+", found: "+nodes.size()+" on "+getActionElement().toXML());
-			}
-			if (refValue == null) {
-				if (expectedCountS == null) {
-					warn("no value or count given: "+getActionElement().toXML());
-				}
-			} else {
-				String nodeValue = nodes.get(0).getValue();
-				if (!refValue.equals(nodeValue)) {
-					fail(message+" expected "+refValue+" from "+xpath+", got: "+nodeValue+" on "+getActionElement().toXML());
-				}
-			}
-		}
-	}
-	
-	private void testNameValue(String name, String refValue) {
-		LOG.trace(semanticDocumentAction.getDebugString());
-		Object testValue = semanticDocumentAction.getVariable(name);
-		if (testValue == null) {
-			throw new RuntimeException("Cannot find name: "+name);
-		}
-		String testString = testValue.toString();
-		if (!testString.equals(refValue)) {
-			throw new RuntimeException("Assert for: ("+name+") expected: "+refValue+"; found: "+testString);
-		}
-	}
-
-	private void compareXML(String message, String filename, String xpath) {
-		try {
-			
-			Element testElem = getSVGPage();
-			if (xpath != null) {
-				Nodes nodes = getSVGPage().query(xpath, CMLConstants.SVG_XPATH);
-				if (nodes.size() != 1) {
-					throw new RuntimeException("Cannot compare more than one node");
-				}
-				Element testElem0 = (Element) nodes.get(0);
-				testElem = new SVGSVG();
-				testElem0.detach();
-				testElem.appendChild(testElem0);
-			}
-			assertTestAgainstXMLFile(message, filename, testElem);
-		} catch (Exception e) {
-			throw new RuntimeException("Cannot carry out comparison", e);
-		}
-	}
-
-	private void assertTestAgainstXMLFile(String message, String filename, Element testElem) {
-		Element element = null;
-		try {
-			element = new Builder().build(new FileInputStream(filename)).getRootElement();
-		} catch (Exception e) {
-			throw new RuntimeException("Cannot parse / find reference: "+filename, e);
-		}
-
-//		SVGElement refElement = SVGElement.readAndCreateSVG(element);
-		String messageOut = CMLUtil.equalsCanonically(element, testElem, true);
-		if (messageOut != null) {
-			fail("FAIL "+message+": "+messageOut);
-		}
-	}
-
-	/** likely to be flaky because of whitespace
-	 * 
-	 * @param message
-	 * @param filename
-	 * @param testString
-	 */
-	private void assertTestAgainstStringFile(String message, String filename, String testString) {
-		try {
-			String s = IOUtils.toString(new FileInputStream(filename));
-			if (!s.equals(testString)) {
-				fail("FAIL "+message+": "+s+" != "+testString);
-			}
-		} catch (Exception e) {
-			throw new RuntimeException("Cannot parse / find reference: "+filename, e);
-		}
-	}
-
-	private Integer getCountWithDefault() {
-		Integer count = 1;
-		String countS = getCount();
-		LOG.trace("***"+countS);
-		if (countS != null) {
-			try {
-				count = new Integer(countS);
-			} catch (NumberFormatException nfe) {
-				throw new RuntimeException("bad count: "+countS);
-			}
-		}
-		return count;
-	}
-
-}

File src/main/java/org/xmlcml/svgplus/command/AssertElement.java

-package org.xmlcml.svgplus.command;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import nu.xom.Node;
-
-import org.apache.log4j.Logger;
-
-public class AssertElement extends AbstractActionElement {
-
-	private final static Logger LOG = Logger.getLogger(AssertElement.class);
-
-	public final static String TAG ="assert";
-	private static final List<String> ATTNAMES = new ArrayList<String>();
-	
-	static {
-		ATTNAMES.add(PageActionElement.COUNT);
-		ATTNAMES.add(PageActionElement.FAIL);
-		ATTNAMES.add(PageActionElement.FILENAME);
-		ATTNAMES.add(PageActionElement.NAME);
-		ATTNAMES.add(PageActionElement.MESSAGE);
-		ATTNAMES.add(PageActionElement.VALUE);
-		ATTNAMES.add(PageActionElement.XPATH);
-	}
-
-	/** constructor
-	 */
-	public AssertElement() {
-		super(TAG);
-	}
-	
-	/** constructor
-	 */
-	public AssertElement(AbstractActionElement element) {
-        super(element);
-	}
-	
-    /**
-     * copy node .
-     *
-     * @return Node
-     */
-    public Node copy() {
-        return new AssertElement(this);
-    }
-
-	/**
-	 * @return tag
-	 */
-	public String getTag() {
-		return TAG;
-	}
-
-	protected List<String> getAttributeNames() {
-		return ATTNAMES;
-	}
-
-	protected List<String> getRequiredAttributeNames() {
-			return Arrays.asList(new String[]{
-			});
-	}
-
-	@Override
-	protected AbstractAction createAction() {
-		return new AssertAction(this);
-	}
-}

File src/main/java/org/xmlcml/svgplus/command/BoxDrawerAction.java

-package org.xmlcml.svgplus.command;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.xmlcml.graphics.svg.SVGElement;
-import org.xmlcml.graphics.svg.SVGRect;
-import org.xmlcml.graphics.svg.SVGUtil;
-
-/**
-	<pageAction xpath="//svg:g[@LEAF='3']/svg:g" action="drawBoxes" 
-	stroke="blue" strokeWidth="3" fill="cyan" opacity="0.3" />
- * @author pm286
- *
- */
-public class BoxDrawerAction extends PageAction {
-
-	private final static Logger LOG = Logger.getLogger(BoxDrawerAction.class);
-	
-	public static final String ANNOTATION_BOX = "annotationBox";
-
-	private String title;
-	
-	public BoxDrawerAction(AbstractActionElement actionElement) {
-		super(actionElement);
-	}
-	
-	@Override
-	public void run() {
-		title = getTitle();
-		drawBoxes();
-	}
-
-	private void drawBoxes() {
-    	List<SVGElement> elements = SVGUtil.getQuerySVGElements(getSVGPage(), getXPath());
-    	for (SVGElement element : elements) {
-    		SVGRect box = element.drawBox(this.getStroke(), this.getFill(), this.getStrokeWidth(), this.getOpacity());
-    		if (box != null) {
-        		if (title != null) {
-        			box.setTitle(title);
-        		}
-//        		PageNormalizerAction.removeCSSStyleAndExpandAsSeparateAttributes(box);
-    		}
-    	}
-	}
-
-}

File src/main/java/org/xmlcml/svgplus/command/BoxDrawerElement.java

-package org.xmlcml.svgplus.command;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import nu.xom.Node;
-
-import org.apache.log4j.Logger;
-
-
-public class BoxDrawerElement extends AbstractActionElement {
-
-	private final static Logger LOG = Logger.getLogger(BoxDrawerElement.class);
-	
-	public final static String TAG ="boxDrawer";
-	private static final List<String> ATTNAMES = new ArrayList<String>();
-	
-	/** attribute names
-	 * 
-	 */
-
-	static {
-//		ATTNAMES.add(PageActionElement.ACTION);
-		ATTNAMES.add(PageActionElement.FILL);
-		ATTNAMES.add(PageActionElement.OPACITY);
-		ATTNAMES.add(PageActionElement.STROKE_WIDTH);
-		ATTNAMES.add(PageActionElement.STROKE);
-		ATTNAMES.add(PageActionElement.TITLE);
-		ATTNAMES.add(PageActionElement.XPATH);
-	}
-
-	/** constructor
-	 */
-	public BoxDrawerElement() {
-		super(TAG);
-	}
-	
-	/** constructor
-	 */
-	public BoxDrawerElement(AbstractActionElement element) {
-        super(element);
-	}
-	
-    /**
-     * copy node .
-     *
-     * @return Node
-     */
-    public Node copy() {
-        return new BoxDrawerElement(this);
-    }
-
-	/**
-	 * @return tag
-	 */
-	public String getTag() {
-		return TAG;
-	}
-
-	protected List<String> getAttributeNames() {
-		return ATTNAMES;
-	}
-
-	protected List<String> getRequiredAttributeNames() {
-		return Arrays.asList(new String[]{
-				AbstractActionElement.XPATH,
-		});
-	}
-
-	@Override
-	protected AbstractAction createAction() {
-		return new BoxDrawerAction(this);
-	}
-
-}

File src/main/java/org/xmlcml/svgplus/command/BoxProcessorAction.java

-package org.xmlcml.svgplus.command;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.xmlcml.graphics.svg.SVGElement;
-import org.xmlcml.graphics.svg.SVGUtil;
-import org.xmlcml.svgplus.paths.PathAnalyzer;
-import org.xmlcml.svgplus.tools.Chunk;
-
-public class BoxProcessorAction extends PageAction {
-
-	private final static Logger LOG = Logger.getLogger(BoxProcessorAction.class);
-	
-	private PathAnalyzer pathAnalyzer;
-	
-	public BoxProcessorAction(AbstractActionElement actionElement) {
-		super(actionElement);
-	}
-	
-	@Override
-	public void run() {
-		pathAnalyzer = getPageEditor().ensurePathAnalyzer();
-		List<SVGElement> elementList = SVGUtil.getQuerySVGElements(getSVGPage(), getXPath());
-		processRoundedBox(elementList);
-	}
-	
-	private void processRoundedBox(List<SVGElement> elementList) {
-		for (SVGElement element : elementList) {
-			LOG.trace("roundedBox "+element.getId());
-			Chunk chunk = null;
-			if (element instanceof Chunk) {
-				chunk = (Chunk) element;
-			}
-			List<SVGElement> outerElements = 
-					pathAnalyzer.getBoxOutsideMargins(chunk, this.getMarginX(), this.getMarginY());
-			if (outerElements.size() != 0) {
-				Integer boxCount = this.getBoxCount();
-				if (false && outerElements.size() < boxCount) { // because title page has strange boxes
-//					chunk.debug("BAD BOX");
-					LOG.debug("elements at edge of box ("+outerElements.size()+") != boxCount: "+boxCount); 
-					throw new RuntimeException("box");
-				} else {
-					for (SVGElement outerElement : outerElements) {
-						outerElement.detach();
-					}
-//					chunk.setChunkStyleValue(ChunkStyle.OUTLINED_BOX);
-				}
-			}
-			LOG.trace("end processRoundedBox");
-		}
-	}
-
-}

File src/main/java/org/xmlcml/svgplus/command/BoxProcessorElement.java

-package org.xmlcml.svgplus.command;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import nu.xom.Node;
-
-import org.apache.log4j.Logger;
-
-
-public class BoxProcessorElement extends AbstractActionElement {
-
-	private final static Logger LOG = Logger.getLogger(BoxProcessorElement.class);
-	
-	public final static String TAG ="boxProcessor";
-	private static final List<String> ATTNAMES = new ArrayList<String>();
-	
-	static {
-//		ATTNAMES.add(PageActionElement.ACTION);
-		ATTNAMES.add(PageActionElement.BOX_COUNT);
-		ATTNAMES.add(PageActionElement.MARGIN_X);
-		ATTNAMES.add(PageActionElement.MARGIN_Y);
-		ATTNAMES.add(PageActionElement.TITLE);
-		ATTNAMES.add(PageActionElement.XPATH);
-	}
-
-	/** constructor
-	 */
-	public BoxProcessorElement() {
-		super(TAG);
-	}
-	
-	/** constructor
-	 */
-	public BoxProcessorElement(AbstractActionElement element) {
-        super(element);
-	}
-	
-    /**
-     * copy node .
-     *
-     * @return Node
-     */
-    public Node copy() {
-        return new BoxProcessorElement(this);
-    }
-
-	/**
-	 * @return tag
-	 */
-	public String getTag() {
-		return TAG;
-	}
-
-	protected List<String> getAttributeNames() {
-		return ATTNAMES;
-	}
-
-	protected List<String> getRequiredAttributeNames() {
-		return Arrays.asList(new String[]{
-			AbstractActionElement.XPATH,
-			PageActionElement.BOX_COUNT,
-			PageActionElement.MARGIN_X,
-			PageActionElement.MARGIN_Y,
-		});
-	}
-
-	@Override
-	protected AbstractAction createAction() {
-		return new BoxProcessorAction(this);
-	}
-
-}

File src/main/java/org/xmlcml/svgplus/command/BreakAction.java

-package org.xmlcml.svgplus.command;
-
-import org.apache.log4j.Logger;
-
-public class BreakAction extends AbstractAction {
-
-	private final static Logger LOG = Logger.getLogger(BreakAction.class);
-	
-	public BreakAction(AbstractActionElement actionElement) {
-		super(actionElement);
-	}
-	
-	@Override
-	public void run() {
-		throw new RuntimeException("BREAK");
-	}
-
-
-}

File src/main/java/org/xmlcml/svgplus/command/BreakElement.java

-package org.xmlcml.svgplus.command;
-
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import nu.xom.Node;
-
-
-public class BreakElement extends AbstractActionElement {
-
-	private final static Logger LOG = Logger.getLogger(BreakElement.class);
-	
-	public final static String TAG ="break";
-	
-	private static final List<String> ATTNAMES = new ArrayList<String>();
-	
-	static {
-//		ATTNAMES.add(PageActionElement.ACTION);
-	}
-
-	/** constructor
-	 */
-	public BreakElement() {
-		super(TAG);
-	}
-	
-	/** constructor
-	 */
-	public BreakElement(AbstractActionElement element) {
-        super(element);
-	}
-	
-    /**
-     * copy node .
-     *
-     * @return Node
-     */
-    public Node copy() {
-        return new BreakElement(this);
-    }
-
-	/**
-	 * @return tag
-	 */
-	public String getTag() {
-		return TAG;
-	}
-
-	protected List<String> getAttributeNames() {
-		return ATTNAMES;
-	}
-
-	protected List<String> getRequiredAttributeNames() {
-		return Arrays.asList(new String[]{
-		});
-	}
-	
-	@Override
-	protected AbstractAction createAction() {
-		return new BreakAction(this);
-	}
-
-}

File src/main/java/org/xmlcml/svgplus/command/ChunkAnalyzer.java

-package org.xmlcml.svgplus.command;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.xmlcml.graphics.svg.SVGCircle;
-import org.xmlcml.graphics.svg.SVGLine;
-import org.xmlcml.graphics.svg.SVGPath;
-import org.xmlcml.graphics.svg.SVGPolyline;
-import org.xmlcml.graphics.svg.SVGRect;
-import org.xmlcml.graphics.svg.SVGText;
-import org.xmlcml.graphics.svg.SVGUtil;
-import org.xmlcml.svgplus.action.SemanticDocumentActionX;
-import org.xmlcml.svgplus.core.SemanticDocumentAction;
-import org.xmlcml.svgplus.paths.LineAnalyzer;
-import org.xmlcml.svgplus.paths.PolylineAnalyzer;
-import org.xmlcml.svgplus.text.TextAnalyzer;
-import org.xmlcml.svgplus.tools.Chunk;
-import org.xmlcml.svgplus.tools.PlotBox;
-
-public class ChunkAnalyzer extends AbstractPageAnalyzer {
-
-	private static final Logger LOG = Logger.getLogger(ChunkAnalyzer.class);
-
-	private static final int MIN_LINE_COUNT = 10;
-	public static final int PLACES = 6;
-
-	private List<SVGText> texts;
-	private List<SVGPath> pathList;
-	private TextAnalyzer textAnalyzer;
-	private List<SVGLine> lines;
-	private LineAnalyzer lineAnalyzer;
-	private List<SVGPolyline> polylines;
-	private PolylineAnalyzer polylineAnalyzer;
-	private Chunk chunk;
-	private PlotBox plotBox;
-
-	@Deprecated
-	public ChunkAnalyzer(SemanticDocumentAction semanticDocumentAction) {
-		super(semanticDocumentAction);
-	}
-
-	public ChunkAnalyzer(SemanticDocumentActionX semanticDocumentActionX) {
-//		super(semanticDocumentActionX);
-		// FIXME 
-		throw new RuntimeException("change ChunkAnalyzer to use new classes");
-	}
-
-	public void analyzeChunk(Chunk chunk) {
-		this.chunk = chunk;
-		ensurePaths();
-//		debugLeaf();
-		analyzeTexts();
-		analyzePaths();
-		analyzeLines();
-		analyzePolylines();
-	}
-
-	private void ensurePaths() {
-		if (pathList == null) {
-			pathList = SVGPath.extractPaths(SVGUtil.getQuerySVGElements(chunk, ".//svg:path"));
-		}
-	}
-
-	public List<SVGText> getTextCharacters() {
-		throw new RuntimeException("NYI");
-	}
-	
-	public List<SVGPath> getPaths() {
-		throw new RuntimeException("NYI");
-	}
-	
-	public List<SVGLine> getLines() {
-		throw new RuntimeException("NYI");
-	}
-	
-	public List<SVGRect> getRects() {
-		throw new RuntimeException("NYI");
-	}
-	
-	public List<SVGCircle> getCircles() {
-		throw new RuntimeException("NYI");
-	}
-	
-	public List<SVGPolyline> getPolylines() {
-		throw new RuntimeException("NYI");
-	}
-	
-	private void analyzeTexts() {
-		analyzeTexts(0);
-		analyzeTexts(90);
-		analyzeTexts(180);
-	}
-
-	private void analyzeTexts(int angle) {
-		ensureTextAnalyzer();
-		String angleCondition = (angle == 0) ? "@angle='0' or not(@angle)" : "@angle='"+angle+"'";
-		texts = SVGText.extractTexts(SVGUtil.getQuerySVGElements(svgg, ".//svg:text["+angleCondition+"]"));
-		LOG.trace("ROT "+angle+": "+texts.size());
-		if (texts.size() > 0) {
-//			textAnalyzer = new TextAnalyzer(pageEditor);
-			textAnalyzer.analyzeTexts(svgg, texts);
-		}
-	}
-	
-	private TextAnalyzer ensureTextAnalyzer() {
-		if (textAnalyzer == null) {
-			textAnalyzer = new TextAnalyzer(semanticDocumentAction);
-		}
-		return textAnalyzer;
-	}
-
-	private void analyzePaths() {
-		throw new RuntimeException("NYI");
-	}
-
-	private void analyzeLines() {
-		lines = SVGLine.extractLines(SVGUtil.getQuerySVGElements(svgg, ".//svg:line"));
-		if (lines.size() > 0) {
-			lineAnalyzer = new LineAnalyzer(semanticDocumentAction);
-			lineAnalyzer.analyzeLinesAsAxesAndWhatever(svgg, lines);
-		}
-	}
-
-	public TextAnalyzer getTextAnalyzer() {
-		ensureTextAnalyzer();
-		return textAnalyzer;
-	}
-
-	private void analyzePolylines() {
-		polylines = SVGPolyline.extractPolylines(SVGUtil.getQuerySVGElements(svgg, ".//svg:polyline"));
-		if (polylines.size() > 0) {
-			polylineAnalyzer = new PolylineAnalyzer(semanticDocumentAction);
-			polylineAnalyzer.analyzePolylines(svgg, polylines);
-		}
-	}
-
-//	private void debugLeaf() {
-//		List<SVGElement> gList = SVGUtil.getQuerySVGElements(svgg, "./svg:g");
-//		LOG.trace("G children: "+gList.size());
-//		for (SVGElement g : gList) {
-//			debugG();
-//		}
-//	}
-
-//	private void debugG() {
-//		List<SVGElement> texts = SVGUtil.getQuerySVGElements(svgg, "./svg:text");
-//		List<SVGElement> lines = SVGUtil.getQuerySVGElements(svgg, "./svg:line");
-//		if (lines.size() > 0) {
-//			LineAnalyzer lineAnalyzer = new LineAnalyzer();
-//			lineAnalyzer.addLines(SVGLine.extractLines(lines));
-//			LOG.debug(lineAnalyzer.debug());
-//		}
-//		List<SVGElement> polylines = SVGUtil.getQuerySVGElements(svgg, "./svg:polyline");
-//		LOG.debug("G "+texts.size()+" texts;    "+lines.size()+" lines;    "+polylines.size()+" polylines; ");
-//	}
-
-	public PlotBox getPlotBox() {
-		if (plotBox == null) {
-			if (lineAnalyzer != null) {
-				plotBox = lineAnalyzer.getPlotBox();
-			}
-		}
-		return plotBox;
-	}
-
-}

File src/main/java/org/xmlcml/svgplus/command/ChunkAnalyzerAction.java

-package org.xmlcml.svgplus.command;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.xmlcml.graphics.svg.SVGElement;
-import org.xmlcml.graphics.svg.SVGG;
-import org.xmlcml.graphics.svg.SVGUtil;
-import org.xmlcml.svgplus.text.TextAnalyzer;
-import org.xmlcml.svgplus.tools.Chunk;
-
-public class ChunkAnalyzerAction extends PageAction {
-
-	private final static Logger LOG = Logger.getLogger(ChunkAnalyzerAction.class);
-	
-	private boolean subSup;
-	private boolean removeNumericTSpans;
-	private boolean splitAtSpaces;
-	
-	public ChunkAnalyzerAction(AbstractActionElement actionElement) {
-		super(actionElement);
-	}
-	
-	@Override
-	public void run() {
-		String xpath = getXPath();
-		if (xpath != null) {
-			List<SVGElement> elements = SVGUtil.getQuerySVGElements(getSVGPage(), xpath);
-			LOG.debug("LEAFS "+elements.size());
-			this.subSup = isTrue(ChunkAnalyzerElement.SUBSUP);
-			this.splitAtSpaces = isTrue(ChunkAnalyzerElement.SPLIT_AT_SPACES);
-			this.removeNumericTSpans = isTrue(ChunkAnalyzerElement.REMOVE_NUMERIC_TSPANS);
-
-			for (SVGElement element : elements) {
-				if (!(element instanceof SVGG)) {
-					throw new RuntimeException("Must operate on <g> elements");
-				}
-				LOG.trace("*********************ELEMENT "+element.getId());
-				analyzeChunk(new Chunk((SVGG)element));
-			}
-			debugFile("target/chunkAnalyzer1Axes.svg");
-		}
-	}
-	
-	private void analyzeChunk(Chunk chunk) {
-		ChunkAnalyzer chunkAnalyzer = new ChunkAnalyzer(semanticDocumentAction);
-		createTextAnalyzer(chunkAnalyzer);
-		chunkAnalyzer.analyzeChunk(chunk);
-	}
-
-	private void createTextAnalyzer(ChunkAnalyzer chunkAnalyzer) {
-		TextAnalyzer textAnalyzer = chunkAnalyzer.getTextAnalyzer();
-		textAnalyzer.setSubSup(subSup);
-		textAnalyzer.setRemoveNumericTSpans(removeNumericTSpans);
-		textAnalyzer.setSplitAtSpaces(splitAtSpaces);
-	}
-	
-}

File src/main/java/org/xmlcml/svgplus/command/ChunkAnalyzerElement.java

-package org.xmlcml.svgplus.command;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import nu.xom.Node;
-
-import org.apache.log4j.Logger;
-
-
-public class ChunkAnalyzerElement extends AbstractActionElement {
-
-	private final static Logger LOG = Logger.getLogger(ChunkAnalyzerElement.class);
-	
-	public final static String TAG ="chunkAnalyzer";
-	
-	private static final List<String> ATTNAMES = new ArrayList<String>();
-	public static final String SUBSUP = "subSup";
-	public static final String REMOVE_NUMERIC_TSPANS = "removeNumericTSpans";
-	public static final String SPLIT_AT_SPACES = "splitAtSpaces";
-	
-	/** attribute names
-	 * 
-	 */
-
-	static {
-		ATTNAMES.add(PageActionElement.XPATH);
-		ATTNAMES.add(SUBSUP);
-		ATTNAMES.add(REMOVE_NUMERIC_TSPANS);
-	}
-
-	/** constructor
-	 */
-	public ChunkAnalyzerElement() {
-		super(TAG);
-	}
-	
-	/** constructor
-	 */
-	public ChunkAnalyzerElement(AbstractActionElement element) {
-        super(element);
-	}
-	
-    /**
-     * copy node .
-     *
-     * @return Node
-     */
-    public Node copy() {
-        return new ChunkAnalyzerElement(this);
-    }
-
-	/**
-	 * @return tag
-	 */
-	public String getTag() {
-		return TAG;
-	}
-
-	protected List<String> getAttributeNames() {
-		return ATTNAMES;
-	}
-
-	protected List<String> getRequiredAttributeNames() {
-		return Arrays.asList(new String[]{
-				AbstractActionElement.XPATH,
-		});
-	}
-
-	@Override
-	protected AbstractAction createAction() {
-		return new ChunkAnalyzerAction(this);
-	}
-
-}

File src/main/java/org/xmlcml/svgplus/command/DebugAction.java

-package org.xmlcml.svgplus.command;
-
-
-import org.apache.log4j.Logger;
-
-public class DebugAction extends DocumentAction {
-
-	private final static Logger LOG = Logger.getLogger(DebugAction.class);
-	
-	public DebugAction(AbstractActionElement actionElement) {
-		super(actionElement);
-	}
-	
-	@Override
-	public void run() {
-		LOG.debug(semanticDocumentAction.getDebugString());
-	}
-
-}