TrainingCorpusShapeSplitter implements ShapeSplitter { @Override public List<ShapeSequence> split(Shape shape) { List<ShapeSequence> shapeSequences = new ArrayList<ShapeSequence>(); ShapeSequence shapeSequence = new ShapeSequence(); shapeSequences.add(shapeSequence); Set<String> nonSplittableLetters = jochreSession.getLinguistics().getDualCharacterLetters(); String testLetter = shape.getLetter().replace("|", ""); if (testLetter.length() == 1 || nonSplittableLetters.contains(testLetter)) { shapeSequence.addShape(shape); } else { int lastLeft = 0; Comparator<Shape> shapeComparator = null; if (jochreSession.getLinguistics().isLeftToRight()) shapeComparator = new ShapeLeftToRightComparator(); else shapeComparator = new ShapeRightToLeftComparator(); TreeSet<Shape> splitShapes = new TreeSet<Shape>(shapeComparator); for (Split split : shape.getSplits()) { Shape newShape = shape.getJochreImage().getShape(shape.getLeft() + lastLeft, shape.getTop(), shape.getLeft() + split.getPosition(), shape.getBottom()); lastLeft = split.getPosition() + 1; splitShapes.add(newShape); } Shape lastShape = shape.getJochreImage().getShape(shape.getLeft() + lastLeft, shape.getTop(), shape.getRight(), shape.getBottom()); splitShapes.add(lastShape); List<String> splitLetters = new ArrayList<String>(); char lastChar = 0; boolean haveSplitLetter = false; for (int i = 0; i < shape.getLetter().length(); i++) { char c = shape.getLetter().charAt(i); if (c == '|') haveSplitLetter = true; if (lastChar != 0) { String doubleChar = "" + lastChar + c; if (nonSplittableLetters.contains(doubleChar)) { splitLetters.add(doubleChar); lastChar = 0; } else { splitLetters.add("" + lastChar); lastChar = c; } } else { lastChar = c; } } if (lastChar != 0) splitLetters.add("" + lastChar); if (splitLetters.size() == 0) splitLetters.add(""); if (haveSplitLetter) { int i = 0; List<String> newSplitLetters = new ArrayList<String>(); boolean inSplit = false; for (String letter : splitLetters) { if (letter.equals("|")) { if (i == 1 && i == splitLetters.size() - 2) { Shape previousShape = null; Shape nextShape = null; String previousLetter = splitLetters.get(0); String nextLetter = splitLetters.get(2); if (shape.getIndex() > 0) { previousShape = shape.getGroup().getShapes().get(shape.getIndex() - 1); } if (shape.getIndex() < shape.getGroup().getShapes().size() - 1) { nextShape = shape.getGroup().getShapes().get(shape.getIndex() + 1); } boolean backwardsSplit = true; if (previousShape != null && previousShape.getLetter().equals("|" + previousLetter)) { backwardsSplit = true; } else if (nextShape != null && nextShape.getLetter().equals(nextLetter + "|")) { backwardsSplit = false; } else if (previousShape != null && previousShape.getLetter().length() == 0) { backwardsSplit = true; } else if (nextShape != null && nextShape.getLetter().length() == 0) { backwardsSplit = false; } else { throw new JochreException("Impossible split for shape " + shape.getId() + ": " + previousLetter + "|" + nextLetter); } if (backwardsSplit) { String letterWithSplit = newSplitLetters.get(0) + "|"; newSplitLetters.remove(0); newSplitLetters.add(letterWithSplit); } else { inSplit = true; } } else if (i == 1) { String letterWithSplit = newSplitLetters.get(0) + "|"; newSplitLetters.remove(0); newSplitLetters.add(letterWithSplit); } else if (i == splitLetters.size() - 2) { inSplit = true; } else { throw new JochreException("Impossible split location for shape " + shape.getId() + ": " + shape.getLetter()); } } else if (inSplit) { newSplitLetters.add("|" + letter); inSplit = false; } else { newSplitLetters.add(letter); } i++; } splitLetters = newSplitLetters; } if (splitLetters.size() != splitShapes.size()) { throw new JochreException("Cannot have more shapes than letters in shape " + shape.getId() + ": " + shape.getLetter() + ", " + splitLetters); } int i = 0; for (Shape splitShape : splitShapes) { shapeSequence.addShape(splitShape, shape); splitShape.setLetter(splitLetters.get(i++)); } } return shapeSequences; } TrainingCorpusShapeSplitter(JochreSession jochreSession); @Override List<ShapeSequence> split(Shape shape);  }
@Test public void testSplit(@Mocked final Shape shape, @Mocked final Shape shape1, @Mocked final Shape shape2, @Mocked final Shape shape3, @Mocked final Shape shape4, @Mocked final GroupOfShapes group, @Mocked final RowOfShapes row, @Mocked final Paragraph paragraph, @Mocked final JochreImage jochreImage, @Mocked final JochrePage jochrePage, @Mocked final JochreDocument jochreDocument, @Mocked final Iterator<Split> i, @Mocked final List<Split> splits, @Mocked final Split split1, @Mocked final Split split2, @Mocked final Split split3) throws Exception { System.setProperty("config.file", "src/test/resources/testDualCharacters.conf"); ConfigFactory.invalidateCaches(); Config config = ConfigFactory.load(); final JochreSession jochreSession = new JochreSession(config); new Expectations() { { shape.getLetter(); result = "אָבּער"; minTimes = 0; shape.getLeft(); result = 100; minTimes = 0; shape.getRight(); result = 200; minTimes = 0; shape.getTop(); result = 100; minTimes = 0; shape.getBottom(); result = 200; minTimes = 0; shape.getGroup(); result = group; minTimes = 0; shape.getJochreImage(); result = jochreImage; minTimes = 0; group.getRow(); result = row; minTimes = 0; row.getParagraph(); result = paragraph; minTimes = 0; paragraph.getImage(); result = jochreImage; minTimes = 0; jochreImage.getPage(); result = jochrePage; minTimes = 0; jochrePage.getDocument(); result = jochreDocument; minTimes = 0; jochreDocument.getLocale(); result = jochreSession.getLocale(); minTimes = 0; shape.getSplits(); result = splits; minTimes = 0; splits.iterator(); result = i; minTimes = 0; i.hasNext(); returns(true, true, true, false); i.next(); returns(split1, split2, split3); split1.getPosition(); result = 35; minTimes = 0; split2.getPosition(); result = 59; minTimes = 0; split3.getPosition(); result = 82; minTimes = 0; jochreImage.getShape(100, 100, 135, 200); result = shape1; minTimes = 0; jochreImage.getShape(136, 100, 159, 200); result = shape2; minTimes = 0; jochreImage.getShape(160, 100, 182, 200); result = shape3; minTimes = 0; jochreImage.getShape(183, 100, 200, 200); result = shape4; minTimes = 0; } }; LOG.debug(shape.toString()); LOG.debug(shape.getLetter()); TrainingCorpusShapeSplitter splitter = new TrainingCorpusShapeSplitter(jochreSession); List<ShapeSequence> result = splitter.split(shape); ShapeSequence shapeSequence = result.get(0); assertEquals(4, shapeSequence.size()); LOG.debug("Split into: " + shapeSequence.toString()); new Verifications() { { shape1.setLetter("אָ"); shape2.setLetter("בּ"); shape3.setLetter("ע"); shape4.setLetter("ר"); } }; }