我如何使用Java或Javascript解析ASCII艺术到HTML?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (62)

我看到Neo4j API非常巧妙地使用ASCII Art API:

http://jaxenter.com/getting-started-with-neo4j-the-java-graph-database-47955.html

我想尝试类似的东西,但是使用ASCI Art转换为HTML。ASCII艺术如何被解析,例如,给定一个ASCII艺术输入如下所示:

--------------------------------
I                              I
I   -------          -------   I
I   I     I          I     I   I
I   I  A  I          I  B  I   I
I   I     I          I     I   I
I   -------          -------   I
I                              I
I                              I
--------------------------------

:可能导致HTML输出如下所示:

<div>
    <div style='display:inline;'>
             A
    </div>
    <div style='display:inline;'>
             B
    </div>
</div>

这个问题是封闭的,因为我需要“展示对解决问题的最低限度的理解”。我确实了解要解决的问题。问题是,我想解决的是使源代码中的模板HTML更易于理解以下Web框架:

https://github.com/zubairq/coils

:虽然解决方案可以应用于任何Web框架。自从我看到有人试图在C ++中创建一个初始版本:

https://github.com/h3nr1x/asciidivs2html/blob/master/asciidivs2html.cpp

: 非常令人印象深刻!如果你能在Java或Clojure中工作,那么如果我们能够重新开放问题,我会提名一个奖励,这样你就可以获得更多的解决方案:)

我运行@meewok提供的Java解决方案,结果如下:

$ java AsciiToDIVs.RunConverter
Created a box(ID=0,X=0,Y=0,width=33,height=10)
Created a box(ID=1,X=2,Y=4,width=8,height=5,parent=0)
Created a char(Char=A,X=4,Y=7,parent=1)
Created a box(ID=2,X=2,Y=21,width=8,height=5,parent=0)
Created a char(Char=B,X=4,Y=24,parent=2)
<div><div><div>A</div></div><div><div>B</div></div></div>
提问于
用户回答回答于

方法

实施的解决方案如下:

  • 创建一个与棋盘类似的内存二维数组(阵列数组)。

然后,我将创建一个算法,当它检测到“ - ”字符时,我会初始化一个方法来检测字符后面剩余的角落(右上角,左下角,右下角)以及它们结束的位置。

示例(快速伪代码):

while(selectedCell==I) selectedCell=selectedCell.goDown();

使用这种策略,您可以绘制出您的箱子,以及包含哪些箱子。

剩下的就是将这些信息打印成html ..

Implementation

由于我心情很好,我花了一个小时+快速制作玩具实施。下面是没有优化的,因为我没有使用迭代器来遍历单元格,并且需要重构才能成为一个严格的框架。

Cell.java

package AsciiToDIVs;

public class Cell {
    public char Character;
    public CellGrid parentGrid;
    private int rowIndex;
    private int colIndex;

    public Cell(char Character, CellGrid parent, int rowIndex, int colIndex)
    {
        this.Character = Character;
        this.parentGrid = parent;
        this.rowIndex = rowIndex;
        this.colIndex = colIndex;
    }

    public int getRowIndex() {
        return rowIndex;
    }

    public int getColIndex() {
        return colIndex;
    }
}

CellGrid.java

package AsciiToDIVs;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;

public class CellGrid {

    private ArrayList<ArrayList<Cell>> CellGridData;

    public CellGrid(String asciiFile) throws IOException {
        readDataFile(asciiFile);
    }

    public ArrayList<FoundObject> findBoxes(FoundBoxObject parent)
    {

        int startRowIndex = 0, startColIndex = 0, 
                parentRowLimit = Integer.MAX_VALUE, 
                parentColLimit = Integer.MAX_VALUE,
                startingColIndex = 0;
        if(parent != null)
        {
            startRowIndex = parent.getRowIndex()+1;
            startColIndex = startingColIndex =  parent.getColIndex()+1;
            parentRowLimit = parent.getRowIndex() + parent.getHeight();
            parentColLimit = parent.getColIndex() + parent.getWidth();
        }

        ArrayList<FoundObject> results = new ArrayList<FoundObject>();

        Cell currentCell;

        if(startRowIndex>=CellGridData.size())
        return null;        

        for(; startRowIndex<CellGridData.size() && startRowIndex<parentRowLimit; startRowIndex++ )
        {
            startColIndex = startingColIndex;

            for(; startColIndex< CellGridData.get(startRowIndex).size() && startColIndex<parentColLimit; startColIndex++)
            {           
                FoundBoxObject withinBox = checkWithinFoundBoxObject(results, startRowIndex, startColIndex);

                if(withinBox !=null)
                startColIndex+=withinBox.getWidth();

                currentCell = getCell(startRowIndex, startColIndex);

                if(currentCell!=null)
                {
                    if(currentCell.Character == '-') // Found a TOP-CORNER
                    {
                        int boxHeight =  getConsecutiveIs(startRowIndex+1, startColIndex) + 1;
                        if(boxHeight>1)
                        {
                            int boxWidth = getConsecutiveDashes(startRowIndex, startColIndex);

                            FoundBoxObject box = new FoundBoxObject(startRowIndex, startColIndex, boxWidth, boxHeight, parent);
                            results.add(box);
                            findBoxes(box);

                            startColIndex+=boxWidth;                            
                        }                   
                    }

                    //This is a character
                    else if(currentCell.Character != '-' && currentCell.Character != 'I' && currentCell.Character != ' ' 
                            && currentCell.Character != '\n' && currentCell.Character != '\n' && currentCell.Character != '\t')
                    {
                        FoundCharObject Char = new FoundCharObject(startRowIndex, startColIndex, parent,  currentCell.Character);
                        results.add(Char);
                    }
                }
            }       
        }

        if(parent!=null)
        parent.containedObjects = results;

        return results;     
    }

    public static String printDIV(ArrayList<FoundObject> objects)
    {
        String result = "";
        Iterator<FoundObject> it = objects.iterator();
        FoundObject fo;

        while(it.hasNext())
        {
            result+="<div>";

            fo = it.next();

            if(fo instanceof FoundCharObject)
            {
                FoundCharObject fc = (FoundCharObject)fo;
                result+=fc.getChar();
            }

            if(fo instanceof FoundBoxObject)
            {
                FoundBoxObject fb = (FoundBoxObject)fo;
                result+=printDIV(fb.containedObjects);
            }

            result+="</div>";
        }

        return result;
    }

    private FoundBoxObject checkWithinFoundBoxObject(ArrayList<FoundObject> results, int rowIndex, int colIndex)
    {
        Iterator<FoundObject> it = results.iterator();
        FoundObject f;
        FoundBoxObject fbox = null;
        while(it.hasNext())
        {
            f = it.next();

            if(f instanceof FoundBoxObject)
            {
                fbox = (FoundBoxObject) f;

                if(rowIndex >= fbox.getRowIndex() && rowIndex <= fbox.getRowIndex() + fbox.getHeight())
                {
                    if(colIndex >= fbox.getColIndex() && colIndex <= fbox.getColIndex() + fbox.getWidth())
                    {
                        return fbox;
                    }
                }
            }
        }

        return null;
    }

    private int getConsecutiveDashes(int startRowIndex, int startColIndex)
    {
        int counter = 0;
        Cell cell = getCell(startRowIndex, startColIndex);

        while( cell!=null && cell.Character =='-')
        {
            counter++;
            cell = getCell(startRowIndex, startColIndex++);
        }

        return counter;

    }

    private int getConsecutiveIs(int startRowIndex, int startColIndex)
    {
        int counter = 0;
        Cell cell = getCell(startRowIndex, startColIndex);

        while( cell!=null && cell.Character =='I')
        {
            counter++;
            cell = getCell(startRowIndex++, startColIndex);
        }

        return counter;
    }

    public Cell getCell(int rowIndex, int columnIndex)
    {
        ArrayList<Cell> row;


        if(rowIndex<CellGridData.size())
        row = CellGridData.get(rowIndex);
        else return null;

        Cell cell = null;

        if(row!=null){
            if(columnIndex<row.size())
            cell = row.get(columnIndex);
        }

        return cell;
    }


    public Iterator<ArrayList<Cell>> getRowGridIterator(int StartRow) {
        Iterator<ArrayList<Cell>> itRow = CellGridData.iterator();

        int CurrentRow = 0;

        while (itRow.hasNext()) {
            // Itrate to Row
            if (CurrentRow++ < StartRow)
                itRow.next();

        }
        return itRow;
    }

    private void readDataFile(String asciiFile) throws IOException {
        CellGridData = new ArrayList<ArrayList<Cell>>();
        ArrayList<Cell> row;

        FileInputStream fstream = new FileInputStream(asciiFile);
        BufferedReader br = new BufferedReader(new InputStreamReader(fstream));

        String strLine;

        // Read File Line By Line
        int rowIndex = 0;
        while ((strLine = br.readLine()) != null) {
            CellGridData.add(row = new ArrayList<Cell>());
            // System.out.println (strLine);
            for (int colIndex = 0; colIndex < strLine.length(); colIndex++) {
                row.add(new Cell(strLine.charAt(colIndex), this, rowIndex,colIndex));
                // System.out.print(strLine.charAt(i));
            }
            rowIndex++;
            // System.out.println();
        }

        // Close the input stream
        br.close();
    }

    public String printGrid() {
        String result = "";

        Iterator<ArrayList<Cell>> itRow = CellGridData.iterator();
        Iterator<Cell> itCol;
        Cell cell;

        while (itRow.hasNext()) {
            itCol = itRow.next().iterator();

            while (itCol.hasNext()) {
                cell = itCol.next();
                result += cell.Character;
            }
            result += "\n";
        }

        return result;
    }

}

FoundBoxObject.java

package AsciiToDIVs;

import java.util.ArrayList;

public class FoundBoxObject extends FoundObject {
    public ArrayList<FoundObject> containedObjects = new ArrayList<FoundObject>();
    public static int boxCounter = 0;

    public final int ID = boxCounter++;

    public FoundBoxObject(int rowIndex, int colIndex, int width, int height, FoundBoxObject parent) {
        super(rowIndex, colIndex, width, height);

        if(parent!=null)
        System.out.println("Created a box(" +
                "ID="+ID+
                ",X="+rowIndex+
                ",Y="+colIndex+
                ",width="+width+
                ",height="+height+
                ",parent="+parent.ID+")");
        else
            System.out.println("Created a box(" +
                    "ID="+ID+
                    ",X="+rowIndex+
                    ",Y="+colIndex+
                    ",width="+width+
                    ",height="+height+
                    ")");   
    }

}

FoundCharObject.java

package AsciiToDIVs;

public class FoundCharObject extends FoundObject {
private Character Char;

public FoundCharObject(int rowIndex, int colIndex,FoundBoxObject parent, char Char) {
    super(rowIndex, colIndex, 1, 1);

    if(parent!=null)
    System.out.println("Created a char(" +
            "Char="+Char+
            ",X="+rowIndex+
            ",Y="+colIndex+
            ",parent="+parent.ID+")");
    else
        System.out.println("Created a char(" +
                ",X="+rowIndex+
                ",Y="+colIndex+")");

    this.Char = Char;
}

public Character getChar() {
    return Char;
}
}

FoundObject.java

package AsciiToDIVs;

public class FoundObject {

    private int rowIndex;
    private int colIndex;
    private int width = 0;
    private int height = 0;

    public FoundObject(int rowIndex, int colIndex, int width, int height )
    {
        this.rowIndex = rowIndex;
        this.colIndex = colIndex;
        this.width = width;
        this.height = height;
    }

    public int getRowIndex() {
        return rowIndex;
    }

    public int getColIndex() {
        return colIndex;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }
}

主要方法

public static void main(String args[])
    {
        try {
            CellGrid grid = new CellGrid("ascii.txt");
            System.out.println(CellGrid.printDIV(grid.findBoxes(null)));
            //System.out.println(grid.printGrid());
        } catch (IOException e) {
            e.printStackTrace();
        }       
    }   

'printDIV'应该是这样的

public static String printDIV(ArrayList<FoundObject> objects)
    {
        String result = "";
        Iterator<FoundObject> it = objects.iterator();
        FoundObject fo;

        while(it.hasNext())
        {
            fo = it.next();

            if(fo instanceof FoundCharObject)
            {
                FoundCharObject fc = (FoundCharObject)fo;
                result+=fc.getChar();
            }

            if(fo instanceof FoundBoxObject)
            {
                result+="<div>";
                FoundBoxObject fb = (FoundBoxObject)fo;
                result+=printDIV(fb.containedObjects);
                result+="</div>";
            }           
        }

        return result;
    }
用户回答回答于

这是JavaScript中一个相当简单的解决方案,通过Node进行测试。当然,你需要调整输入和输出方法。

var s = "\n\
--------------------------------\n\
I                              I\n\
I   -------          -------   I\n\
I   I     I          I     I   I\n\
I   I  A  I          I  B  I   I\n\
I   I     I          I     I   I\n\
I   -------          -------   I\n\
I                              I\n\
I                              I\n\
--------------------------------\n\
";

var lines = s.split('\n');

var outer_box_top_re = /--+/g;

var i;
for (i=0; i<lines.length; i++) {
    while ((res = outer_box_top_re.exec(lines[i])) != null) {
        L = res.index
        R = outer_box_top_re.lastIndex
        process_box(i, L, R)
    }
}

function process_box(T, L, R) {
    console.log('<div top="' + T + '" left="' + L + '" right="' + R + '">')
    blank_out(T, L, R)

    var i = T;
    while (1) {
        i += 1;
        if (i >= lines.length) {
            console.log('Fell off bottom of ascii-art without finding bottom of box');
            process.exit(1);
        }

        var line = lines[i];

        if (line[L] == 'I' && line[R-1] == 'I') {
            // interior

            // Look for (the tops of) sub-boxes.
            // (between L+1 and R-2)
            var inner_box_top_re = /--+/g;
            // Inner and outer need to be separate so that
            // inner doesn't stomp on outer's lastIndex.
            inner_box_top_re.lastIndex = L+1;
            while ((res = inner_box_top_re.exec(lines[i])) != null) {
                sub_L = res.index;
                sub_R = inner_box_top_re.lastIndex;
                if (sub_L > R-1) { break; }
                process_box(i, sub_L, sub_R);
            }

            // Look for any other content (i.e., a box label)
            content = lines[i].substring(L+1, R-1);
            if (content.search(/[^ ]/) != -1) {
                console.log(content);
            }

            blank_out(i, L, R);
        }
        else if (line.substring(L,R).match(/^-+$/)) {
            // bottom
            blank_out(i, L, R);
            break;
        }
        else {
            console.log("line " + i + " doesn't contain a valid continuation of the box");
            process.exit(1)
        }
    }

    console.log('</div>')
}

function blank_out(i, L, R) {
    lines[i] = (
          lines[i].substring(0,L)
        + lines[i].substring(L,R).replace(/./g, ' ')
        + lines[i].substring(R)
    );
}

扫码关注云+社区