Kawai Wiki

Rev

Rev 90 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package org.kawai.tag;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.jsp.JspException;

import org.kawai.model.Page;
import org.mentaregex.Regex;
import org.mentawai.tag.util.PrintTag;

public class KawaiTagInterpreter extends PrintTag {
       
        private static final Map<String, String> EMPTY_MAP = new HashMap<String, String>();
       
        private String name;
       
        public void setName(String name) {
                this.name = name;
        }
       
        @Override
        public String getStringToPrint() throws JspException {
               
                Page page = (Page) pageContext.findAttribute(name);
                if (page == null) {
                        throw new JspException("Cannot find page with name: " + name);
                }
               
                String body = page.getBody();
               
                body = translateContextPath(body);
                body = translateCodeBlock(body);
               
                return body;
        }
       
        private String escapeSlash(String s) {
                if (s.contains("/")) {
                        s = Regex.escapeSlash(s, "\\\\");
                }
                return s;
        }
       
        private String translateContextPath(String body) {
                String cp = req.getContextPath();
                cp = escapeSlash(cp);
                return Regex.sub(body, "s/\\[contextPath\\/\\]/" + cp + "/g");
        }
       
        private static String[] splitCodeBlock(String s) {
                int start = s.indexOf("[code");
                if (start == -1) return null;
                int closingBracketIndex = s.indexOf("]", start);
                if (closingBracketIndex == -1) return null;
                int end = s.indexOf("[/code]");
                if (end > start) {
                        String part1 = "";
                        if (start > 0) {
                                part1 = s.substring(0, start);
                        }
                        String part2 = "";
                        if (end < s.length() - "[/code]".length() - 1) {
                                part2 = s.substring(end + "[/code]".length(), s.length());
                        }
                        String contents = "";
                        int contentsStart = s.indexOf("]", start) + 1;
                        int contentsEnd = end;
                        if (contentsEnd > contentsStart) {
                                contents = s.substring(contentsStart, contentsEnd);
                        }
                        String tagAttributes = "";
                        if (closingBracketIndex > start + "[code".length()) {
                                tagAttributes = s.substring(start + "[code".length(), closingBracketIndex).trim();
                        }
                       
                        return new String[] { tagAttributes, part1, contents, part2 };
                }
                return null;
        }
       
        private static Map<String, String> parseAttributes(String attrs) {
                if (attrs.equals("")) return EMPTY_MAP;
                Map<String, String> map = new HashMap<String, String>();
                String[] temp = attrs.split(" +");
                for(String s : temp) {
                        String[] temp2 = s.split("\\=");
                        if (temp2[1].startsWith("\"") && temp2[1].endsWith("\"")) {
                                map.put(temp2[0], temp2[1].substring(1, temp2[1].length() - 1));
                        } else {
                                map.put(temp2[0], temp2[1]);
                        }
                }
                return map;
        }
       
        private static String buildOpenShTag(Map<String, String> map) {
                StringBuilder sb = new StringBuilder(256);
                sb.append("<pre class=\"");
                if (map.containsKey("brush")) {
                        sb.append("brush: ").append(map.get("brush")).append(";");
                } else {
                        sb.append("brush: java;");
                }
                map.remove("brush");
                if (map.containsKey("highlight")) {
                        sb.append(" highlight: [").append(map.get("highlight")).append("];");
                }
                map.remove("highlight");
                Iterator<String> iter = map.keySet().iterator();
                while(iter.hasNext()) {
                        String name = iter.next();
                        if (name.equals("ul")) continue;
                        String value = map.get(name);
                        sb.append(" ").append(name).append(": ").append(value).append(";");
                }
                sb.append("\">");
                return sb.toString();
        }
       
        private static String translateCodeBlock(String body) {
                String[] parts = splitCodeBlock(body);
                if (parts == null) return body;
                StringBuilder sb = new StringBuilder(1024 * 10);
                sb.append(parts[1]);
                Map<String, String> attrs = parseAttributes(parts[0]);

                boolean indent = true;
               
                if (attrs.containsKey("ul")) {
                        indent = attrs.get("ul").equals("true");
                }

                if (indent) sb.append("<ul>");
                sb.append(buildOpenShTag(attrs));
                sb.append(parts[2]);
                sb.append("</pre>");
                if (indent) sb.append("</ul>");
                sb.append(parts[3]);
                return translateCodeBlock(sb.toString());
        }
       
        public static void main(String[] args) {
               
                String x1 = "house";
                String x2 = "home";
               
                String s = "aaaaaa [code a=\"asfadf\" bbb=\"asfasfffff\"]" + x1 + "[/code] bbbbb [code ]" + x2 + "[/code] cccccccccccc";
               
                String[] blocks = splitCodeBlock(s);
               
                for(String x : blocks) System.out.println("{" + x + "}");
               
                blocks = splitCodeBlock(blocks[3]);
               
                for(String x : blocks) System.out.println("{" + x + "}");
               
                System.out.println(translateCodeBlock(s));
               
        }
}