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