improved settings dialogs
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.wiki / src / net / sourceforge / phpeclipse / wiki / renderer / AbstractContentRenderer.java
1 package net.sourceforge.phpeclipse.wiki.renderer;
2
3 import java.io.IOException;
4 import java.util.StringTokenizer;
5
6 import net.sourceforge.phpeclipse.wiki.editor.WikiEditor;
7 import net.sourceforge.phpeclipse.wiki.editor.WikiEditorPlugin;
8 import net.sourceforge.phpeclipse.wiki.preferences.Util;
9
10 import org.eclipse.core.resources.IProject;
11 import org.eclipse.core.runtime.IPath;
12 import org.eclipse.core.runtime.Path;
13 import org.eclipse.jface.text.BadLocationException;
14 import org.eclipse.jface.text.IDocument;
15
16 public abstract class AbstractContentRenderer implements IContentRenderer {
17   protected IProject fProject;
18
19   public static final String CLASS_MONO_SPACE = "monospace";
20
21   public static final String CLASS_QUOTE = "quote";
22
23   public static final String TABLE_DELIMETER = "|";
24
25   public static final String HR = "hr";
26
27   public static final String NEW_WIKIDOC_HREF = "?";
28
29   public static final String WIKI_HREF = "http://--wiki/";
30
31   public static final String[][] REPLACE_TEXT = new String[][] { { "<", "&lt;" }, { "\"", "&quot;" } };
32
33   private WikiEditor editor;
34
35   protected StringBuffer buffer;
36
37   private int currentLine;
38
39   private int currentListDepth;
40
41   private boolean inTable;
42
43   private void setEditor(WikiEditor editor) {
44     this.editor = editor;
45   }
46
47   protected StringBuffer getBuffer() {
48     return buffer;
49   }
50
51   protected WikiEditor getEditor() {
52     return editor;
53   }
54
55   //  public void render(String content, StringBuffer buf) {
56   //    try {
57   //      buffer = buf;
58   //      appendHeader();
59   //
60   //      int index = 0;
61   //      int startIndex = 0;
62   //      String line;
63   //      while (index < content.length()) {
64   //        if (content.charAt(index++) == '\n') {
65   //          line = content.substring(startIndex, index);
66   //          startIndex = index;
67   //          appendLine(line);
68   //
69   //        }
70   //        index++;
71   //      }
72   //      if (startIndex < content.length()) {
73   //        line = content.substring(startIndex, content.length());
74   //        renderLine(line);
75   //      }
76   //      appendFooter();
77   //      // return buffer.toString();
78   //    } catch (Exception e) {
79   //      WikiEditorPlugin.getDefault().log(buffer.toString());
80   //      WikiEditorPlugin.getDefault().log(e.getLocalizedMessage(), e);
81   //      // return "<html><body><p>" + e.getLocalizedMessage() +
82   //      // "</p></body></html>";
83   //    }
84   //  }
85
86   //  protected void renderLine(String line) {
87   //    if (isHeader(line)) {
88   //      appendHeader(line);
89   //    } else if (isList(line)) {
90   //      appendListItem(line);
91   //    } else if (tableLine(line)) {
92   //      processTable(line);
93   //    } else if (process(line)) {
94   //      return;
95   //    } else {
96   //      buffer.append(line);
97   //    }
98   //  }
99
100   //  public final String render(WikiEditor editor) {
101   //    initialise(editor);
102   //    try {
103   //      buffer = new StringBuffer();
104   //      appendHeader();
105   //      buffer.append("<h1>").append(editor.getWikiNameBeingEdited()).append("</h1>");
106   //      appendContents();
107   //      appendFooter();
108   //      return buffer.toString();
109   //    } catch (Exception e) {
110   //      WikiEditorPlugin.getDefault().log(buffer.toString());
111   //      WikiEditorPlugin.getDefault().log(e.getLocalizedMessage(), e);
112   //      return "<html><body><p>" + e.getLocalizedMessage() + "</p></body></html>";
113   //    }
114   //  }
115
116   private void initialise(WikiEditor editor) {
117     setEditor(editor);
118     currentListDepth = 0;
119     inTable = false;
120     initialise();
121   }
122
123   protected abstract void initialise();
124
125   protected void appendHeader() throws IOException {
126     buffer.append("<html><head>");
127     //    String basePath = Util.getMiscProjectsPreferenceValue(fProject, WikiConstants.HTML_OUTPUT_PATH);
128     //    buffer.append("<base href=\"" + basePath + "/" + fProject.getName() + "\"/>");
129
130     //    if (WikiEditorPlugin.getDefault().getPluginPreferences().contains(WikiConstants.BROWSER_CSS_URL)) {
131     //      buffer.append("<link href=\"")
132     //          .append(WikiEditorPlugin.getDefault().getPluginPreferences().getString(WikiConstants.BROWSER_CSS_URL)).append(
133     //              "\" fType=\"text/css\" rel=\"STYLESHEET\">");
134     //    }
135     //    appendStyle();
136
137     buffer.append("</head><body>\n");
138   }
139
140   private void appendContents() {
141     IDocument document = editor.getDocument();
142     currentLine = 0;
143     while (currentLine < document.getNumberOfLines()) {
144       String line = getLine(document, currentLine);
145       //      appendLine(line);
146       currentLine++;
147     }
148   }
149
150   protected void appendNewLine() {
151     getBuffer().append(System.getProperty("line.separator"));
152   }
153
154   //  protected String getNextLine() {
155   //    if (hasLine(currentLine + 1)) {
156   //      currentLine++;
157   //      return getLine(editor.getDocument(), currentLine);
158   //    }
159   //    throw new RuntimeException("Should not be called if there is no next line.");
160   //  }
161
162   //  protected String peekNextLine() {
163   //    if (hasLine(currentLine + 1)) {
164   //      return getLine(editor.getDocument(), currentLine + 1);
165   //    }
166   //    return "";
167   //  }
168
169   protected boolean hasNextLine() {
170     return hasLine(currentLine + 1);
171   }
172
173   private boolean hasLine(int lineNumber) {
174     return lineNumber < editor.getDocument().getNumberOfLines();
175   }
176
177   protected void appendFooter() {
178     buffer.append("\n</body></html>");
179   }
180
181   //  protected void appendStyle() throws IOException {
182   //    buffer.append("<style fType=\"text/css\"><!--");
183   //    IPath path = new Path("style").append(RendererFactory.getContentRendererName() + ".css");
184   //    buffer.append(WikiEditorPlugin.getDefault().loadTextContents(path));
185   //    buffer.append("--></style>");
186   //  }
187   //
188   //  protected void appendLine(String line) {
189   //    if (isHeader(line)) {
190   //      appendHeader(line);
191   //    } else if (isList(line)) {
192   //      appendListItem(line);
193   //    } else if (tableLine(line)) {
194   //      processTable(line);
195   //    } else if (process(line)) {
196   //      return;
197   //    } else {
198   //      buffer.append("<p>");
199   //      append(processTags(line));
200   //      buffer.append("</p>");
201   //    }
202   //  }
203
204   //  private final void appendListItem(String line) {
205   //    int bullet = getListDepth(line);
206   //    if (bullet > currentListDepth) {
207   //      repeatAppend("<ul>", bullet - currentListDepth);
208   //      currentListDepth = bullet;
209   //    } else if (bullet < currentListDepth) {
210   //      repeatAppend("</ul>", currentListDepth - bullet);
211   //      currentListDepth = bullet;
212   //    }
213   //    getBuffer().append("<li>");
214   //    String content = "";
215   //    if (bullet < line.length() - 1) {
216   //      content = getListtext(line);
217   //    }
218   //    append(processTags(content));
219   //    getBuffer().append("</li>");
220   //    if (!isList(peekNextLine())) {
221   //      repeatAppend("</ul>", currentListDepth);
222   //      currentListDepth = 0;
223   //    }
224   //  }
225
226   protected abstract String getListtext(String line);
227
228   protected void repeatAppend(String item, int n) {
229     for (int i = 0; i < n; i++) {
230       getBuffer().append(item);
231     }
232   }
233
234   protected abstract int getListDepth(String line);
235
236   protected abstract String processTags(String line);
237
238   private String getLine(IDocument document, int n) {
239     try {
240       String line = document.get(document.getLineOffset(n), document.getLineLength(n));
241       if (document.getLineDelimiter(n) != null) {
242         line = line.substring(0, line.length() - document.getLineDelimiter(n).length());
243       }
244       for (int i = 0; i < REPLACE_TEXT.length; i++) {
245         line = line.replaceAll(REPLACE_TEXT[i][0], REPLACE_TEXT[i][1]);
246       }
247       return line;
248     } catch (BadLocationException e) {
249       WikiEditorPlugin.getDefault().logAndReport("Error", e.getLocalizedMessage(), e);
250       return e.getLocalizedMessage();
251     }
252   }
253
254   //  protected void append(String line) {
255   //    TextRegion[] regions = TextRegionBuilder.getTextRegions(line, editor);
256   //    for (int i = 0; i < regions.length; i++) {
257   //      regions[i].accept(new TextRegionVisitor() {
258   //        public Object visit(UndefinedTextRegion undefinedTextRegion) {
259   //          buffer.append(undefinedTextRegion.getText());
260   //          return null;
261   //        }
262   //
263   //        public Object visit(UrlTextRegion urlTextRegion) {
264   //          appendLink(urlTextRegion.getText(), urlTextRegion.getText());
265   //          return null;
266   //        }
267   //
268   //        public Object visit(WikiNameTextRegion wikiNameTextRegion) {
269   //          if (editor.hasWikiSibling(wikiNameTextRegion)) {
270   //            appendLink(AbstractContentRenderer.WIKI_HREF + wikiNameTextRegion.getText(), wikiNameTextRegion.getText());
271   //          } else {
272   //            buffer.append(wikiNameTextRegion.getText());
273   //            appendLink(AbstractContentRenderer.WIKI_HREF + wikiNameTextRegion.getText(), AbstractContentRenderer.NEW_WIKIDOC_HREF);
274   //          }
275   //          return null;
276   //        }
277   //
278   //        public Object visit(WikiUrlTextRegion wikiUrlTextRegion) {
279   //          String link;
280   //          if (wikiUrlTextRegion.getLink().startsWith(WikiConstants.ECLIPSE_PREFIX)) {
281   //            link = AbstractContentRenderer.WIKI_HREF + wikiUrlTextRegion.getLink();
282   //          } else {
283   //            link = wikiUrlTextRegion.getLink();
284   //          }
285   //          appendLink(link, wikiUrlTextRegion.getText());
286   //          return null;
287   //        }
288   //
289   //        public Object visit(BasicTextRegion basicTextRegion) {
290   //          buffer.append(basicTextRegion.getText());
291   //          return null;
292   //        }
293   //
294   //        public Object visit(EclipseResourceTextRegion eclipseResourceTextRegion) {
295   //          appendLink(AbstractContentRenderer.WIKI_HREF + eclipseResourceTextRegion.getText(), eclipseResourceTextRegion.getText());
296   //          return null;
297   //        }
298   //
299   //        public Object visit(JavaTypeTextRegion region) {
300   //          try {
301   //            if (region.getType().getUnderlyingResource() != null) {
302   //              String url = AbstractContentRenderer.WIKI_HREF + WikiConstants.ECLIPSE_PREFIX
303   //                  + region.getType().getUnderlyingResource().getFullPath().toString();
304   //              appendLink(url, region.getText());
305   //            } else {
306   //              append(region.getText());
307   //            }
308   //          } catch (JavaModelException e) {
309   //            WikiPlugin.getDefault().logAndReport("Error", e.getLocalizedMessage(), e);
310   //          }
311   //          return null;
312   //        }
313   //
314   //      });
315   //    }
316   //  }
317
318   protected void appendLink(String url, String text) {
319     buffer.append("<a href=\"").append(url).append("\">").append(text).append("</a>");
320   }
321
322   protected abstract boolean isHeader(String line);
323
324   protected abstract void appendHeader(String line);
325
326   protected abstract boolean isList(String line);
327
328   /**
329    * Gives implementors a chance to do processing on this line.
330    * 
331    * @return if true, the line will not be processed further
332    */
333   protected abstract boolean process(String line);
334
335   /**
336    * Replace all occurrences of markeup which occurs in pairs with an opening and closing tag in the given line. e.g.
337    * 
338    * <pre>
339    * 
340    *  
341    *   
342    *    
343    *     
344    *          replacePair(&quot;my ''bold'' word&quot;, &quot;''&quot;, &quot;&lt;b&gt;&quot;, &quot;,&lt;/b&gt;&quot;) returns &quot;my &lt;b&gt;bold&lt;/b&gt; word&quot;
345    *      
346    *     
347    *    
348    *   
349    *  
350    * </pre>
351    */
352   protected String replacePair(String line, String search, String openingTag, String closingTag) {
353     StringBuffer buffer = new StringBuffer();
354     String[] foo = line.split(search);
355     for (int i = 0; i < foo.length; i++) {
356       if (i % 2 == 1) {
357         buffer.append(openingTag).append(foo[i]).append(closingTag);
358       } else {
359         buffer.append(foo[i]);
360       }
361     }
362     return buffer.toString();
363   }
364
365   protected void appendHR() {
366     getBuffer().append("<hr>");
367   }
368
369   private boolean tableLine(String line) {
370     return line.startsWith(AbstractContentRenderer.TABLE_DELIMETER);
371   }
372
373   //  private void processTable(String line) {
374   //    if (!inTable) {
375   //      inTable = true;
376   //      getBuffer().append(getTableTag());
377   //    }
378   //    getBuffer().append("<tr>");
379   //    StringTokenizer tokenizer = new StringTokenizer(line, AbstractContentRenderer.TABLE_DELIMETER);
380   //    while (tokenizer.hasMoreTokens()) {
381   //      String cell = tokenizer.nextToken();
382   //      String element = "td";
383   //      if (cell.trim().startsWith("*")) {
384   //        element = "th";
385   //        cell = cell.replaceAll("\\*", "");
386   //      }
387   //      getBuffer().append("<").append(element).append(">");
388   //      append(processTags(cell));
389   //      getBuffer().append("</").append(element).append(">");
390   //    }
391   //    getBuffer().append("</tr>");
392   //    if (!tableLine(peekNextLine())) {
393   //      getBuffer().append("</table>");
394   //      inTable = false;
395   //    }
396   //  }
397
398   /**
399    * @return the tag for table (can be overridden to add style)
400    */
401   protected String getTableTag() {
402     return "<table>";
403   }
404
405   public void forEachHeader(IDocument document, StructureClosure closure) throws BadLocationException {
406     for (int i = 0; i < document.getNumberOfLines(); i++) {
407       String line = getLine(document, i);
408       if (isHeader(line)) {
409         String header = getHeaderText(line);
410         closure.acceptHeader(header, document.getLineOffset(i));
411       }
412     }
413   }
414
415   /**
416    * Get the header from a line with header markup
417    * 
418    * @param line
419    *          guaranteed to be a valid header as defined by b {@link #isHeader(String) isHeader(String)}
420    */
421   protected abstract String getHeaderText(String line);
422
423   /**
424    * @param project
425    *          The fProject to set.
426    */
427   public void setProject(IProject project) {
428     fProject = project;
429   }
430 }