@Override
 public void beginHeader(int level, WikiParameters params) {
   beginElement();
   super.beginHeader(level, params);
   if (toc != null) {
     String id = toc.addHeading(null, level); // we don't know the title yet
     print("<a name=\"heading_" + id + "\">");
     mark = writer.getBuffer().length();
   }
 }
 @Override
 public void endPropertyBlock(String propertyUri, boolean doc) {
   endElement();
   if (propertyUri.startsWith("block:")) {
     writer = writer.getParent();
     if (writer == null) {
       throw new IllegalStateException("block macro underflow");
     }
   } else {
     super.endPropertyBlock(propertyUri, doc);
   }
 }
 @Override
 public void beginPropertyBlock(String propertyUri, boolean doc) {
   beginElement();
   if (propertyUri.startsWith("block:")) {
     String name = propertyUri.substring(6);
     WikiBlockWriter bwriter = new WikiBlockWriter(writer, name);
     writer.writeText(bwriter);
     writer = bwriter;
   } else {
     super.beginPropertyBlock(propertyUri, doc);
   }
 }
 @Override
 public void endHeader(int level, WikiParameters params) {
   if (toc != null) {
     if (mark == -1) {
       throw new IllegalStateException("marker was not set");
     }
     toc.tail.title = writer.getBuffer().substring(mark);
     mark = -1;
     print("</a>");
     super.endHeader(level, params);
   } else {
     super.endHeader(level, params);
   }
   endElement();
 }
 @Override
 protected void println(String str) {
   writer.println(str);
 }
 @Override
 protected void println() {
   writer.println();
 }