/*=============================================================================# # Copyright (c) 2014-2016 Stephan Wahlbrink (WalWare.de) and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v10.html # # Contributors: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.docmlet.wikitext.core.source; import java.io.IOException; import java.io.Writer; import org.eclipse.mylyn.wikitext.core.parser.Attributes; import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder; import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage; public class MarkupEventPrinter extends DocumentBuilder { private final Writer out; private int depth; private MarkupLanguage markupLanguage; private String text; public MarkupEventPrinter(final Writer out) { this.out= out; } public MarkupEventPrinter(final String text, final MarkupLanguage markupLanguage, final Writer out) { this.out= out; reset(text, markupLanguage); } public void reset(final String text, final MarkupLanguage markupLanguage) { this.text= text; this.markupLanguage= markupLanguage; } protected void printIndent(final int depth) throws IOException { for (int i= 0; i < depth; i++) { this.out.write(" "); //$NON-NLS-1$ } } protected void header() { try { this.out.append("==== Document Events ("); //$NON-NLS-1$ if (this.markupLanguage != null) { this.out.append("language= "); //$NON-NLS-1$ this.out.append(this.markupLanguage.getName()); this.out.append(", "); //$NON-NLS-1$ } this.out.append("textLength= "); //$NON-NLS-1$ this.out.append(Integer.toString(this.text.length())); this.out.append(") ====\n"); //$NON-NLS-1$ } catch (final IOException e) { throw new RuntimeException(e); } } protected void footer() { try { this.out.append("====\n"); //$NON-NLS-1$ } catch (final IOException e) { throw new RuntimeException(e); } } protected void printBegin(final int beginOffset) throws IOException { if (beginOffset < 0 || beginOffset > this.text.length()) { this.out.append("<out-of-range>"); //$NON-NLS-1$ return; } this.out.append(this.text.substring(beginOffset, Math.min(beginOffset + 8, this.text.length()))); this.out.append(" ..."); //$NON-NLS-1$ } protected void printEnd(final int endOffset) throws IOException { if (endOffset < 0 || endOffset > this.text.length()) { this.out.append("<out-of-range>"); //$NON-NLS-1$ return; } this.out.append("... "); //$NON-NLS-1$ writeEncoded(this.text, Math.max(endOffset - 8, 0), endOffset); } private void writeEncoded(final String s, final int begin, final int end) throws IOException { for (int i= begin; i < end; i++) { final int c= s.charAt(i); if (c < 0x10) { this.out.write("<0x0"); //$NON-NLS-1$ this.out.write(Integer.toHexString(c)); this.out.write('>'); } else if (c < 0x20) { this.out.write("<0x"); //$NON-NLS-1$ this.out.write(Integer.toHexString(c)); this.out.write('>'); } else { this.out.write(c); } } } private void begin(final String label) { try { printIndent(this.depth); final int beginOffset= this.locator.getDocumentOffset(); final int endOffset= this.locator.getLineDocumentOffset() + this.locator.getLineSegmentEndOffset(); this.out.append("["); //$NON-NLS-1$ this.out.append(Integer.toString(beginOffset)); this.out.append(", "); //$NON-NLS-1$ this.out.append(Integer.toString(endOffset)); this.out.append(") "); //$NON-NLS-1$ this.out.append("begin"); //$NON-NLS-1$ this.out.append(label); this.out.append(": "); //$NON-NLS-1$ printBegin(beginOffset); this.out.append('\n'); } catch (final IOException e) { throw new RuntimeException(e); } finally { this.depth++; } } private void end(final String label) { try { this.depth--; printIndent(this.depth); final int beginOffset= this.locator.getDocumentOffset(); final int endOffset= this.locator.getLineDocumentOffset() + this.locator.getLineSegmentEndOffset(); this.out.append("["); //$NON-NLS-1$ this.out.append(Integer.toString(beginOffset)); this.out.append(", "); //$NON-NLS-1$ this.out.append(Integer.toString(endOffset)); this.out.append(") "); //$NON-NLS-1$ this.out.append("end"); //$NON-NLS-1$ this.out.append(label); this.out.append(": "); //$NON-NLS-1$ printEnd(endOffset); this.out.append('\n'); } catch (final IOException e) { throw new RuntimeException(e); } } private void terminal(final String label) { try { printIndent(this.depth); final int beginOffset= this.locator.getDocumentOffset(); final int endOffset= this.locator.getLineDocumentOffset() + this.locator.getLineSegmentEndOffset(); this.out.append("["); //$NON-NLS-1$ this.out.append(Integer.toString(beginOffset)); this.out.append(", "); //$NON-NLS-1$ this.out.append(Integer.toString(endOffset)); this.out.append(") "); //$NON-NLS-1$ this.out.append(label); this.out.append(": "); //$NON-NLS-1$ // printEnd(endOffset); this.out.append('\n'); } catch (final IOException e) { throw new RuntimeException(e); } } @Override public void beginDocument() { header(); begin("Document"); //$NON-NLS-1$ } @Override public void endDocument() { end("Document"); //$NON-NLS-1$ footer(); } @Override public void beginBlock(final BlockType type, final Attributes attributes) { begin("Block(" + type + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } @Override public void endBlock() { end("Block"); //$NON-NLS-1$ } @Override public void beginSpan(final SpanType type, final Attributes attributes) { begin("Span(" + type + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } @Override public void endSpan() { end("Span"); //$NON-NLS-1$ } @Override public void beginHeading(final int level, final Attributes attributes) { begin("Heading"); //$NON-NLS-1$ } @Override public void endHeading() { end("Heading"); //$NON-NLS-1$ } @Override public void characters(final String text) { terminal("characters"); //$NON-NLS-1$ } @Override public void entityReference(final String entity) { terminal("entityReference"); //$NON-NLS-1$ } @Override public void image(final Attributes attributes, final String url) { terminal("image"); //$NON-NLS-1$ } @Override public void link(final Attributes attributes, final String hrefOrHashName, final String text) { terminal("link"); //$NON-NLS-1$ } @Override public void imageLink(final Attributes linkAttributes, final Attributes imageAttributes, final String href, final String imageUrl) { terminal("imageLink"); //$NON-NLS-1$ } @Override public void acronym(final String text, final String definition) { terminal("acronym"); //$NON-NLS-1$ } @Override public void lineBreak() { terminal("lineBreak"); //$NON-NLS-1$ } @Override public void charactersUnescaped(final String literal) { terminal("charactersUnescaped"); //$NON-NLS-1$ } }