string
into a capital letter
*
* @param string
* @return
*/
public static String firstToUpper(String string){
return string.substring(0,1).toUpperCase()+string.substring(1);
}
public static String insertSpaceAtCaps(String string){
int uppers = 0;
//first we count
for(int i=0; i < string.length(); i++){
if(Character.isUpperCase(string.charAt(i))) uppers++;
}
int[] indexes = null;
if(Character.isUpperCase(string.charAt(0))){
indexes = new int[uppers];
} else {
indexes = new int[++uppers];
}
indexes[0] = 0;
int k = 1;
//then we find the indexes (we have ckecked the first char already)
for(int j =1; j < string.length(); j++){
if(Character.isUpperCase(string.charAt(j))) indexes[k++] = j;
}
StringBuffer buffer = new StringBuffer("");
//and finally we breakup the String
for(int i =0; i < indexes.length; i++){
if(i+1 < indexes.length){
buffer.append(string.substring(indexes[i], indexes[i+1]));
buffer.append(" ");
} else {
buffer.append(string.substring(indexes[i]));
}
}
return buffer.toString();
}
public static boolean isOneOf(char c, char[] group){
for(int i = 0; i < group.length; i++)
if(c == group[i]) return true;
return false;
}
public static boolean isOneOf(String str, String[] group){
for(int i = 0; i < group.length; i++)
if(str.equals(group[i])) return true;
return false;
}
public static String getPath(String fullPath){
if(fullPath.lastIndexOf("\\") != -1)
return fullPath.substring(0, fullPath.lastIndexOf("\\"));
else return "";
}
public static String getBaseFilename(String fullPath){
if(fullPath.lastIndexOf(".") != -1 && fullPath.lastIndexOf("\\") != -1)
return fullPath.substring(fullPath.lastIndexOf("\\") + 1, fullPath.lastIndexOf("."));
else return fullPath;
}
public static String getExtension(String fullPath){
if(fullPath.lastIndexOf(".") != -1)
return fullPath.substring(fullPath.lastIndexOf(".") + 1);
else return "";
}
public static void main(String[] args){
System.out.println("1 "+StringUtils.firstToUpper("testing"));
System.out.println("2 "+StringUtils.firstToUpper(" testing"));
System.out.println("3 "+StringUtils.firstToUpper("_testing"));
System.out.println("4 "+StringUtils.firstToUpper("Testing"));
System.out.println("5 "+StringUtils.firstToUpper("ttesting"));
String path = "C:\\Files\\test.txt";
System.out.println(path);
System.out.println(StringUtils.getPath(path));
System.out.println(StringUtils.getBaseFilename(path));
System.out.println(StringUtils.getExtension(path));
path = "test.txt";
System.out.println(path);
System.out.println(StringUtils.getPath(path));
System.out.println(StringUtils.getBaseFilename(path));
System.out.println(StringUtils.getExtension(path));
path = "test";
System.out.println(path);
System.out.println("path: "+StringUtils.getPath(path));
System.out.println("base: "+StringUtils.getBaseFilename(path));
System.out.println(" ext: "+StringUtils.getExtension(path));
}
}
ditaa-0.9/src/org/stathissideris/ascii2image/text/GridPattern.java 0000644 0001750 0001750 00000022243 11277501420 023441 0 ustar neo neo /*
* DiTAA - Diagrams Through Ascii Art
*
* Copyright (C) 2004 Efstathios Sideris
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package org.stathissideris.ascii2image.text;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.regex.Pattern;
/**
* This is a TextGrid (usually 3x3) that contains the equivalent of a
* 2D reqular expression (which uses custom syntax to make things more
* visual, but standard syntax is also possible).
*
* The custom syntax is:
* . means anything
* b means any boundary (any of - = / \ + | :)
* ! means not boundary (none of - = / \ + | :)
* - means - or =
* | means | or :
* [ means not | nor :
* ~ means not - nor =
* ^ means a boundary but not - nor =
* ( means a boundary but not | nor :
* s means a straight boundary (one of - = + | :)
* S means not a straight boundary (none of - = + | :)
*
* 1 means a cell that has entry point 1
* 2 means a cell that has entry point 2
* 3 means a cell that has entry point 3 etc. up to number 8
*
* %1 means a cell that does not have entry point 1 etc.
*
* See below for an explanation of entry points
*
* +, \, / and the space are literal (as is any other character)
*
*
* Entry points
*
* * 1 2 3 * *--*--* * | | * 8* *4 * | | * *--*--* * 7 6 5 ** * We number the entry points for each cell as in the diagram * above. If a cell is occupied by a character, we define as * entry points the points of the above diagram that the character * can touch with the end of its lines. For example - has * entry points 8 and 4, | and : have entry points 2 and 6, * / has 3 and 7, \ has 1 and 5, + has 2, 6, 8 and 4 etc. * * * @author Efstathios Sideris */ public class GridPattern extends TextGrid { private ArrayList
cell
.
*
* @param cell
* @return
*/
public TextGrid.Cell findCellNextTo(TextGrid.Cell cell){
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cCell = (TextGrid.Cell) it.next();
if(cCell.isNextTo(cell)) return cCell;
}
return null;
}
/**
* Returns all the cells that are found to be next to cell
.
*
* @param cell
* @return
*/
public CellSet findCellsNextTo(TextGrid.Cell cell){
if(cell == null) throw new IllegalArgumentException("cell cannot be null");
CellSet set = new CellSet();
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cCell = (TextGrid.Cell) it.next();
if(cCell.isNextTo(cell)) set.add(cCell);
}
return set;
}
public void appendSet(CellSet set){
typeIsValid = false;
Iterator it = set.iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(find(cell) == null) add(cell);
}
}
public void subtractSet(CellSet set){
typeIsValid = false;
Iterator it = set.iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
TextGrid.Cell thisCell = find(cell);
if(thisCell != null) remove(thisCell);
}
}
public int getWidth(){
return getMaxX() - getMinX();
}
public int getHeight(){
return getMaxY() - getMinY();
}
public int getMaxX(){
int result = 0;
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(cell.x > result) result = cell.x;
}
return result;
}
public int getMinX(){
int result = Integer.MAX_VALUE;
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(cell.x < result) result = cell.x;
}
return result;
}
public int getMaxY(){
int result = 0;
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(cell.y > result) result = cell.y;
}
return result;
}
public int getMinY(){
int result = Integer.MAX_VALUE;
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(cell.y < result) result = cell.y;
}
return result;
}
public Object remove(TextGrid.Cell cell){
typeIsValid = false;
cell = find(cell);
if(cell != null) return internalSet.remove(cell);
else return null;
}
public boolean equals(Object o){
CellSet otherSet = (CellSet) o;
return internalSet.equals(otherSet.internalSet);
}
public static ArrayList removeDuplicateSets(ArrayList list) {
ArrayList uniqueSets = new ArrayList();
Iterator it = list.iterator();
while(it.hasNext()){
CellSet set = (CellSet) it.next();
boolean isOriginal = true;
Iterator uniquesIt = uniqueSets.iterator();
while(uniquesIt.hasNext()){
CellSet uniqueSet = (CellSet) uniquesIt.next();
if(set.equals(uniqueSet)){
isOriginal = false;
}
}
if(isOriginal) uniqueSets.add(set);
}
return uniqueSets;
}
/**
* Takes into account character info from the grid
*
* @return ArrayList of distinct BoundarySetS
*/
public ArrayList breakIntoDistinctBoundaries(TextGrid grid){
ArrayList result;
AbstractionGrid temp = new AbstractionGrid(grid, this);
result = temp.getDistinctShapes();
return result;
}
/**
*
* @return ArrayList of distinct BoundarySetS
*/
public ArrayList breakIntoDistinctBoundaries(){
ArrayList result = new ArrayList();
//CellSet tempSet = copyCellSet(this);
//tempSet.translate( - this.getMinX() + 1, - this.getMinY() + 1);
// TextGrid boundaryGrid = new TextGrid(tempSet.getMaxX()+2, tempSet.getMaxY()+2);
// boundaryGrid.fillCellsWith(tempSet, '*');
TextGrid boundaryGrid = new TextGrid(getMaxX()+2, getMaxY()+2);
boundaryGrid.fillCellsWith(this, '*');
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(boundaryGrid.isBlank(cell.x, cell.y)) continue;
CellSet boundarySet = boundaryGrid.fillContinuousArea(cell.x, cell.y, ' ');
//boundarySet.translate( this.getMinX() - 1, this.getMinY() - 1);
result.add(boundarySet);
}
return result;
}
/**
*
* Breaks that:
* * +-----+ * | | * + ---+------------------- * | | * +-----+ ** * into the following 3: * *
* +-----+ * | | * + + * | | * +-----+ * * --- * ------------------- ** * @param grid * @return a list of boundaries that are either open or closed but not mixed * and they are equivalent to the
this
*/
public ArrayList breakTrulyMixedBoundaries(TextGrid grid){
ArrayList result = new ArrayList();
CellSet visitedEnds = new CellSet();
TextGrid workGrid = TextGrid.makeSameSizeAs(grid);
grid.copyCellsTo(this, workGrid);
if (DEBUG){
System.out.println("Breaking truly mixed boundaries below:");
workGrid.printDebug();
}
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell start = (TextGrid.Cell) it.next();
if(workGrid.isLinesEnd(start) && !visitedEnds.contains(start)){
if (DEBUG)
System.out.println("Starting new subshape:");
CellSet set = new CellSet();
set.add(start);
if(DEBUG) System.out.println("Added boundary "+start);
TextGrid.Cell previous = start;
TextGrid.Cell cell = null;
CellSet nextCells = workGrid.followCell(previous);
if(nextCells.size() == 0)
throw new IllegalArgumentException("This shape is either open but multipart or has only one cell, and cannot be processed by this method");
cell = (TextGrid.Cell) nextCells.getFirst();
set.add(cell);
if(DEBUG) System.out.println("Added boundary "+cell);
boolean finished = false;
if(workGrid.isLinesEnd(cell)){
visitedEnds.add(cell);
finished = true;
}
while(!finished){
nextCells = workGrid.followCell(cell, previous);
if(nextCells.size() == 1) {
set.add(cell);
if(DEBUG) System.out.println("Added boundary " + cell);
previous = cell;
cell = (TextGrid.Cell) nextCells.getFirst();
//if(!cell.equals(start) && grid.isPointCell(cell))
// s.addToPoints(makePointForCell(cell, workGrid, cellWidth, cellHeight, allRound));
if(workGrid.isLinesEnd(cell)){
visitedEnds.add(cell);
finished = true;
}
} else if(nextCells.size() > 1) {
finished = true;
}
}
result.add(set);
}
}
//substract all boundary sets from this CellSet
CellSet whatsLeft = new CellSet(this);
it = result.iterator();
while (it.hasNext()) {
CellSet set = (CellSet) it.next();
whatsLeft.subtractSet(set);
if(DEBUG) set.printAsGrid();
}
result.add(whatsLeft);
if(DEBUG) whatsLeft.printAsGrid();
return result;
}
public TextGrid makeIntoGrid(){
TextGrid grid = new TextGrid(getMaxX()+2, getMaxY()+2);
grid.fillCellsWith(this, '*');
return grid;
}
public CellSet makeScaledOneThirdEquivalent(){
TextGrid gridBig = this.makeIntoGrid();
gridBig.fillCellsWith(this, '*');
if (VERBOSE_DEBUG){
System.out.println("---> making ScaledOneThirdEquivalent of:");
gridBig.printDebug();
}
TextGrid gridSmall = new TextGrid((getMaxX() + 2) / 3, (getMaxY() + 2) / 3);
for(int y = 0; y < gridBig.getHeight(); y++){
for(int x = 0; x < gridBig.getWidth(); x++){
TextGrid.Cell cell = gridBig.new Cell(x, y);
if(!gridBig.isBlank(cell)) gridSmall.set(x/3, y/3, '*');
}
}
if (VERBOSE_DEBUG){
System.out.println("---> made into grid:");
gridSmall.printDebug();
}
return gridSmall.getAllNonBlank();
}
}
ditaa-0.9/src/org/stathissideris/ascii2image/text/AbstractionGrid.java 0000644 0001750 0001750 00000012653 11277077356 024321 0 ustar neo neo /*
* DiTAA - Diagrams Through Ascii Art
*
* Copyright (C) 2004 Efstathios Sideris
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package org.stathissideris.ascii2image.text;
import java.util.ArrayList;
import java.util.Iterator;
/**
*
* @author Efstathios Sideris
*/
public class AbstractionGrid {
private static final boolean DEBUG = false;
private TextGrid grid;
/**
* Makes an AbstractionGrid using internalGrid
as
* its internal buffer
*
* @param internalGrid
* @return
*/
public static AbstractionGrid makeUsingBuffer(TextGrid internalGrid){
if(internalGrid.getWidth() % 3 != 0
|| internalGrid.getHeight() % 3 != 0) throw new IllegalArgumentException("Passed TextGrid must have dimensions that are divisible by 3.");
AbstractionGrid result = new AbstractionGrid(internalGrid.getWidth() / 3, internalGrid.getHeight() / 3);
result.setInternalBuffer(internalGrid);
return result;
}
/**
* Makes an AbstractionGrid using the cellSet
* of textGrid
.
*
* @param textGrid
* @param cellSet
*/
public AbstractionGrid(TextGrid textGrid, CellSet cellSet){
this(textGrid.getWidth(), textGrid.getHeight());
/*this(cellSet.getWidth(), cellSet.getHeight());
cellSet = new CellSet(cellSet);
cellSet.translate( - cellSet.getMinX(), - cellSet.getMinY());*/
if(DEBUG){
System.out.println("Making AbstractionGrid using buffer:");
textGrid.printDebug();
System.out.println("...and the following CellSet:");
cellSet.printAsGrid();
}
Iterator it = cellSet.iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(textGrid.isBlank(cell)) continue;
if(textGrid.isCross(cell)){
set(cell.x, cell.y, AbstractCell.makeCross());
} else if(textGrid.isT(cell)){
set(cell.x, cell.y, AbstractCell.makeT());
} else if(textGrid.isK(cell)){
set(cell.x, cell.y, AbstractCell.makeK());
} else if(textGrid.isInverseT(cell)){
set(cell.x, cell.y, AbstractCell.makeInverseT());
} else if(textGrid.isInverseK(cell)){
set(cell.x, cell.y, AbstractCell.makeInverseK());
} else if(textGrid.isCorner1(cell)){
set(cell.x, cell.y, AbstractCell.makeCorner1());
} else if(textGrid.isCorner2(cell)){
set(cell.x, cell.y, AbstractCell.makeCorner2());
} else if(textGrid.isCorner3(cell)){
set(cell.x, cell.y, AbstractCell.makeCorner3());
} else if(textGrid.isCorner4(cell)){
set(cell.x, cell.y, AbstractCell.makeCorner4());
} else if(textGrid.isHorizontalLine(cell)){
set(cell.x, cell.y, AbstractCell.makeHorizontalLine());
} else if(textGrid.isVerticalLine(cell)){
set(cell.x, cell.y, AbstractCell.makeVerticalLine());
} else if(textGrid.isCrossOnLine(cell)){
set(cell.x, cell.y, AbstractCell.makeCross());
} else if(textGrid.isStarOnLine(cell)){
set(cell.x, cell.y, AbstractCell.makeStar());
}
}
if(DEBUG){
System.out.println("...the resulting AbstractionGrid is:");
grid.printDebug();
}
}
private AbstractionGrid(int width, int height){
grid = new TextGrid(width*3, height*3);
}
public TextGrid getCopyOfInternalBuffer(){
return new TextGrid(grid);
}
private void setInternalBuffer(TextGrid grid){
this.grid = grid;
}
public int getWidth(){
return grid.getWidth() / 3;
}
public int getHeight(){
return grid.getHeight() / 3;
}
public TextGrid getAsTextGrid(){
TextGrid result = new TextGrid(getWidth(), getHeight());
for(int y = 0; y < grid.getHeight(); y++){
for(int x = 0; x < grid.getWidth(); x++){
TextGrid.Cell cell = grid.new Cell(x, y);
if(!grid.isBlank(cell)) result.set(x/3, y/3, '*');
}
}
if (DEBUG){
System.out.println("Getting AbstractionGrid as textGrid.\nAbstractionGrid:");
grid.printDebug();
System.out.println("...as text grid:");
result.printDebug();
}
return result;
}
public ArrayList getDistinctShapes(){
ArrayList result = new ArrayList();
CellSet nonBlank = grid.getAllNonBlank();
ArrayList distinct = nonBlank.breakIntoDistinctBoundaries();
Iterator it = distinct.iterator();
while (it.hasNext()) {
CellSet set = (CellSet) it.next();
AbstractionGrid temp = new AbstractionGrid(this.getWidth(), this.getHeight());
temp.fillCells(set);
result.add(temp.getAsTextGrid().getAllNonBlank());
}
return result;
}
protected void fillCells(CellSet cells){
grid.fillCellsWith(cells, '*');
}
public void set(int xPos, int yPos, AbstractCell cell){
xPos *= 3;
yPos *= 3;
for(int y = 0; y < 3; y++){
for(int x = 0; x < 3; x++){
if(cell.rows[x][y] == 1){
grid.set(xPos + x, yPos + y, '*');
}
}
}
}
}
ditaa-0.9/src/org/stathissideris/ascii2image/text/TextGrid.java 0000644 0001750 0001750 00000140455 11303043320 022744 0 ustar neo neo /*
* DiTAA - Diagrams Through Ascii Art
*
* Copyright (C) 2004 Efstathios Sideris
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package org.stathissideris.ascii2image.text;
import java.awt.Color;
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.stathissideris.ascii2image.core.FileUtils;
import org.stathissideris.ascii2image.core.ProcessingOptions;
import org.stathissideris.ascii2image.graphics.CustomShapeDefinition;
/**
*
* @author Efstathios Sideris
*/
public class TextGrid {
private static final boolean DEBUG = false;
private ArrayList* * +- or -+ or + or + or /- or -/ or / (you get the point) * | | | * ** * @param cell * @return */ public boolean isStub(Cell cell){ return matchesAny(cell, GridPatternGroup.stubCriteria); } public boolean isCrossOnLine(Cell cell){ return matchesAny(cell, GridPatternGroup.crossOnLineCriteria); } public boolean isHorizontalCrossOnLine(Cell cell){ return matchesAny(cell, GridPatternGroup.horizontalCrossOnLineCriteria); } public boolean isVerticalCrossOnLine(Cell cell){ return matchesAny(cell, GridPatternGroup.verticalCrossOnLineCriteria); } public boolean isStarOnLine(Cell cell){ return matchesAny(cell, GridPatternGroup.starOnLineCriteria); } public boolean isLoneDiagonal(Cell cell){ return matchesAny(cell, GridPatternGroup.loneDiagonalCriteria); } public boolean isHorizontalStarOnLine(Cell cell){ return matchesAny(cell, GridPatternGroup.horizontalStarOnLineCriteria); } public boolean isVerticalStarOnLine(Cell cell){ return matchesAny(cell, GridPatternGroup.verticalStarOnLineCriteria); } public boolean isArrowhead(Cell cell){ return (isNorthArrowhead(cell) || isSouthArrowhead(cell) || isWestArrowhead(cell) || isEastArrowhead(cell)); } public boolean isNorthArrowhead(Cell cell){ return get(cell) == '^'; } public boolean isEastArrowhead(Cell cell){ return get(cell) == '>'; } public boolean isWestArrowhead(Cell cell){ return get(cell) == '<'; } public boolean isSouthArrowhead(Cell cell){ return (get(cell) == 'v' || get(cell) == 'V') && isVerticalLine(cell.getNorth()); } // unicode for bullets // // 2022 bullet // 25CF black circle // 25AA black circle (small) // 25A0 black square // 25A1 white square // 25CB white circle // 25BA black right-pointing pointer public boolean isBullet(int x, int y){ return isBullet(new Cell(x, y)); } public boolean isBullet(Cell cell){ char c = get(cell); if((c == 'o' || c == '*') && isBlank(cell.getEast()) && isBlank(cell.getWest()) && Character.isLetterOrDigit(get(cell.getEast().getEast())) ) return true; return false; } public void replaceBullets(){ int width = getWidth(); int height = getHeight(); for(int yi = 0; yi < height; yi++){ for(int xi = 0; xi < width; xi++){ Cell cell = new Cell(xi, yi); if(isBullet(cell)){ set(cell, ' '); set(cell.getEast(), '\u2022'); } } } } /** * true if the cell is not blank * but the previous (west) is * * @param cell * @return */ public boolean isStringsStart(Cell cell){ return (!isBlank(cell) && isBlank(cell.getWest())); } /** * true if the cell is not blank * but the next (east) is * * @param cell * @return */ public boolean isStringsEnd(Cell cell){ return (!isBlank(cell) //&& (isBlank(cell.getEast()) || get(cell.getEast()) == 0)); && isBlank(cell.getEast())); } public int otherStringsStartInTheSameColumn(Cell cell){ if(!isStringsStart(cell)) return 0; int result = 0; int height = getHeight(); for(int y = 0; y < height; y++){ Cell cCell = new Cell(cell.x, y); if(!cCell.equals(cell) && isStringsStart(cCell)){ result++; } } return result; } public int otherStringsEndInTheSameColumn(Cell cell){ if(!isStringsEnd(cell)) return 0; int result = 0; int height = getHeight(); for(int y = 0; y < height; y++){ Cell cCell = new Cell(cell.x, y); if(!cCell.equals(cell) && isStringsEnd(cCell)){ result++; } } return result; } public boolean isColumnBlank(int x){ int height = getHeight(); for(int y = 0; y < height; y++){ if(!isBlank(x, y)) return false; } return true; } public CellSet followLine(int x, int y){ return followLine(new Cell(x, y)); } public CellSet followIntersection(Cell cell){ return followIntersection(cell, null); } public CellSet followIntersection(Cell cell, Cell blocked){ if(!isIntersection(cell)) return null; CellSet result = new CellSet(); Cell cN = cell.getNorth(); Cell cS = cell.getSouth(); Cell cE = cell.getEast(); Cell cW = cell.getWest(); if(hasEntryPoint(cN, 6)) result.add(cN); if(hasEntryPoint(cS, 2)) result.add(cS); if(hasEntryPoint(cE, 8)) result.add(cE); if(hasEntryPoint(cW, 4)) result.add(cW); if(result.contains(blocked)) result.remove(blocked); return result; } /** * Returns the neighbours of a line-cell that are boundaries * (0 to 2 cells are returned) * * @param cell * @return null if the cell is not a line */ public CellSet followLine(Cell cell){ if(isHorizontalLine(cell)){ CellSet result = new CellSet(); if(isBoundary(cell.getEast())) result.add(cell.getEast()); if(isBoundary(cell.getWest())) result.add(cell.getWest()); return result; } else if (isVerticalLine(cell)){ CellSet result = new CellSet(); if(isBoundary(cell.getNorth())) result.add(cell.getNorth()); if(isBoundary(cell.getSouth())) result.add(cell.getSouth()); return result; } return null; } public CellSet followLine(Cell cell, Cell blocked){ CellSet nextCells = followLine(cell); if(nextCells.contains(blocked)) nextCells.remove(blocked); return nextCells; } public CellSet followCorner(Cell cell){ return followCorner(cell, null); } public CellSet followCorner(Cell cell, Cell blocked){ if(!isCorner(cell)) return null; if(isCorner1(cell)) return followCorner1(cell, blocked); if(isCorner2(cell)) return followCorner2(cell, blocked); if(isCorner3(cell)) return followCorner3(cell, blocked); if(isCorner4(cell)) return followCorner4(cell, blocked); return null; } public CellSet followCorner1(Cell cell){ return followCorner1(cell, null); } public CellSet followCorner1(Cell cell, Cell blocked){ if(!isCorner1(cell)) return null; CellSet result = new CellSet(); if(!cell.getSouth().equals(blocked)) result.add(cell.getSouth()); if(!cell.getEast().equals(blocked)) result.add(cell.getEast()); return result; } public CellSet followCorner2(Cell cell){ return followCorner2(cell, null); } public CellSet followCorner2(Cell cell, Cell blocked){ if(!isCorner2(cell)) return null; CellSet result = new CellSet(); if(!cell.getSouth().equals(blocked)) result.add(cell.getSouth()); if(!cell.getWest().equals(blocked)) result.add(cell.getWest()); return result; } public CellSet followCorner3(Cell cell){ return followCorner3(cell, null); } public CellSet followCorner3(Cell cell, Cell blocked){ if(!isCorner3(cell)) return null; CellSet result = new CellSet(); if(!cell.getNorth().equals(blocked)) result.add(cell.getNorth()); if(!cell.getWest().equals(blocked)) result.add(cell.getWest()); return result; } public CellSet followCorner4(Cell cell){ return followCorner4(cell, null); } public CellSet followCorner4(Cell cell, Cell blocked){ if(!isCorner4(cell)) return null; CellSet result = new CellSet(); if(!cell.getNorth().equals(blocked)) result.add(cell.getNorth()); if(!cell.getEast().equals(blocked)) result.add(cell.getEast()); return result; } public CellSet followStub(Cell cell){ return followStub(cell, null); } public CellSet followStub(Cell cell, Cell blocked){ if(!isStub(cell)) return null; CellSet result = new CellSet(); if(isBoundary(cell.getEast())) result.add(cell.getEast()); else if(isBoundary(cell.getWest())) result.add(cell.getWest()); else if(isBoundary(cell.getNorth())) result.add(cell.getNorth()); else if(isBoundary(cell.getSouth())) result.add(cell.getSouth()); if(result.contains(blocked)) result.remove(blocked); return result; } public CellSet followCell(Cell cell){ return followCell(cell, null); } public CellSet followCell(Cell cell, Cell blocked){ if(isIntersection(cell)) return followIntersection(cell, blocked); if(isCorner(cell)) return followCorner(cell, blocked); if(isLine(cell)) return followLine(cell, blocked); if(isStub(cell)) return followStub(cell, blocked); if(isCrossOnLine(cell)) return followCrossOnLine(cell, blocked); System.err.println("Umbiguous input at position "+cell+":"); TextGrid subGrid = getTestingSubGrid(cell); subGrid.printDebug(); throw new RuntimeException("Cannot follow cell "+cell+": cannot determine cell type"); } public String getCellTypeAsString(Cell cell){ if(isK(cell)) return "K"; if(isT(cell)) return "T"; if(isInverseK(cell)) return "inverse K"; if(isInverseT(cell)) return "inverse T"; if(isCorner1(cell)) return "corner 1"; if(isCorner2(cell)) return "corner 2"; if(isCorner3(cell)) return "corner 3"; if(isCorner4(cell)) return "corner 4"; if(isLine(cell)) return "line"; if(isStub(cell)) return "stub"; if(isCrossOnLine(cell)) return "crossOnLine"; return "unrecognisable type"; } public CellSet followCrossOnLine(Cell cell, Cell blocked){ CellSet result = new CellSet(); if(isHorizontalCrossOnLine(cell)){ result.add(cell.getEast()); result.add(cell.getWest()); } else if(isVerticalCrossOnLine(cell)){ result.add(cell.getNorth()); result.add(cell.getSouth()); } if(result.contains(blocked)) result.remove(blocked); return result; } public boolean isOutOfBounds(Cell cell){ if(cell.x > getWidth() - 1 || cell.y > getHeight() - 1 || cell.x < 0 || cell.y < 0) return true; return false; } public boolean isOutOfBounds(int x, int y){ char c = get(x, y); if(0 == c) return true; return false; } public boolean isBlank(Cell cell){ char c = get(cell); if(0 == c) return false; return c == ' '; } public boolean isBlank(int x, int y){ char c = get(x, y); if(0 == c) return true; return c == ' '; } public boolean isCorner(Cell cell){ return isCorner(cell.x, cell.y); } public boolean isCorner(int x, int y){ return (isNormalCorner(x,y) || isRoundCorner(x,y)); } public boolean matchesAny(Cell cell, GridPatternGroup criteria){ TextGrid subGrid = getTestingSubGrid(cell); return subGrid.matchesAny(criteria); } public boolean isCorner1(Cell cell){ return matchesAny(cell, GridPatternGroup.corner1Criteria); } public boolean isCorner2(Cell cell){ return matchesAny(cell, GridPatternGroup.corner2Criteria); } public boolean isCorner3(Cell cell){ return matchesAny(cell, GridPatternGroup.corner3Criteria); } public boolean isCorner4(Cell cell){ return matchesAny(cell, GridPatternGroup.corner4Criteria); } public boolean isCross(Cell cell){ return matchesAny(cell, GridPatternGroup.crossCriteria); } public boolean isK(Cell cell){ return matchesAny(cell, GridPatternGroup.KCriteria); } public boolean isInverseK(Cell cell){ return matchesAny(cell, GridPatternGroup.inverseKCriteria); } public boolean isT(Cell cell){ return matchesAny(cell, GridPatternGroup.TCriteria); } public boolean isInverseT(Cell cell){ return matchesAny(cell, GridPatternGroup.inverseTCriteria); } public boolean isNormalCorner(Cell cell){ return matchesAny(cell, GridPatternGroup.normalCornerCriteria); } public boolean isNormalCorner(int x, int y){ return isNormalCorner(new Cell(x, y)); } public boolean isRoundCorner(Cell cell){ return matchesAny(cell, GridPatternGroup.roundCornerCriteria); } public boolean isRoundCorner(int x, int y){ return isRoundCorner(new Cell(x, y)); } public boolean isIntersection(Cell cell){ return matchesAny(cell, GridPatternGroup.intersectionCriteria); } public boolean isIntersection(int x, int y){ return isIntersection(new Cell(x, y)); } public void copyCellsTo(CellSet cells, TextGrid grid){ Iterator it = cells.iterator(); while(it.hasNext()){ Cell cell = (Cell) it.next(); grid.set(cell, this.get(cell)); } } public boolean equals(TextGrid grid){ if(grid.getHeight() != this.getHeight() || grid.getWidth() != this.getWidth() ){ return false; } int height = grid.getHeight(); for(int i = 0; i < height; i++){ String row1 = this.getRow(i).toString(); String row2 = grid.getRow(i).toString(); if(!row1.equals(row2)) return false; } return true; } // @Override // public int hashCode() { // int h = 0; // for(StringBuffer row : rows) { // h += row.hashCode(); // } // return h; // } /** * Fills all the cells in
cells
with c
*
* @param cells
* @param c
*/
public void fillCellsWith(Iterable cells, char c){
Iteratorseed
.
*
* @param seed
* @return
*/
public CellSet findBoundariesExpandingFrom(Cell seed){
CellSet boundaries = new CellSet();
char oldChar = get(seed);
if(isOutOfBounds(seed)) return boundaries;
char newChar = 1; //TODO: kludge
Stack
* The syntax is:
*
* {@textdiagram diagram_name
*
* the ascii art diagram
* }
*
* The diagram name will be used when generating the image, so that the image * can be referenced to somewhere else (by using an a-href HTML tag). The * diagram name can only contain letters, numbers and underscore. The name of * the generated image will become "<classname>-<diagram name>.png". *
* The syntax for the ditaa diagram is described at * http://ditaa.sourceforge.net/. *
* Note: The overview file needs to be named "overview.html" if it lies
* in the source path, otherwise it is sufficient that it ends with ".html".
*
* @author Mikael Brannstrom
*/
public class JavadocTaglet implements Taglet {
private static final String NAME = "textdiagram";
private static final Pattern FIGURE_NAME_PATTERN = Pattern.compile("\\w+");
private final File[] srcPath;
private final File dstDir;
private final boolean simpleMode;
/** Creates a new instance of TextDiagramTaglet */
public JavadocTaglet() {
String configSourcepath = null;
String configDestDirName = null;
// Try to get configuration
try {
// Do this: Configuration config = Standard.htmlDoclet.configuration();
Field htmlDocletField = Standard.class.getField("htmlDoclet");
Object htmlDoclet = htmlDocletField.get(null); // static field
Method configurationMethod = htmlDoclet.getClass().getMethod("configuration", null);
Object config = configurationMethod.invoke(htmlDoclet, null);
// Do this: configSourcepath = config.sourcepath;
Field sourcepathField = config.getClass().getField("sourcepath");
configSourcepath = (String)sourcepathField.get(config);
// Do this: configDestDirName = config.destDirName;
Field destDirNameField = config.getClass().getField("destDirName");
configDestDirName = (String)destDirNameField.get(config);
} catch(Exception e) {
warning("Could not setup taglet. Falling back to simple mode.\n"+e);
}
if(configDestDirName == null) {
srcPath = null;
dstDir = null;
simpleMode = true;
} else {
// setup srcPath
String[] srcPathStr = configSourcepath.split("[;:]");
srcPath = new File[srcPathStr.length];
for(int i=0; i");
strBuf.append(figureText);
strBuf.append("
");
return strBuf.toString();
} else {
File outputFile = getOutputFile(tag.position().file(), figureName);
generateImage(figureText, outputFile);
StringBuffer strBuf = new StringBuffer();
strBuf.append("");
return strBuf.toString();
}
}
/** Returns null since this is an inline tag.
*/
public String toString(Tag[] tag) {
return null; // should return null, this is an inline tag
}
/** Returns the path of the output file given
* the source file and the diagram name.
* @param srcFile the source file which contains the tag
* @param name the diagram name that will be used for generating the output
* filename.
*/
private File getOutputFile(File srcFile, String name) {
String relPath = getRelativePath(srcFile);
// Special hack for the overview file
if(srcFile.getName().toLowerCase().equals("overview.html") ||
(relPath == null && srcFile.getName().toLowerCase().endsWith(".html"))) {
relPath = "overview";
}
if(relPath == null) {
error("The file is not relative to the source path: "+srcFile);
}
// get the filename and dirname
String dirname=null, filename=null;
int i = relPath.lastIndexOf(File.separatorChar);
if(i == -1) {
filename = relPath;
} else if(i == 0) {
filename = relPath.substring(1);
} else {
filename = relPath.substring(i+1);
dirname = relPath.substring(0, i);
}
// skip file ending in filename
i = filename.lastIndexOf('.');
if(i != -1)
filename = filename.substring(0, i);
String path;
if(dirname == null) {
path = filename;
} else {
path = dirname+File.separator+filename;
}
return new File(dstDir, path+"-"+name+".png");
}
/** Returns the relative path of a (source) file.
* The path is relative to one of the source dirs specified to the
* standard doclet.
* @returns the relative path. If a relative path could not be found
* null is returned.
*/
private String getRelativePath(File file) {
file = file.getAbsoluteFile();
try {
file = file.getCanonicalFile();
} catch (IOException ex) {
warning("Could not get canonical path of file: "+file);
}
String filePath = file.getAbsolutePath();
for(int i=0; i