source: default/trunk/de.ugoe.cs.swe.bnftools.ebnf.ui/src/de/ugoe/cs/swe/bnftools/ui/formatter/EbnfHtmlFormatterVisitor.java @ 42

Last change on this file since 42 was 42, checked in by zeiss, 14 years ago
  • Property svn:mime-type set to text/plain
File size: 11.9 KB
Line 
1package de.ugoe.cs.swe.bnftools.ui.formatter;
2
3import java.util.ArrayList;
4import java.util.Iterator;
5
6import org.apache.commons.lang.StringEscapeUtils;
7import org.apache.commons.lang.StringUtils;
8import org.eclipse.emf.ecore.EObject;
9import org.eclipse.xtext.parsetree.LeafNode;
10import org.eclipse.xtext.parsetree.NodeUtil;
11
12import de.ugoe.cs.swe.bnftools.ebnf.EtsiBnf;
13import de.ugoe.cs.swe.bnftools.ebnf.Import;
14import de.ugoe.cs.swe.bnftools.ebnf.Rule;
15import de.ugoe.cs.swe.bnftools.ebnf.RuleReference;
16import de.ugoe.cs.swe.bnftools.ebnf.SectionHeading;
17import de.ugoe.cs.swe.bnftools.ebnf.StringRule;
18
19public class EbnfHtmlFormatterVisitor extends EbnfFormatterVisitor {
20
21        private ArrayList<MetaTextEntry> metaTexts = new ArrayList<MetaTextEntry>();
22        private ArrayList<MetaTextEntry> transformedTexts = new ArrayList<MetaTextEntry>();
23        private int lastMetaTextBlock = 0;
24        private boolean isParagraphOpen = false;
25       
26        public EbnfHtmlFormatterVisitor(EObject rootNode, FormatterConfig config) {
27                super(rootNode, config);
28                this.config = config;
29                buf = new StringBuffer();
30        }
31
32        protected void weaveComments() {
33                bufferPositionOriginalText = 0;
34                bufferPositionFormattedTextNoWhitespaces = 0;
35                bufferPositionFormattedText = 0;
36               
37                StringBuffer result = new StringBuffer();
38                formattedTextNoWhitespaces = buf.toString().replaceAll("[ \t\n\r]", "");
39                formattedText = buf.toString();
40
41                MetaTextEntry currentMetaText = null;
42                if (metaTexts.iterator().hasNext())
43                        currentMetaText = metaTexts.iterator().next();
44
45                MetaTextEntry currentTransformedText = null;
46                if (transformedTexts.iterator().hasNext())
47                        currentTransformedText = transformedTexts.iterator().next();
48               
49                while (bufferPositionFormattedTextNoWhitespaces <= formattedTextNoWhitespaces.length()) {
50                        skipWhitespacesOriginalText();
51                        skipWhitespacesFormattedText(result);
52                       
53                        if (!(bufferPositionOriginalText < originalText.length()))
54                                break;
55                       
56                        char formattedPositionNoWhitespaces;
57                        if (bufferPositionFormattedTextNoWhitespaces == formattedTextNoWhitespaces.length()) {
58                                formattedPositionNoWhitespaces = ' ';
59                        } else {
60                                formattedPositionNoWhitespaces = formattedTextNoWhitespaces.charAt(bufferPositionFormattedTextNoWhitespaces);
61                        }
62                        char originalPosition = originalText.charAt(bufferPositionOriginalText);
63                       
64                        if (formattedPositionNoWhitespaces != originalPosition) {
65//                              if ((currentMetaText != null) && (bufferPositionFormattedTextNoWhitespaces == currentMetaText.getOffset())) {
66//                                      result.append(currentMetaText.getText());
67//                                      metaTexts.remove(currentMetaText);
68//                                      if (metaTexts.iterator().hasNext())
69//                                              currentMetaText = metaTexts.iterator().next();
70//                                      else
71//                                              currentMetaText = null;
72//                              }
73
74                                if (formattedPositionNoWhitespaces == ';') { // formatted text always outputs the optional semicolon, skip it if necessary
75                                        bufferPositionFormattedTextNoWhitespaces++;
76                                        bufferPositionFormattedText++;
77                                } else if (isCommentNext(originalText, bufferPositionOriginalText)) {
78                                        LeafNode currentComment = allComments.get(allCommentsPosition);
79                                        if (currentComment.getTotalOffset() == bufferPositionOriginalText) {
80                                                if (isMultiLineComment(currentComment.getText())) {
81                                                        int newLinesCount = scanBackNewlinesCount(originalText, bufferPositionOriginalText-1);
82                                                        if (newLinesCount > 0) {
83                                                                if (scanBackNewlinesCount(result.toString(), result.toString().length()-1) == 0) {
84                                                                        result.append("\n\n");
85                                                                }
86                                                               
87                                                                result.append(currentComment.getText());
88                                                                result.append("\n");
89                                                        } else {
90                                                                String lastWhiteSpaces = scanBackWhitespaces(result.toString(), result.toString().length()-1);
91                                                                result.delete(result.toString().length() - lastWhiteSpaces.length(), result.toString().length());
92                                                                result.append(" " + stripEndingNewline(currentComment.getText()));
93                                                                result.append(lastWhiteSpaces);
94                                                        }
95                                                } else if (isSingleLineComment(currentComment.getText())) {
96                                                        int newLinesCount = scanBackNewlinesCount(originalText, bufferPositionOriginalText-1);
97                                                        String lastWhiteSpaces = scanBackWhitespaces(result.toString(), result.toString().length()-1);
98                                                        result.delete(result.toString().length() - lastWhiteSpaces.length(), result.toString().length());
99                                                        if (newLinesCount > 0) {
100                                                                result.append("\n\n" + stripEndingNewline(currentComment.getText()));
101                                                        } else {
102                                                                result.append(" " + stripEndingNewline(currentComment.getText()));
103                                                        }
104                                                        result.append(lastWhiteSpaces);
105                                                }
106                                                bufferPositionOriginalText+=currentComment.getLength();
107                                                allCommentsPosition++;
108                                        }
109                                } else { // disaster handling: return original unformatted text!
110                                        System.err.println("Disaster Recovery: returning original text!!");
111                                        buf = new StringBuffer();
112                                        buf.append(originalText);
113                                        return;
114                                }
115                        } else {
116                                while (lastMetaTextBlock == 0 && (currentMetaText != null) && (bufferPositionFormattedTextNoWhitespaces >= currentMetaText.getOffset())) {
117                                        result.append(currentMetaText.getText());
118                                        metaTexts.remove(currentMetaText);
119                                        if (metaTexts.iterator().hasNext())
120                                                currentMetaText = metaTexts.iterator().next();
121                                        else
122                                                currentMetaText = null;
123                                       
124                                        if ((currentMetaText == null) && (bufferPositionFormattedTextNoWhitespaces != currentMetaText.getOffset()))
125                                                lastMetaTextBlock = 1;
126                                }
127
128                                if (currentTransformedText != null && currentTransformedText.getOffset() == bufferPositionFormattedTextNoWhitespaces) {
129                                        result.append(currentTransformedText.getTransformedText());
130                                        bufferPositionOriginalText += currentTransformedText.getText().length();
131                                        bufferPositionFormattedText += currentTransformedText.getText().length();
132                                        bufferPositionFormattedTextNoWhitespaces += currentTransformedText.getText().replaceAll("[ \t\r\n]", "").length();
133                                        transformedTexts.remove(currentTransformedText);
134                                        currentTransformedText = null;
135                                       
136                                        if (transformedTexts.iterator().hasNext())
137                                                currentTransformedText = transformedTexts.iterator().next();
138                                } else {
139                                        String text = formattedText.substring(bufferPositionFormattedText, bufferPositionFormattedText+1);
140                                        result.append(text);
141                                        bufferPositionOriginalText++;
142                                        bufferPositionFormattedText++;
143                                        bufferPositionFormattedTextNoWhitespaces++;
144                                }
145
146                                while ( lastMetaTextBlock == 1 && currentMetaText != null && bufferPositionFormattedTextNoWhitespaces >= currentMetaText.getOffset()) {
147                                        result.append(currentMetaText.getText());
148                                        metaTexts.remove(currentMetaText);
149                                        if (metaTexts.iterator().hasNext()) {
150                                                currentMetaText = metaTexts.iterator().next();
151                                        } else {
152                                                currentMetaText = null;
153                                        }
154                                       
155                                        if ((currentMetaText == null) || (bufferPositionFormattedTextNoWhitespaces != currentMetaText.getOffset()))
156                                                lastMetaTextBlock = 0;
157                                }
158                        }
159                }
160                while ( bufferPositionFormattedTextNoWhitespaces >= formattedTextNoWhitespaces.length()-1 && currentMetaText != null) {
161                        result.append(currentMetaText.getText());
162                        metaTexts.remove(currentMetaText);
163                        if (metaTexts.iterator().hasNext()) {
164                                currentMetaText = metaTexts.iterator().next();
165                        } else {
166                                currentMetaText = null;
167                        }
168                }
169
170               
171                buf = result;
172        }
173       
174        protected void metaText(String str) {
175                MetaTextEntry metaTextEntry = new MetaTextEntry(str, buf.toString().replaceAll("[ \t\n\r]", "").length());
176                metaTexts.add(metaTextEntry);
177        }
178
179        protected void textTransformed(String original, String transformed) {
180                MetaTextEntry metaText = new MetaTextEntry(original, transformed, buf.toString().replaceAll("[ \t\n\r]", "").length());
181                transformedTexts.add(metaText);
182                buf.append(original);
183                newLineOffsetCounter += original.length();
184        }
185       
186        protected void newLine() {
187                buf.append("\n");
188                if (!isParagraphOpen) {
189                        metaText("\n<p class=PL style='mso-pagination:widow-orphan lines-together;page-break-after: avoid'>\n");
190                        isParagraphOpen = true;
191                } else {
192                        metaText("\n</p>\n");
193                        isParagraphOpen = false;
194                }
195               
196                if ((ruleSpacingStack != null) && (!ruleSpacingStack.empty())) {
197                        newLineOffsetCounter = ruleSpacingStack.peek();
198                } else {
199                        newLineOffsetCounter = 0;
200                }
201        }
202       
203        protected void space() {
204                metaText("<span style='mso-spacerun:yes'>&nbsp;</span>");
205                buf.append(" ");
206                newLineOffsetCounter++;
207        }
208       
209        protected void spaces(int count) {
210                metaText("<span style='mso-spacerun:yes'>");
211                buf.append(" ");
212                for (int i=0; i < count; i++) {
213                        metaText("&nbsp;");
214                }
215                metaText("</span>");
216        }
217        // -----------------------------------------------------------------------------
218       
219        protected void visitBefore(EtsiBnf node) {
220                parserEtsiBnfNode = NodeUtil.getNodeAdapter(node).getParserNode();
221                collectAllComments(parserEtsiBnfNode);
222                originalText = NodeUtil.getNodeAdapter(node).getParserNode().serialize();
223                originalTextNoWhitespaces = originalText.replaceAll("[ \t\n\r]", "");
224               
225                textTransformed("grammar " + node.getName(),"");
226                if (node.getType() != null)
227                        textTransformed(node.getType(),"");
228                textTransformed(";","");
229                metaText("<body lang=EN-US link=blue vlink=purple style='tab-interval:14.15pt'>\n");
230                metaText("<div class=WordSection1>\n");
231               
232//              newLine();
233//              newLine();
234        }
235       
236        protected void visitAfter(EtsiBnf node) {
237                metaText("</div>\n");
238                metaText("</body>\n");
239                metaText("</html>\n");
240                weaveComments();
241        }
242
243        protected void visitBefore(Import node) {
244                textTransformed("import \"" + node.getImportURI() + "\"","");
245                if (node.getGrammarType() != null) {
246                        textTransformed("/" + node.getGrammarType(), "");
247                }
248                if (node.getLabel() != null) {
249                        space();
250                        textTransformed("label: " + node.getLabel(), "");
251                }
252                textTransformed(";", "");
253//              text("\n");
254        }
255       
256        protected void visitBefore(SectionHeading node) {
257                if (!lastWasSectionHeading && !buf.substring(buf.length()-2).equals("\n\n"))
258                        newLine();
259               
260                lastWasSectionHeading=true;
261               
262                metaText("<h3><span lang=EN-GB>\n");
263                String text = node.getSectionHeader().replaceAll("[\n\r]", "");
264                textTransformed(text, StringEscapeUtils.escapeHtml(text).replaceAll("[\n\r]", ""));
265//              textTransformed(text, text.replaceAll("[\t]", "\\<span style='mso-tab-count:1'\\>"));
266                metaText("\n</span></h3>\n");
267        }
268
269        protected void visitAfter(SectionHeading node) {
270        }
271       
272        protected void visitBefore(RuleReference node) {
273                wrap();
274               
275                metaText("<u><span style='color:blue'><a href=\"#T" + node.getRuleref().getName() + "\">");
276                text(node.getRuleref().getName());
277                metaText("</a></span></u>");
278        }
279
280        protected void visitAfter(RuleReference node) {
281        }
282
283        protected void visitBefore(Rule node) {
284//              if (lastWasSectionHeading)
285                        newLine();
286               
287                lastWasSectionHeading=false;
288
289                newLineOffsetCounter = 0;
290
291                if (node.getRulenumber() > 0)
292                        text(node.getRulenumber() + ". ");
293
294                metaText("<span lang=EN-GB style='mso-no-proof:no'>\n<a name=\"#T" + node.getName() + "\">");
295                textTransformed(node.getName(), node.getName().replaceAll("[ \t\r\n]", ""));
296                metaText("</a>");
297                text(" ::= ");
298               
299                rightHandSideRuleOffset = newLineOffsetCounter;
300                ruleSpacingStack.push(newLineOffsetCounter);
301        }
302       
303        protected void visitAfter(Rule node) {
304                metaText("<o:p></o:p>\n</span>");
305                text(";");
306                newLine();
307                text("\n");
308                ruleSpacingStack.pop();
309        }
310       
311        protected void visitBefore(StringRule node) {
312                wrap();
313                if (node.getLiteral() != null) {
314//                      text("\"" + node.getLiteral() + "\"");
315                        textTransformed("\"" + node.getLiteral() + "\"", StringEscapeUtils.escapeHtml("\"" + node.getLiteral() + "\"").replaceAll("[ \t\n\r]", ""));
316//                      textTransformed("\"" + node.getLiteral() + "\"", "gnabar");
317                } else if (node.getColon() != null) {
318//                      text("\"\"\"");
319                        textTransformed("\"\"\"", StringEscapeUtils.escapeHtml("\"\"\"").replaceAll("[ \t\n\r]", ""));
320//                      textTransformed("\"\"\"", "gnabar");
321                }
322        }
323
324        protected void visitAfter(StringRule node) {
325        }
326}
Note: See TracBrowser for help on using the repository browser.