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

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