\r
public class XGen<RT extends XGen<RT>> {\r
\r
- public static int COMMENT_COLUMN = 40;\r
- private StringBuilder backSB = new StringBuilder();\r
- private Stack<Back> backStack = new Stack<Back>();\r
- \r
- protected XGen(Writer w) {\r
- forward = new IndentPrintWriter(w);\r
- }\r
-\r
- public int pushBack(Back b) {\r
- int rv = backStack.size();\r
- backStack.push(b);\r
- return rv;\r
- }\r
-\r
- public boolean pretty = false;\r
- protected IndentPrintWriter forward;\r
-\r
- public IndentPrintWriter getWriter() {\r
- return forward;\r
- }\r
-\r
- protected PrintWriter back = new PrintWriter(\r
- new StringBuilderWriter(backSB));\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT pretty() {\r
- pretty = true;\r
- return (RT) this;\r
- }\r
-\r
- protected void prettyln(PrintWriter pw) {\r
- if(pretty)pw.println();\r
- }\r
-\r
- public RT leaf(Mark mark, String tag, String ... args) {\r
- mark.spot = backStack.size();\r
- return leaf(tag, args);\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT leaf(String tag, String ... attrs) {\r
- forward.append('<');\r
- forward.append(tag);\r
- addAttrs(attrs);\r
- forward.append('>');\r
- back.append("</");\r
- back.append(tag);\r
- back.append('>');\r
- backStack.push(new Back(backSB.toString(), false, true));\r
- backSB.setLength(0);\r
- return (RT)this;\r
- }\r
-\r
- public RT incr(String tag, String ... args) {\r
- return incr(null, tag, false, args);\r
- }\r
-\r
- public RT incr(String tag, boolean oneLine, String ... args) {\r
- return incr(null, tag, oneLine, args);\r
- }\r
-\r
- public RT incr(Mark mark) {\r
- return incr(mark,mark.comment, false, new String[0]);\r
- }\r
-\r
- public RT incr(Mark mark, String tag, String ... attrs) {\r
- return incr(mark, tag, false, attrs);\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT incr(Mark mark, String tag, boolean oneLine, String ... attrs) {\r
- forward.append('<');\r
- forward.append(tag);\r
- addAttrs(attrs);\r
- forward.append('>');\r
- \r
- back.append("</");\r
- back.append(tag);\r
- back.append('>');\r
- \r
- if(pretty) {\r
- if(mark!=null && mark.comment!=null) {\r
- int fi = forward.getIndent()*IndentPrintWriter.INDENT;\r
- for(int i = fi+backSB.length();i<=COMMENT_COLUMN;++i) {\r
- back.append(' ');\r
- }\r
- back.append("<!-- end ");\r
- back.append(mark.comment);\r
- back.append(" -->");\r
- \r
- forward.toCol(COMMENT_COLUMN);\r
- forward.append("<!-- begin ");\r
- forward.append(mark.comment);\r
- forward.append(" -->");\r
- }\r
- forward.inc();\r
- if(!oneLine) {\r
- forward.println();\r
- }\r
- back.println();\r
- }\r
- if(mark!=null)mark.spot = backStack.size();\r
- backStack.push(new Back(backSB.toString(),true, false));\r
- backSB.setLength(0);\r
- return (RT)this;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT tagOnly(String tag, String ... attrs) {\r
- forward.append('<');\r
- forward.append(tag);\r
- addAttrs(attrs);\r
- forward.append(" />");\r
- if(pretty) {\r
- forward.println();\r
- }\r
- return (RT)this;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT text(String txt) {\r
- forward.append(txt);\r
- return (RT)this;\r
- }\r
- \r
- @SuppressWarnings("unchecked")\r
- public RT xml(String txt) {\r
- for(int i=0; i<txt.length();++i) {\r
- char c = txt.charAt(i);\r
- switch(c) {\r
- case '<':\r
- forward.append("<");\r
- break;\r
- case '>':\r
- forward.append(">");\r
- break;\r
- case '&':\r
- forward.append("&");\r
- break;\r
- default:\r
- forward.append(c);\r
- }\r
- }\r
- return (RT)this;\r
- }\r
-\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT textCR(int tabs, String txt) {\r
- for(int i=0;i<tabs;++i) {\r
- forward.append(" ");\r
- }\r
- forward.append(txt);\r
- if(pretty)forward.println();\r
- return (RT)this;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT value() {\r
- Mark mark = new Mark();\r
- mark.spot = backStack.size()-1;\r
- end(mark);\r
- return (RT)this;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT value(String txt) {\r
- forward.append(txt);\r
- Mark mark = new Mark();\r
- mark.spot = backStack.size()-1;\r
- end(mark);\r
- return (RT)this;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT value(String txt, int levels) {\r
- forward.append(txt);\r
- Mark mark = new Mark();\r
- mark.spot = backStack.size()-levels;\r
- end(mark);\r
- return (RT)this;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT end(Mark mark) {\r
- int size = backStack.size();\r
- Back c;\r
- boolean println = false;\r
- for(int i=mark==null?0:mark.spot;i<size;++i) {\r
- c = backStack.pop();\r
- if(c.dec)forward.dec();\r
- forward.append(c.str);\r
- println = c.cr;\r
- }\r
- if(pretty && println) {\r
- forward.println();\r
- }\r
- return (RT)this;\r
- }\r
-\r
- public RT end() {\r
- Mark mark = new Mark();\r
- mark.spot=backStack.size()-1;\r
- if(mark.spot<0)mark.spot=0;\r
- return end(mark);\r
- }\r
-\r
- public RT end(int i) {\r
- Mark mark = new Mark();\r
- mark.spot=backStack.size()-i;\r
- if(mark.spot<0)mark.spot=0;\r
- return end(mark);\r
- }\r
-\r
- public void endAll() {\r
- end(new Mark());\r
- forward.flush();\r
- }\r
-\r
- protected void addAttrs(String[] attrs) {\r
- if(attrs!=null) {\r
- for(String attr : attrs) {\r
- if(attr!=null && attr.length()>0) {\r
- forward.append(' ');\r
- String[] split = attr.split("=",2);\r
- switch(split.length) {\r
- case 0:\r
- break;\r
- case 1:\r
- forward.append(split[0]);\r
-// forward.append("=\"\"");\r
- break;\r
- default:\r
- forward.append(split[0]);\r
- forward.append("=\"");\r
- forward.append(split[1]);\r
- forward.append('"');\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public RT comment(String string) {\r
- if(pretty) {\r
- forward.print("<!-- ");\r
- forward.print(string);\r
- forward.println(" -->");\r
- }\r
- return (RT)this;\r
- }\r
-\r
- public void setIndent(int indent) {\r
- forward.setIndent(indent);\r
- forward.toIndent();\r
- }\r
-\r
- public int getIndent() {\r
- return forward.getIndent();\r
- }\r
+ private static final int COMMENT_COLUMN = 40;\r
+ private StringBuilder backSB = new StringBuilder();\r
+ private Stack<Back> backStack = new Stack<Back>();\r
+ \r
+ protected XGen(Writer w) {\r
+ forward = new IndentPrintWriter(w);\r
+ }\r
+\r
+ public int pushBack(Back b) {\r
+ int rv = backStack.size();\r
+ backStack.push(b);\r
+ return rv;\r
+ }\r
+\r
+ public boolean pretty = false;\r
+ protected IndentPrintWriter forward;\r
+\r
+ public IndentPrintWriter getWriter() {\r
+ return forward;\r
+ }\r
+\r
+ protected PrintWriter back = new PrintWriter(\r
+ new StringBuilderWriter(backSB));\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT pretty() {\r
+ pretty = true;\r
+ return (RT) this;\r
+ }\r
+\r
+ protected void prettyln(PrintWriter pw) {\r
+ if (pretty)pw.println();\r
+ }\r
+\r
+ public RT leaf(Mark mark, String tag, String ... args) {\r
+ mark.spot = backStack.size();\r
+ return leaf(tag, args);\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT leaf(String tag, String ... attrs) {\r
+ forward.append('<');\r
+ forward.append(tag);\r
+ addAttrs(attrs);\r
+ forward.append('>');\r
+ back.append("</");\r
+ back.append(tag);\r
+ back.append('>');\r
+ backStack.push(new Back(backSB.toString(), false, true));\r
+ backSB.setLength(0);\r
+ return (RT)this;\r
+ }\r
+\r
+ public RT incr(String tag, String ... args) {\r
+ return incr(null, tag, false, args);\r
+ }\r
+\r
+ public RT incr(String tag, boolean oneLine, String ... args) {\r
+ return incr(null, tag, oneLine, args);\r
+ }\r
+\r
+ public RT incr(Mark mark) {\r
+ return incr(mark,mark.comment, false, new String[0]);\r
+ }\r
+\r
+ public RT incr(Mark mark, String tag, String ... attrs) {\r
+ return incr(mark, tag, false, attrs);\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT incr(Mark mark, String tag, boolean oneLine, String ... attrs) {\r
+ forward.append('<');\r
+ forward.append(tag);\r
+ addAttrs(attrs);\r
+ forward.append('>');\r
+ \r
+ back.append("</");\r
+ back.append(tag);\r
+ back.append('>');\r
+ \r
+ if (pretty) {\r
+ if (mark!=null && mark.comment!=null) {\r
+ int fi = forward.getIndent()*IndentPrintWriter.INDENT_MULTIPLIER;\r
+ for (int i = fi+backSB.length();i<=COMMENT_COLUMN;++i) {\r
+ back.append(' ');\r
+ }\r
+ back.append("<!-- end ");\r
+ back.append(mark.comment);\r
+ back.append(" -->");\r
+ \r
+ forward.toCol(COMMENT_COLUMN);\r
+ forward.append("<!-- begin ");\r
+ forward.append(mark.comment);\r
+ forward.append(" -->");\r
+ }\r
+ forward.inc();\r
+ if (!oneLine) {\r
+ forward.println();\r
+ }\r
+ back.println();\r
+ }\r
+ if (mark!=null)mark.spot = backStack.size();\r
+ backStack.push(new Back(backSB.toString(),true, false));\r
+ backSB.setLength(0);\r
+ return (RT)this;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT tagOnly(String tag, String ... attrs) {\r
+ forward.append('<');\r
+ forward.append(tag);\r
+ addAttrs(attrs);\r
+ forward.append(" />");\r
+ if (pretty) {\r
+ forward.println();\r
+ }\r
+ return (RT)this;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT text(String txt) {\r
+ forward.append(txt);\r
+ return (RT)this;\r
+ }\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ public RT xml(String txt) {\r
+ for (int i=0; i<txt.length();++i) {\r
+ char c = txt.charAt(i);\r
+ switch(c) {\r
+ case '<':\r
+ forward.append("<");\r
+ break;\r
+ case '>':\r
+ forward.append(">");\r
+ break;\r
+ case '&':\r
+ forward.append("&");\r
+ break;\r
+ default:\r
+ forward.append(c);\r
+ }\r
+ }\r
+ return (RT)this;\r
+ }\r
+\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT textCR(int tabs, String txt) {\r
+ for (int i=0;i<tabs;++i) {\r
+ forward.append(" ");\r
+ }\r
+ forward.append(txt);\r
+ if (pretty)forward.println();\r
+ return (RT)this;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT value() {\r
+ Mark mark = new Mark();\r
+ mark.spot = backStack.size()-1;\r
+ end(mark);\r
+ return (RT)this;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT value(String txt) {\r
+ forward.append(txt);\r
+ Mark mark = new Mark();\r
+ mark.spot = backStack.size()-1;\r
+ end(mark);\r
+ return (RT)this;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT value(String txt, int levels) {\r
+ forward.append(txt);\r
+ Mark mark = new Mark();\r
+ mark.spot = backStack.size()-levels;\r
+ end(mark);\r
+ return (RT)this;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT end(Mark mark) {\r
+ int size = backStack.size();\r
+ Back c;\r
+ boolean println = false;\r
+ for (int i=mark==null?0:mark.spot;i<size;++i) {\r
+ c = backStack.pop();\r
+ if (c.dec)forward.dec();\r
+ forward.append(c.str);\r
+ println = c.cr;\r
+ }\r
+ if (pretty && println) {\r
+ forward.println();\r
+ }\r
+ return (RT)this;\r
+ }\r
+\r
+ public RT end() {\r
+ Mark mark = new Mark();\r
+ mark.spot=backStack.size()-1;\r
+ if (mark.spot<0)mark.spot=0;\r
+ return end(mark);\r
+ }\r
+\r
+ public RT end(int i) {\r
+ Mark mark = new Mark();\r
+ mark.spot=backStack.size()-i;\r
+ if (mark.spot<0)mark.spot=0;\r
+ return end(mark);\r
+ }\r
+\r
+ public void endAll() {\r
+ end(new Mark());\r
+ forward.flush();\r
+ }\r
+\r
+ protected void addAttrs(String[] attrs) {\r
+ if (attrs!=null) {\r
+ for (String attr : attrs) {\r
+ if (attr!=null && attr.length()>0) {\r
+ forward.append(' ');\r
+ String[] split = attr.split("=",2);\r
+ switch(split.length) {\r
+ case 0:\r
+ break;\r
+ case 1:\r
+ forward.append(split[0]);\r
+// forward.append("=\"\"");\r
+ break;\r
+ default:\r
+ forward.append(split[0]);\r
+ forward.append("=\"");\r
+ forward.append(split[1]);\r
+ forward.append('"');\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public RT comment(String string) {\r
+ if (pretty) {\r
+ forward.print("<!-- ");\r
+ forward.print(string);\r
+ forward.println(" -->");\r
+ }\r
+ return (RT)this;\r
+ }\r
+\r
+ public void setIndent(int indent) {\r
+ forward.setIndent(indent);\r
+ forward.toIndent();\r
+ }\r
+\r
+ public int getIndent() {\r
+ return forward.getIndent();\r
+ }\r
\r
}\r