Index: jrst2/src/java/org/codelutin/jrst/JRSTReader.java diff -u jrst2/src/java/org/codelutin/jrst/JRSTReader.java:1.34 jrst2/src/java/org/codelutin/jrst/JRSTReader.java:1.35 --- jrst2/src/java/org/codelutin/jrst/JRSTReader.java:1.34 Tue Jun 19 21:24:56 2007 +++ jrst2/src/java/org/codelutin/jrst/JRSTReader.java Wed Jun 20 14:04:03 2007 @@ -23,10 +23,10 @@ * Created: 27 oct. 06 00:15:34 * * @author poussin - * @version $Revision: 1.34 $ + * @version $Revision: 1.35 $ * - * Last update: $Date: 2007/06/19 21:24:56 $ - * by : $Author: bpoussin $ + * Last update: $Date: 2007/06/20 14:04:03 $ + * by : $Author: sletellier $ */ package org.codelutin.jrst; @@ -53,6 +53,7 @@ import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.codelutin.jrst.directive.CalcDirective; import org.codelutin.jrst.directive.ContentDirective; import org.codelutin.jrst.directive.DateDirective; import org.codelutin.jrst.directive.ImageDirective; @@ -280,28 +281,29 @@ protected Map directives = new HashMap(); - private static boolean sectnum = false; + private boolean sectnum = false; private Element footer; - private static int idMax = 0; + private int idMax = 0; - private static int symbolMax = 0; + private int symbolMax = 0; - private static int symbolMaxRef = 0; + private int symbolMaxRef = 0; - private static LinkedList lblFootnotes = new LinkedList(); + private LinkedList lblFootnotes = new LinkedList(); - private static LinkedList lblFootnotesRef = new LinkedList(); + private LinkedList lblFootnotesRef = new LinkedList(); - private static LinkedList eFootnotes = new LinkedList(); + private LinkedList eFootnotes = new LinkedList(); - private static LinkedList eTarget = new LinkedList(); + private LinkedList eTarget = new LinkedList(); - static LinkedList eTargetAnonymous = new LinkedList(); - static LinkedList eTargetAnonymousCopy = new LinkedList(); + private LinkedList eTargetAnonymous = new LinkedList(); - private static LinkedList eTitle = new LinkedList(); + private LinkedList eTargetAnonymousCopy = new LinkedList(); + + private LinkedList eTitle = new LinkedList(); static { defaultDirectives = new HashMap(); @@ -309,6 +311,7 @@ defaultDirectives.put(DATE, new DateDirective()); defaultDirectives.put("time", new DateDirective()); defaultDirectives.put("contents", new ContentDirective()); + defaultDirectives.put("calc", new CalcDirective()); defaultDirectives.put("sectnum", new SectnumDirective()); // TODO put here all other directive } @@ -342,7 +345,7 @@ } /** - * @param defaultDirectives + * @param JRSTDirective * the defaultDirectives to set */ public void addDirectives(String name, JRSTDirective directive) { @@ -362,15 +365,15 @@ JRSTLexer lexer = new JRSTLexer(reader); try { Element root = composeDocument(lexer); - + Document result = DocumentHelper.createDocument(); result.setRootElement(root); root.accept(new VisitorSupport() { - public void visit(Element e) { + public void visit(Element e) { // remove all level attribute e.addAttribute("level", null); - + // Constrution du sommaire String type = e.attributeValue("type"); if (type != null) { if (type.equals("contents")) { @@ -391,7 +394,7 @@ } } }); - + return result; } catch (Exception eee) { log.error(_("JRST parsing error line {0} char {1}:\n{2}", lexer @@ -402,13 +405,27 @@ } /** + *

+ * exemple : + *

+ * + *
+     * ..contents : Sommaire
+     *   depth: 3
+     * 
+ * + *

+ * depth sert a limiter la profondeur du sommaire + *

+ * * @param Element - * e + * */ private void composeContents(Element e) { Element result = DocumentHelper.createElement(TOPIC); String option = e.getText(); int depth = -1; + // depth: 3 Pattern pattern = Pattern.compile("\\s*\\:depth\\:\\s*\\p{Digit}+"); Matcher matcher = pattern.matcher(option); if (matcher.matches()) { @@ -416,22 +433,27 @@ matcher = pattern.matcher(matcher.group()); if (matcher.find()) depth = Integer.parseInt(matcher.group()); - } - int levelInit = 0; + } + int levelInit = 0; try { - levelInit = Integer.parseInt(eTitle.getFirst().attributeValue("level")); + levelInit = Integer.parseInt(eTitle.getFirst().attributeValue( + "level")); } catch (NumberFormatException eee) { - log.error("Can't parse level in: " + eTitle.getFirst().asXML(), eee); + log + .error( + "Can't parse level in: " + + eTitle.getFirst().asXML(), eee); return; } - + LinkedList title = new LinkedList(); + // on rajoute les refid for (int i = 0; i < eTitle.size(); i++) { idMax++; eTitle.get(i).addAttribute("refid", "id" + idMax); } + // on enleve les titres limites par depth for (Element el : eTitle) { - int level = Integer.parseInt(el.attributeValue("level")); level = level - levelInit; el.addAttribute("level", "" + level); @@ -446,7 +468,7 @@ String titleValue = e.attributeValue("value"); e.addAttribute("value", null); String value = titleValue.trim().toLowerCase(); - + // sans titre c "contents" par default if (value.matches("\\s*")) { value = "contents"; titleValue = "Contents"; @@ -454,6 +476,7 @@ e.addAttribute("id", value); e.addAttribute("name", value); result.addElement("title").setText(titleValue); + // on compose les lignes result.add(composeLineContent(title, "")); e.setText(""); e.appendContent(result); @@ -472,12 +495,11 @@ int cnt = 0; while (!title.isEmpty()) { - boolean done = false; Element e = title.getFirst(); int level = Integer.parseInt(e.attributeValue("level")); LinkedList child = new LinkedList(); - if (level <= 0 && !done) { + if (level <= 0) { cnt++; title.removeFirst(); item = result.addElement(LIST_ITEM); @@ -488,7 +510,7 @@ reference.addAttribute("id", id); reference.addAttribute("refid", text.replaceAll("\\W+", " ") .trim().toLowerCase().replaceAll("\\W+", "-")); - //reference.addAttribute("inline", "true"); + // si l'on doit les numeroter if (sectnum) { Element generated = reference.addElement("generated") .addAttribute("class", "sectnum"); @@ -514,8 +536,9 @@ e = title.getFirst(); level = Integer.parseInt(e.attributeValue("level")); } - } while (!title.isEmpty() && level > 0 && !done); + } while (!title.isEmpty() && level > 0); String numTmp = ""; + // numerotation if (sectnum) { numTmp = num + cnt + "."; } @@ -545,6 +568,13 @@ // skip blank line skipBlankLine(lexer); + // les liens anonymes + LinkedList items = lexer.refTarget(); + for (Element e : items) { + eTarget.add(e); + + } + // le header item = lexer.peekHeader(); if (itemEquals(HEADER, item)) { @@ -553,6 +583,7 @@ header.addAttribute("inline", "true").setText(item.getText()); } + // le footer item = lexer.peekFooter(); if (itemEquals(FOOTER, item)) { footer = DocumentHelper.createElement(DECORATION); @@ -560,6 +591,7 @@ header.addAttribute("inline", "true").setText(item.getText()); } + // les hyperlinks LinkedList listItem = lexer.peekTargetAnonymous(); if (listItem != null) { for (Element e : listItem) { @@ -567,13 +599,15 @@ anonym.addAttribute("anonymous", "1"); idMax++; anonym.addAttribute("id", "id" + idMax); - anonym.addAttribute("refuri", e.attributeValue("refuri") - .trim()); + anonym + .addAttribute("refuri", e.attributeValue("refuri") + .trim()); eTargetAnonymous.add(anonym); eTargetAnonymousCopy.add(anonym); } } + // les eléments a enlever (deja parser : header, footer...) item = lexer.peekRemove(); if (itemEquals("remove", item)) lexer.remove(); @@ -615,7 +649,6 @@ // les infos du doc item = lexer.peekDocInfo(); - Element documentinfo = null; while (itemEquals(DOCINFO, item) || itemEquals(FIELD_LIST, item)) { @@ -702,6 +735,7 @@ item = lexer.peekTitle(); } + // on ajoute le footer a la fin if (footer != null) result.add(footer); @@ -709,6 +743,10 @@ } /** + *

+ * skip blank line + *

+ * * @param lexer * @throws DocumentException * @throws IOException @@ -726,6 +764,9 @@ /** * * + *

+ * Corps du document + *

* * @param lexer * @param root @@ -824,7 +865,7 @@ lexer.remove(); Element list = composeTarget(item); parent.add(list); - } else if (itemEquals("targetAnonymous",item)){ + } else if (itemEquals("targetAnonymous", item)) { lexer.remove(); Element list = composeTargetAnonymous(item); parent.add(list); @@ -849,7 +890,7 @@ } // Pour afficher le "PseudoXML" - //if (item!=null) System.out.println(item.asXML()); + // if (item!=null) System.out.println(item.asXML()); item = lexer.peekTitleOrBodyElement(); } @@ -858,6 +899,23 @@ } /** + *

+ * include un document rst + *

+ * + *
+     * .. include:: doc.rst
+     * 
+ * + *

+ * include un document literal (code...) + *

+ * + *
+     * .. include:: literal
+     *       doc.rst
+     * 
+ * * @param item * @return Element * @throws Exception @@ -881,8 +939,8 @@ File fileIn = new File(path); URL url = fileIn.toURL(); Reader in = new InputStreamReader(url.openStream()); - JRSTReader jrst = new JRSTReader(); - Document doc = jrst.read(in); + + Document doc = newJRSTReader(in); result = doc.getRootElement(); } @@ -890,6 +948,12 @@ } /** + *
+     * ..
+     *   So this block is not "lost",
+     *   despite its indentation. 
+     * 
+ * * @param item * @return Element */ @@ -897,26 +961,42 @@ return item; } + /** + *
+     * __ http://truc.html
+     * 
* @param item * @return Element */ private Element composeTargetAnonymous(Element item) { - Element result=null; - result =eTargetAnonymousCopy.getFirst(); + Element result = null; + result = eTargetAnonymousCopy.getFirst(); eTargetAnonymousCopy.removeFirst(); return result; } + /** + *
      * @param item
      * @return Element
      */
     private Element composeTarget(Element item) {
-        eTarget.add(item);
-        return item;
+        Element result = null;
+        for (Element e : eTarget) {
+            if (e.attributeValue("id").equals(item.attributeValue("id"))) {
+                result = e;
+            }
+        }
+        return result;
     }
 
     /**
+     * 
+     * .. [#] This is a footnote
+     * 
* @param item * @return Element * @throws Exception @@ -1002,10 +1082,8 @@ lblFootnotes.add(Integer.parseInt(label)); efootnote.addAttribute("type", type); eFootnotes.add(efootnote); - - JRSTReader reader = new JRSTReader(); String text = footnote.getText(); - Document doc = reader.read(new StringReader(text)); + Document doc = newJRSTReader(new StringReader(text)); result[cnt].appendContent(doc.getRootElement()); cnt++; @@ -1024,6 +1102,10 @@ } /** + *
+     * -a command-line option "a" -1 file, --one=file, --two file Multiple
+     * options with arguments.
+     * 
* @param lexer * @return Element * @throws Exception @@ -1050,17 +1132,23 @@ } } Element description = optionListItem.addElement(DESCRIPTION); - JRSTReader reader = new JRSTReader(); + String text = item.getText(); - Document doc = reader.read(new StringReader(text)); + Document doc = newJRSTReader(new StringReader(text)); description.appendContent(doc.getRootElement()); - + item = lexer.peekOption(); } return result; } /** + *
+     * .. topic:: Title
+     * 
+     *    Body.
+     * 
+ * * @param Element * item * @return Element @@ -1072,17 +1160,22 @@ result = DocumentHelper.createElement(TOPIC); result.addElement(TITLE).addAttribute("inline", "true").setText( item.attributeValue(TITLE)); - JRSTReader reader = new JRSTReader(); String text = item.getText(); - Document doc = reader.read(new StringReader(text)); + Document doc = newJRSTReader(new StringReader(text)); result.appendContent(doc.getRootElement()); - + return result; } /** + *
+     * .. sidebar:: Title
+     *    :subtitle: If Desired
+     *    
+     *    Body.
+     * 
+ * * @param Element - * item * @return Element * @throws Exception */ @@ -1095,15 +1188,21 @@ if (item.attributeValue("subExiste").equals("true")) result.addElement(SUBTITLE).addAttribute("inline", "true").setText( item.attributeValue(SUBTITLE)); - JRSTReader reader = new JRSTReader(); + String text = item.getText(); - Document doc = reader.read(new StringReader(text)); + Document doc = newJRSTReader(new StringReader(text)); result.appendContent(doc.getRootElement()); return result; } /** + *
+     * | line block
+     * |
+     * |    indent
+     * 
+ * * @param lexer * @param item * @return Element @@ -1156,8 +1255,12 @@ } /** + *
+     * >>> print 'this is a Doctest block'
+     * this is a Doctest block
+     * 
+ * * @param Element - * item * @return Element */ private Element composeDoctestBlock(Element item) { @@ -1165,18 +1268,26 @@ } /** + *
+     * As a great paleontologist once said,
+     * 
+     *      This theory, that is mine, is mine.
+     * 
+     *      -- Anne Elk (Miss)
+     * 
+ * * @param Element - * item * @return Element * @throws Exception + * */ private Element composeBlockQuote(Element item) throws Exception { Element result = null; result = DocumentHelper.createElement(BLOCK_QUOTE); - JRSTReader reader = new JRSTReader(); + String text = item.getText(); - Document doc = reader.read(new StringReader(text)); + Document doc = newJRSTReader(new StringReader(text)); result.appendContent(doc.getRootElement()); String sAttribution = item.attributeValue(ATTRIBUTION); if (sAttribution != null) { @@ -1188,10 +1299,16 @@ } /** + *
+     * .. admonition:: And, by the way...
+     * 
+     *      You can make up your own admonition too.
+     * 
+ * * @param Element - * item * @return Element * @throws Exception + * */ private Element composeAdmonition(Element item) throws Exception { Element result = null; @@ -1209,15 +1326,17 @@ } else result = DocumentHelper.createElement(item.attributeValue("type") .toLowerCase()); - JRSTReader reader = new JRSTReader(); + String text = item.getText(); - Document doc = reader.read(new StringReader(text)); + Document doc = newJRSTReader(new StringReader(text)); result.appendContent(doc.getRootElement()); return result; } /** - * @param item + * parse all directives + * + * @param Element * @return Node */ private Node composeDirective(Element item) { @@ -1238,8 +1357,11 @@ } /** + *
+     * .. |biohazard| image:: biohazard.png
+     * 
+ * * @param Element - * item * @return Element */ private Element composeSubstitutionDefinition(Element item) { @@ -1253,9 +1375,35 @@ } /** + *

+ * Complexe Table + *

+ * + *
+     * +------------------------+------------+---------------------+
+     * | body row 3             | Cells may  | - Table cells       |
+     * +------------------------+ span rows. | - contain           |
+     * | body row 4             |            | - body elements.    |
+     * +------------------------+------------+---------------------+
+     * 
+ * + *

+ * And simple table + *

+ * + *
+     * =====  =====  ======
+     *    Inputs     Output
+     * ============  ======
+     *   A      B    A or B
+     * ------------  ------
+     *   A      B    A or B
+     * =====  =====  ======
+     * 
+ * * @param Element - * item * @return Element + * */ @SuppressWarnings("unchecked") private Element composeTable(Element item) throws Exception { @@ -1313,7 +1461,7 @@ JRSTLexer.CELL); for (int c = 0; c < cells.size(); c++) { Element cell = cells.get(c); - // si la cellule a ete utilisé pour un regroupement vertical on + // si la cellule a ete utilise pour un regroupement vertical on // la passe if (!"true".equals(cell.attributeValue("used"))) { Element entry = row.addElement(ENTRY); @@ -1332,7 +1480,7 @@ + JRSTLexer.CELL_INDEX_START + "=" + cellStart + "]"); text += tmpCell.getText(); - // on marque la cellule comme utilisé + // on marque la cellule comme utilise tmpCell.addAttribute("used", "true"); } while (!"true".equals(tmpCell .attributeValue(JRSTLexer.CELL_END))); @@ -1361,8 +1509,7 @@ .valueOf(morecols)); } // parse entry text in table - JRSTReader reader = new JRSTReader(); - Document doc = reader.read(new StringReader(text)); + Document doc = newJRSTReader(new StringReader(text)); entry.appendContent(doc.getRootElement()); } } @@ -1376,6 +1523,17 @@ } /** + *

* items begin with "-", "+", or "*" + *

+ * + *
+     * * aaa
+     *   - bbb
+     * * ccc
+     *   - ddd
+     *      + eee
+     * 
+ * * @param lexer * @return Element * @throws Exception @@ -1400,6 +1558,14 @@ } /** + *
+     * 3. et meme
+     * * #. pour voir
+     * * I) de tout
+     * (a) pour tout
+     * (#) vraiment tout
+     * 
+ * * @param lexer * @return Element * @throws Exception @@ -1432,6 +1598,11 @@ } /** + *
+     * le mot : la classe
+     *   la definition
+     * 
+ * * @param lexer * @return Element * @throws Exception @@ -1472,6 +1643,12 @@ } /** + *
+     * :un peu: de field
+     *      ca ne fait pas
+     *      de mal
+     * 
+ * * @param lexer * @return Element * @throws Exception @@ -1489,6 +1666,13 @@ } /** + *
+     * :field1: avec un
+     *    petit texte 
+     *    - et meme un 
+     *    - debut 
+     *    - de list
+     * 
* @param lexer * @return Element * @throws Exception @@ -1517,6 +1701,11 @@ } /** + *
+     * DEFINITIONS
+     * -----------
+     * 
+ * * @param lexer * @return Element * @throws Exception @@ -1689,6 +1878,47 @@ return result; } + private Document newJRSTReader(Reader r) throws Exception { + JRSTReader reader = new JRSTReader(); + reader.setVariable(idMax, symbolMax, symbolMaxRef, lblFootnotes, + lblFootnotesRef, eFootnotes, eTarget, eTargetAnonymous, + eTargetAnonymousCopy); + + return reader.read(r); + + } + /** + *

+ * Initialises les variables d'environements + * par ex, les hyperlinks peuvent etre referencer dans tous le document + *

+ * @param idMax + * @param symbolMax + * @param symbolMaxRef + * @param lblFootnotes + * @param lblFootnotesRef + * @param eFootnotes + * @param eTarget + * @param eTargetAnonymous + * @param eTargetAnonymousCopy + */ + public void setVariable(int idMax, int symbolMax, int symbolMaxRef, + LinkedList lblFootnotes, + LinkedList lblFootnotesRef, + LinkedList eFootnotes, LinkedList eTarget, + LinkedList eTargetAnonymous, + LinkedList eTargetAnonymousCopy) { + this.idMax = idMax; + this.symbolMax = symbolMax; + this.symbolMaxRef = symbolMaxRef; + this.lblFootnotes = lblFootnotes; + this.lblFootnotesRef = lblFootnotesRef; + this.eFootnotes = eFootnotes; + this.eTarget = eTarget; + this.eTargetAnonymous = eTargetAnonymous; + this.eTargetAnonymousCopy = eTargetAnonymousCopy; + } + /** * Parse text in element and replace text with parse result * @@ -1733,7 +1963,7 @@ text = text.substring(0, start) + "" + key + "" + text.substring(end); matcher = REGEX_INLINE_REFERENCE.matcher(text); - + } // do all substitution inline text = REGEX_EMAIL.matcher(text).replaceAll( @@ -1745,10 +1975,11 @@ "<" + EMPHASIS + ">$1"); text = REGEX_REFERENCE.matcher(text).replaceAll( "<" + REFERENCE + " refuri='$1'>$1$2"); + // _[#]truc matcher = REGEX_FOOTNOTE_REFERENCE.matcher(text); while (matcher.find()) { String txtDebut = text.substring(0, matcher.start()); - String txtFin = text.substring(matcher.end()+1, text.length()); + String txtFin = text.substring(matcher.end() + 1, text.length()); Element footnote = DocumentHelper.createElement(FOOTNOTE_REFERENCE); String sFootnote = matcher.group(); boolean done = false; @@ -1868,6 +2099,7 @@ text = txtDebut + footnote.asXML() + txtFin; matcher = REGEX_FOOTNOTE_REFERENCE.matcher(text); } + // .. __http://truc.html matcher = REGEX_ANONYMOUS_HYPERLINK_REFERENCE.matcher(text); while (matcher.find()) { String txtDebut = text.substring(0, matcher.start()); @@ -1886,13 +2118,13 @@ text = txtDebut + anonym.asXML() + txtFin; matcher = REGEX_ANONYMOUS_HYPERLINK_REFERENCE.matcher(text); } - + // .. _truc: http://truc.html matcher = REGEX_HYPERLINK_REFERENCE.matcher(text); while (matcher.find()) { String txtDebut = text.substring(0, matcher.start()); String txtFin = text.substring(matcher.end(), text.length()); String ref = text.substring(matcher.start(), matcher.end() - 1); - + ref = ref.replaceAll("('|_)", ""); ref = ref.replaceAll("[\\W&&[^-]]", " ").trim(); Element hyper = DocumentHelper.createElement("reference"); @@ -1909,11 +2141,11 @@ if (!trouve) hyper.addAttribute("refid", ref); hyper.setText(ref); - text = txtDebut + hyper.asXML() +" "+ txtFin; + text = txtDebut + hyper.asXML() + " " + txtFin; matcher = REGEX_HYPERLINK_REFERENCE.matcher(text); - + } - + // substitution reference matcher = REGEX_SUBSTITUTION_REFERENCE.matcher(text); int begin = 0; @@ -1934,12 +2166,11 @@ begin = text.length(); text += end; matcher = REGEX_SUBSTITUTION_REFERENCE.matcher(text); - } // undo substitution in LITERAL Pattern p = Pattern.compile("([^<>]+)"); - + matcher = p.matcher(text); while (matcher.find()) { String start = text.substring(0, matcher.start()); @@ -1949,9 +2180,9 @@ text = start + temporaries.get(tempKey) + end; matcher = p.matcher(text); } - Element result = DocumentHelper.parseText("" + text.trim() + "") - .getRootElement(); - + Element result = DocumentHelper.parseText( + "" + text.trim() + "").getRootElement(); + e.setText(""); e.appendContent(result); }