]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/documentation/HtmlUnparsingContext.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / parsing / documentation / HtmlUnparsingContext.java
1 package org.simantics.scl.compiler.internal.parsing.documentation;\r
2 \r
3 import java.io.IOException;\r
4 import java.io.StringReader;\r
5 import java.util.regex.Matcher;\r
6 import java.util.regex.Pattern;\r
7 \r
8 import org.simantics.scl.compiler.elaboration.modules.Documentation;\r
9 import org.simantics.scl.compiler.types.Type;\r
10 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;\r
11 \r
12 public abstract class HtmlUnparsingContext {\r
13     StringBuilder stringBuilder;\r
14     String listLevel = "";\r
15     \r
16     int tableOfContentsLevel = 0;\r
17     StringBuilder tableOfContents;\r
18     \r
19     int headerLinkId = 0;\r
20     \r
21     public HtmlUnparsingContext(StringBuilder stringBuilder) {\r
22         this.stringBuilder = stringBuilder;\r
23         this.tableOfContents = null;\r
24     }\r
25     \r
26     public HtmlUnparsingContext() {\r
27         this(new StringBuilder());\r
28         tableOfContents = new StringBuilder();\r
29     }\r
30 \r
31     public StringBuilder getStringBuilder() {\r
32         return stringBuilder;\r
33     }\r
34     \r
35     public StringBuilder getTableOfContents() {\r
36         return tableOfContents;\r
37     }\r
38     \r
39     public void finishTableOfContents() {\r
40         while(tableOfContentsLevel > 0) {\r
41             tableOfContents.append("</ul>\n");\r
42             --tableOfContentsLevel;\r
43         }\r
44     }\r
45     \r
46     public void header(int level, String text) {\r
47         clear();        \r
48         ++headerLinkId;\r
49         stringBuilder.append("<h").append(level)\r
50         .append(" id=\"sec").append(headerLinkId).append("\">")\r
51         .append(text)\r
52         .append("</h").append(level).append(">\n");\r
53         \r
54         while(tableOfContentsLevel > level) {\r
55             tableOfContents.append("</ul>\n");\r
56             --tableOfContentsLevel;\r
57         }\r
58         while(tableOfContentsLevel < level) {\r
59             tableOfContents.append("<ul>\n");\r
60             ++tableOfContentsLevel;\r
61         }\r
62         tableOfContents.append("<li><a href=\"#sec")\r
63             .append(headerLinkId).append("\">")\r
64             .append(text).append("</a></li>\n");\r
65     }\r
66         \r
67     public void clear() {\r
68         setListLevel("");\r
69     }\r
70     \r
71     public void setListLevel(String newLevel) {\r
72         String oldLevel = this.listLevel;\r
73         int commonLevel = 0;\r
74         while(commonLevel < oldLevel.length() && commonLevel < newLevel.length() && \r
75                 newLevel.charAt(commonLevel) == oldLevel.charAt(commonLevel))\r
76             ++commonLevel;\r
77         \r
78         for(int i=oldLevel.length()-1;i>=commonLevel;--i) {\r
79             char c = oldLevel.charAt(i);\r
80             if(c == '*')\r
81                 stringBuilder.append("</ul>\n");\r
82             else if(c == '#')\r
83                 stringBuilder.append("</ol>\n");\r
84         }\r
85         for(int i=commonLevel;i<newLevel.length();++i) {\r
86             char c = newLevel.charAt(i);\r
87             if(c == '*')\r
88                 stringBuilder.append("<ul>\n");\r
89             else if(c == '#')\r
90                 stringBuilder.append("<ol>\n");\r
91         }\r
92         \r
93         this.listLevel = newLevel;\r
94     }\r
95     \r
96     public void appendDocumentation(String doc) {\r
97         DocumentationLexer lexer = new DocumentationLexer(new StringReader(doc));\r
98 \r
99         clear();\r
100         while(true) {\r
101             DocumentationElement element = null;\r
102             try {\r
103                 element = lexer.nextToken();\r
104             } catch (IOException e) {\r
105                 e.printStackTrace();\r
106             } catch (DocumentationParsingException e) {\r
107                 e.printStackTrace();\r
108             }\r
109             if(element == null)\r
110                 break;\r
111             element.toHtml(this);\r
112         }\r
113         clear();\r
114     }\r
115 \r
116     public static String escape(String text) {\r
117         return text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");\r
118     }\r
119 \r
120     public abstract void documentEntity(String ref);\r
121 \r
122     public void appendType(TypeUnparsingContext tuc, Type type, int precedence) {\r
123         StringBuilder b = new StringBuilder();\r
124         type.toString(tuc, b, precedence);\r
125         stringBuilder.append(escape(b.toString()));\r
126     }\r
127     \r
128     public void appendType(TypeUnparsingContext tuc, Type type) {\r
129         appendType(tuc, type, 3);\r
130     }\r
131     \r
132     public void appendRef(String ref) {\r
133         stringBuilder.append("<a name=\"").append(ref).append("\" class=\"ref\">")\r
134                      .append(escape(ref)).append("</a>");\r
135     }\r
136 \r
137     public Documentation toDocumentation() {\r
138         finishTableOfContents();\r
139         return new Documentation(stringBuilder.toString(), tableOfContents.toString());\r
140     }\r
141 \r
142     private static final Pattern PARAGRAPH_PATTERN = Pattern.compile("'[^ ']+'|@[^@]+@");\r
143     \r
144     public void appendParagraph(String text) {\r
145         clear();\r
146         stringBuilder.append("<p>");        \r
147         Matcher m = PARAGRAPH_PATTERN.matcher(text);\r
148         int lastAppend = 0;\r
149         while(m.find()) {\r
150             int start = m.start();\r
151             int end = m.end();\r
152             \r
153             stringBuilder.append(text, lastAppend, start);\r
154             char c = text.charAt(start);\r
155             if(c == '\'') {\r
156                 String ref = text.substring(start+1, end-1);\r
157                 \r
158                 stringBuilder.append("<code><a href=\"#").append(ref).append("\">")\r
159                              .append(ref)\r
160                              .append("</a></code>");\r
161             }\r
162             else if(c == '@') {\r
163                 stringBuilder.append("<code>").append(text, start+1, end-1).append("</code>");\r
164             }\r
165             lastAppend = end;\r
166         }\r
167         stringBuilder.append(text, lastAppend, text.length());\r
168         stringBuilder.append("</p>\n");        \r
169     }\r
170 }\r