Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * #%L
    * JRst :: Api
    * 
    * $Id: JRSTLexer.java 601 2011-06-09 16:31:45Z kcardineaud $
    * $HeadURL: http://svn.nuiton.org/svn/jrst/tags/jrst-1.4/jrst/src/main/java/org/nuiton/jrst/JRSTLexer.java $
    * %%
    * Copyright (C) 2004 - 2010 CodeLutin
    * %%
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as 
   * published by the Free Software Foundation, either version 3 of the 
   * License, or (at your option) any later version.
   * 
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Lesser Public License for more details.
   * 
   * You should have received a copy of the GNU General Lesser Public 
   * License along with this program.  If not, see
   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
   * #L%
   */
  
  package org.nuiton.jrst;
  
  import static org.nuiton.jrst.ReStructuredText.BLOCK_QUOTE;
  
  import org.dom4j.Element;
  
  import java.io.Reader;
  import java.util.List;
Le principe est de positionner la mark du AdvancedReader lors du debut d'une methode peek*, puis a la fin de la methode de regarder le nombre de caractere utilisé pour la methode et de faire un reset.

Le nombre de caractere utilisé servira pour le remove lorsque l'utilisateur indiquera qu'il utilise l'element retourné, si l'utilisateur n'appelle pas remove alors il peut relire autant de fois qu'il veut le meme element, ou essayer d'en lire un autre.

Pour mettre en place ce mecanisme le plus simple est d'utiliser les methodes beginPeek() et endPeek() Created: 28 oct. 06 00:44:20

Author(s):
poussin, letellier
Version:
$Revision: 601 $ Last update: $Date: 2011-06-09 18:31:45 +0200 (Thu, 09 Jun 2011) $ by : $Author: kcardineaud $
  
  public class JRSTLexer {

    
to use log facility, just put in your code: log.info(\"...\");
  
      private static Log log = LogFactory.getLog(JRSTLexer.class);
  
      public static final String BULLET_CHAR = "*" + "+" + "-"/*
                                                                   * + "\u2022" +
                                                                   * "\u2023" +
                                                                   * "\u2043"
                                                                   */;
  
      public static final String TITLE_CHAR = "-=-~'`^+:!\"#$%&*,./;|?@\\_[\\]{}<>()";
  
      public static final String DOCINFO_ITEM = "author|authors|organization|address|contact|version|revision|status|date|copyright";
  
      public static final String ADMONITION_PATTERN = "admonition|attention|caution|danger|error|hint|important|note|tip|warning";
  
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      // Title Elements
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
      public static final String TITLE = "title";
  
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      // Bibliographic Elements
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
      public static final String DOCINFO = "docinfo";
  
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      // Decoration Elements
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
      public static final String DECORATION = "decoration";
  
     public static final String HEADER = "header";
 
     public static final String FOOTER = "footer";
 
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     // Structural Elements
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
     public static final String TRANSITION = "transition";
 
     public static final String SIDEBAR = "sidebar";
 
     public static final String TOPIC = "topic";
 
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     // Body Elements
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
     static final public String LITERAL_BLOCK = "literal_block";
 
     static final public String PARAGRAPH = "paragraph";
 
     static final public String BLANK_LINE = "blankLine";
     
     static final public String COMMENT = "comment";
 
     static final public String SUBSTITUTION_DEFINITION = "substitution_definition";
 
     static final public String BULLET_LIST = "bullet_list";
 
     static final public String FIELD_LIST = "field_list";
 
     static final public String DEFINITION_LIST = "definition_list";
 
     static final public String ENUMERATED_LIST = "enumerated_list";
 
     static final public String OPTION_LIST = "option_list";
 
     public static final String LINE_BLOCK = "line_block";
 
     public static final String LINE = "line";
 
     public static final String ATTRIBUTION = "attribution";
 
     public static final String DOCTEST_BLOCK = "doctest_block";
 
     public static final String ADMONITION = "admonition";
 
     public static final String TARGET = "target";
 
     public static final String FOOTNOTE = "footnote";
     
     public static final String FOOTNOTES = "footnotes";
     
     public static final String LEVEL = "level";
     
     public static final String TARGETANONYMOUS = "targetAnonymous";
     
 
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     // Table Elements
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
     static final public String TABLE = "table";
 
     static final public String ROW = "row";
 
     static final public String CELL = "cell";
 
     static final public String TABLE_HEADER = "header";
 
     static final public String TABLE_WIDTH = "width";
 
     static final public String ROW_END_HEADER = "endHeader";
 
     static final public String CELL_INDEX_START = "indexStart";
 
     static final public String CELL_INDEX_END = "indexEnd";
 
     static final public String CELL_BEGIN = "begin";
 
     static final public String CELL_END = "end";
     
     static final public String REMOVE = "remove";
 
     static final public String INCLUDE = "include";
     
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     // Directive Elements
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
     static final public String DIRECTIVE = "directive";
 
     static final public String DIRECTIVE_TYPE = "type";
 
     static final public String DIRECTIVE_VALUE = "value";
     
     
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     // Attributs
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     
     static final public String AUTONUM = "autoNum";
     
     static final public String AUTONUMLABEL = "autoNumLabel";
     
     static final public String AUTOSYMBOL = "autoSymbol";
     
     static final public String BULLET = "bullet";
     
     static final public String CHAR = "char";
     
     static final public String ID = "id";
     
     static final public String CLASSIFIERS = "classifiers";
     
     static final public String DELIMITER = "delimiter";
     
     static final public String DELIMITEREXISTE ="delimiterExiste";
     
     static final public String ENUMTYPE = "enumtype";
     
     static final public String REFURI = "refuri";
     
     static final public String OPTION = "option";
     
     static final public String LITERAL = "literal";
     
     static final public String NAME = "name";
     
     static final public String NUM ="num";
     
     static final public String OPTIONARGUMENT = "option_argument";
     
     static final public String OPTIONSTRING = "option_string";
     
     static final public String PREFIX = "prefix";
     
     static final public String START = "start";
     
     static final public String SUBEXISTE = "subExiste";
     
     static final public String SUFFIX = "suffix";
         
     static final public String SUBTITLE = "subtitle";
     
     static final public String TERM = "term";
     
     static final public String TITLEATTR = "title";
     
     static final public String XMLSPACE = "xml:space";
     
     static final public String TYPE = "type";
     
 
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     
     protected static final String TRUE = "true";
     
     protected static final String FALSE = "false";
    
    
    
retient le niveau du titre, pour un titre de type double, on met deux fois le caratere dans la chaine, sinon on le met une seul fois.
 =====
 Super
 =====
 titre
 -----
 
donnera dans la liste ["==", "-"]
 
     private List<StringtitleLevels;
 
     private AdvancedReader in;

    
length of the last element returned (number of char need to this element)
 
     private int elementLength;
     
     
     
 
     public JRSTLexer(Reader reader) {
          = new ArrayList<String>();
          = new AdvancedReader(reader);
     }

    
true if no more element to read

Returns:
boolean
Throws:
java.io.IOException
 
     public boolean eof() throws IOException {
         .mark();
         .skipBlankLines();
         boolean result = .eof();
         .reset();
         return result;
     }

    
remove one element from list of element already read

 
     public void remove() throws IOException {
         .skip();
     }

    
start peek

 
     private void beginPeek() throws IOException {
          = 0;
         .mark();
     }

    
end peek

 
     private void endPeek() throws IOException {
          = .readSinceMark();
         .reset();
     }

    
Read block text, block text have same indentation and is continu (no blank line)

Parameters:
minLeftMargin min left blank needed to accept to read block
Returns:
String[]
Throws:
java.io.IOException
 
     private String[] readBlock(int minLeftMarginthrows IOException {
         String[] result = new String[0];
         String firstLine = .readLine();
         if (firstLine != null) {
             .unread(firstLinetrue);
             int level = level(firstLine);
             if (level >= minLeftMargin) {
                 result = .readWhile("^\\s{" + level + "}\\S+.*");
             }
         }
 
         return result;
     }

    
All lines are joined and left and right spaces are removed during join

Parameters:
String [] lines
Returns:
String
 
     private String joinBlock(String[] lines) {
         String result = joinBlock(lines" "true);
         return result;
     }

    
All lines are joined whith the String joinSep and left and right spaces are removed if trim

Parameters:
String [] lines
String joinSep
Boolean trim
Returns:
String
 
     private String joinBlock(String[] linesString joinSepboolean trim) {
         String result = "";
         String sep = "";
         for (String line : lines) {
             if (trim) {
                 line = line.trim();
             }
             result += sep + line;
             sep = joinSep;
         }
         return result;
     }

    
search if the doc have an header
    .. header:: This space for rent. aaaa **aaaa**
 

Returns:
Element
Throws:
java.io.IOException
 
     public Element peekHeader() throws IOException {
         beginPeek();
         Element result = null;
         String[] line = .readAll();
         if (line != null) {
             int i = 0;
             for (String l : line) {
                 i++;
                 if (l.matches("^\\s*.. " +  + ":: .*")) {
                     int level = level(l);
                     l = l.replaceAll("^\\s*.. " +  + ":: """);
                     result = DocumentHelper.createElement().addAttribute(
                             , String.valueOf(level));
                     result.addAttribute("" + i);
                     result.setText(l);
                 }
 
             }
         }
         endPeek();
         return result;
 
     }

    
search if the doc have an header
    .. footer:: design by **LETELLIER Sylvain**
 

Returns:
Element
Throws:
java.io.IOException
 
     public Element peekFooter() throws IOException {
         beginPeek();
         Element result = null;
         String[] line = .readAll();
         if (line != null) {
             int i = 0;
             for (String l : line) {
                 i++;
 
                 if (l.matches("^\\s*.. " +  + ":: .*")) {
                     int level = level(l);
                     l = l.replaceAll("^\\s*.. " +  + ":: """);
                     result = DocumentHelper.createElement().addAttribute(
                             , String.valueOf(level));
                     result.addAttribute("" + i);
                     result.setText(l);
                 }
             }
         }
         endPeek();
         return result;
 
     }

    
 .. __: http://www.python.org
 

Returns:
Element
Throws:
java.io.IOException
 
     public LinkedList<ElementpeekTargetAnonymous() throws IOException {
         beginPeek();
         LinkedList<Elementresult = new LinkedList<Element>();
         String[] line = .readAll();
         if (line != null) {
             int i = 0;
             for (String l : line) {
                 i++;
 
                 if (l.matches("^\\s*__ .+$|^\\s*\\.\\. __\\:.+$")) {
                 	.debug(l);
                     Element resultTmp = DocumentHelper
                             .createElement();
                     resultTmp.addAttribute("" + level(l));
                     Matcher matcher = Pattern.compile("__ |.. __: ").matcher(l);
                     
                     if (matcher.find()) {
                         resultTmp.addAttribute(l.substring(matcher
                                 .end(), l.length()));
                     }
                     
                     result.add(resultTmp);
                 }
             }
 
         }
         endPeek();
         return result;
     }

    
Return title or para

Returns:
Element
Throws:
java.io.IOException
 
     public Element peekTitleOrBodyElement() throws IOException {
         Element result = null;
         if (result == null) {
             result = peekTitle();
         }
         if (result == null) {
             result = peekBodyElement();
         }
 
         return result;
     }

    
read doc info author, date, version, ... or field list element
 :author: Benjamin Poussin
 :address:
   Quelque part
   Dans le monde
 

Returns:
Element
Throws:
java.io.IOException
 
     public Element peekDocInfo() throws IOException {
         Element result = null;
         if (result == null) {
             result = peekDocInfoItem();
 
         }
         if (result == null) {
             result = peekFieldList();
         }
 
         return result;
 
     }

    
Return para

Returns:
Element
Throws:
java.io.IOException
 
     public Element peekBodyElement() throws IOException {
         Element result = null;
         if (result == null) {
             result = peekInclude();
         }
         if (result == null) {
             result = peekDoctestBlock();
         }
         if (result == null) {
             result = peekAdmonition();
         }
         if (result == null) {
             result = peekSidebar();
         }
         if (result == null) {
             result = peekTopic();
         }
         if (result == null) {
             result = peekRemove();
         }
         if (result == null) {
             result = peekDirectiveOrReference();
         }
         if (result == null) {
             result = peekTransition();
         }
         if (result == null) {
             result = peekTable();
         }
         if (result == null) {
             result = peekLineBlock();
         }
         if (result == null) {
             result = peekBulletList();
         }
         if (result == null) {
             result = peekOption();
         }
         if (result == null) {
             result = peekEnumeratedList();
         }
         if (result == null) {
             result = peekTarget();
         }
         if (result == null) {
             result = peekFootnote();
         }
         // comment must be read after peekDirectiveOrReference()
         // and peekFootnote()
         if (result == null) {
             result = peekComment();
         }
         if (result == null) {
             result = peekDefinitionList();
         }
         if (result == null) {
             result = peekFieldList();
         }
         if (result == null) {
             result = peekTargetAnonymousBody();
         }
         if (result == null) {
             result = peekLiteralBlock();
         }
         if (result == null) {
             result = peekBlockQuote();
         }
         if (result == null) {
             result = peekBlankLine();
         }
         if (result == null) {
             result = peekPara();
         }
 
         return result;
     }

    
Remove already read elements

Returns:
Element
Throws:
java.io.IOException
 
     public Element peekRemove() throws IOException {
         beginPeek();
         Element result = null;
         String line = .readLine();
         if (line != null) {
             // Le header est parse des le debut
             if (line.matches("^\\s*.. " +  + ":: .*")) {
                 result = DocumentHelper.createElement().addAttribute(
                         "" + level(line));
             }
             // Le footer
             if (line.matches("^\\s*.. " +  + ":: .*")) {
                 result = DocumentHelper.createElement().addAttribute(
                         "" + level(line));
             }
 
         }
         endPeek();
         return result;
     }

    
read include
 .. include:: text.txt
 or
 .. include:: literal
      text.txt
 
 

Returns:
Element
Throws:
java.io.IOException
 
     private Element peekInclude() throws IOException {
         beginPeek();
         Element result = null;
         String line = .readLine();
         if (line != null) {
             if (line.matches("^\\s*\\.\\.\\sinclude\\:\\:.+$")) {
                 result = DocumentHelper.createElement();
                 result.addAttribute("" + level(line));
                 String option = line.substring(line.indexOf("::") + 2).trim();
                 result.addAttribute("");
                 if (option.trim().equalsIgnoreCase()) {
                     result.addAttribute();
                     line = .readLine();
                     result.setText(line.trim());
                 } else {
                     result.setText(option);
                 }
 
             }
         }
         endPeek();
         return result;
     }

    
read options
 Ex :     -a            command-line option "a"
          -1 file, --one=file, --two file
                     Multiple options with arguments.
 Schéma :  ________________________________
           v          |                    |
        -{1,2}\w+ ->|','                   |
                    |'='-----|-> \w+ --->|','
                    |' '-----|           |' '---+
                    |"  " -----> \w+ ---> end   |
                      ˆ                         |
                      |_________________________|
 Légende :   
 
          -{1,2} --> 1 or 2 tirets
          \w+ -----> word characters one or more times
 

Returns:
Element
Throws:
java.io.IOException
 
     public Element peekOption() throws IOException {
 
         beginPeek();
         Element result = null;
         String line = .readLine();
         if (line != null) {
             if (line.matches("^(\\s*((--?)|(//?))\\w+([ =][<a-zA-Z][\\w-><]*)?)\\s*.*$")) {
                 result = DocumentHelper.createElement()
                         .addAttribute("" + level(line));
                 char delimiter;
                 do {
                     Matcher matcher = Pattern.compile("[-/][-/]?.+").matcher(line);
                     matcher.find();
                     Element option = result.addElement();
                     String option_stringTmp = matcher.group();
                     matcher = Pattern.compile("^[-/][-/]?\\w+").matcher(option_stringTmp);
                     matcher.find();
                     String option_string = matcher.group();
                     option.addAttribute(option_string);
                     
                     boolean done = false;
                     // Delimiteur bidon
                     delimiter = '.';
                     if (option_stringTmp.length() > matcher.end()) {
                         delimiter = option_stringTmp.charAt(matcher.end());
                         option_stringTmp = option_stringTmp.substring(
                             matcher.end(), option_stringTmp.length());
                     } else {
                         done = true;
                     }
                     option.addAttribute();
 
                     if (delimiter == ' ') { // S'il y a 2 espaces a suivre,
                         // l'option est finie
                         if (option_stringTmp.charAt(1) == ' ') {
                             done = true;
                         }
                     }
                     String option_argument = null;
                     if ((delimiter == '=' || delimiter == ' ') && !done) {
                         option.addAttribute();
                         option.addAttribute("" + delimiter);
                         matcher = Pattern.compile(delimiter + "(([a-zA-Z][\\w-]+)|(<[a-zA-Z][^>]*>))").matcher(
                                 option_stringTmp);
                         if (matcher.find()) {
                             option_argument = matcher.group().substring(1,
                                     matcher.group().length());
                             option.addAttribute(option_argument);
                             if (option_stringTmp.charAt(option_argument.length() + 1) == ',') {
                                 delimiter = ',';
                             } else {
                                 done = true;
                             }
                         } else { // Si la description n'est pas sur la meme
                             // ligne
                             option_argument = option_stringTmp;
                             option.addAttribute(,
                                     option_argument);
                             line = .readLine();
                             if (line != null) {
                                 result.setText(line.trim());
                             }
                         }
                     }
                     if (delimiter == ',') {
                         line = line.substring(option_string.length() + 1
                                 + (option_argument == null ? 0 : option_argument.length()));
                     }
                     if (done) {
                         result.setText(option_stringTmp.substring(matcher.end(), option_stringTmp.length()).trim()
                                 + " " + joinBlock(readBlock(1)));
                     }
                 } while (delimiter == ',');
             }
         }
         endPeek();
         return result;
     }

    
read topic
 -.. topic:: Title
     Body.
 

Returns:
Element
Throws:
java.io.IOException
 
     private Element peekTopic() throws IOException {
         beginPeek();
         Element result = null;
         String line = .readLine();
         if (line != null) {
             if (line.matches("^\\.\\.\\s+(" +  + ")::\\s+(.*)$")) {
                 Matcher matcher = Pattern.compile( + "::").matcher(line);
                 matcher.find();
                 result = DocumentHelper.createElement().addAttribute(
                         "" + level(line));
                 String title = line.substring(matcher.end(), line.length());
                 result.addAttribute(title);
                 line = .readLine();
                 if (line.matches("\\s*")) {
                     line = .readLine();
                 }
                 int level = level(line);
                 String[] lines = null;
                 if (level != 0) {
                     lines = .readWhile("(^ {" + level + "}.*)|(\\s*)");
                     String txt = line;
                     for (String txtTmp : lines) {
                         txt += "\n" + txtTmp.trim();
                     }
                     result.setText(txt);
                 }
 
             }
         }
 
         endPeek();
         return result;
     }

    
read sidebar
 .. sidebar:: Title
    :subtitle: If Desired
    Body.
 

Returns:
Element
Throws:
java.io.IOException
 
     private Element peekSidebar() throws IOException {
         beginPeek();
         Element result = null;
         String line = .readLine();
         if (line != null) {
             if (line.matches("^\\.\\.\\s*(" +  + ")::\\s*(.*)$")) {
                 Matcher matcher = Pattern.compile( + "::").matcher(line);
                 matcher.find();
                 result = DocumentHelper.createElement().addAttribute(
                         "" + level(line));
                 String title = line.substring(matcher.end(), line.length());
                 result.addAttribute(title);
                 line = .readLine();
                 if (line.matches("^\\s+:subtitle:\\s*(.*)$*")) {
                     matcher = Pattern.compile(":subtitle:\\s*").matcher(line);
                     matcher.find();
                     String subTitle = line.substring(matcher.end(), line
                             .length());
                     result.addAttribute();
                     result.addAttribute(subTitle);
                     line = .readLine();
                 } else {
                     result.addAttribute();
                 }
                 String txt = joinBlock(readBlock(level(line)));
                 result.setText(txt);
 
             }
         }
 
         endPeek();
         return result;
     }

    
read line block
 |        A one, two, a one two three four
 |
 | Half a bee, philosophically,
 |     must, *ipso facto*, half not be.
 | But half the bee has got to be,
 |               *vis a vis* its entity.  D'you see?
 

Returns:
Element
Throws:
java.io.IOException
 
     private Element peekLineBlock() throws IOException {
         beginPeek();
         Element result = null;
         String line = .readLine();
         if (line != null) {
             if (line.matches("\\|\\s.*")) {
                 String[] linesTmp = readBlock(0);
                 String[] lines = new String[linesTmp.length + 1];
                 lines[0] = line;
                 for (int i = 0; i < linesTmp.lengthi++) {
                     lines[i + 1] = linesTmp[i];
                 }
                 int[] levelsTmp = new int[lines.length];
                 int levelmin = 999;
                 result = DocumentHelper.createElement().addAttribute(
                         , 0 + "");
                 for (int i = 0; i < levelsTmp.lengthi++) {
                     // on enleve |
                     lines[i] = lines[i].replaceAll("\\|\\s?""");
                 }
                 for (int i = 0; i < levelsTmp.lengthi++) {
                     // determination des levels
                     levelsTmp[i] = level(lines[i]);
                 }
                 for (int i : levelsTmp) {
                     // level minimal
                     levelmin = Math.min(levelmini);
                 }
                 int cnt = 0;
                 String lineAv = "";
                 int[] levels = new int[levelsTmp.length];
                 for (String l : lines) {
                     if (!l.matches("\\s*")) { // Si la ligne courante n'est
                         // pas vide
                         int level = levelsTmp[cnt] - levelmin;
                         if (level != 0) {
                             if (cnt != 0) {
                                 if (!lineAv.matches("\\s*")) { // Si la ligne
                                     // d'avant n'est
                                     // pas vide
                                     int levelAv = levelsTmp[cnt - 1] - levelmin;
                                     if (levelAv < level) {
                                         levels[cnt] = levels[cnt - 1] + 1;
                                         if (cnt != levels.length) {
                                             int levelAp = levelsTmp[cnt + 1]
                                                     - levelmin;
                                             if (levelAp < level
                                                     && levelAv < levelAp) {
                                                 levels[cnt]++;
                                             }
                                         }
                                     } else {
                                         levels[cnt] = levels[cnt - 1] - 1;
                                     }
                                 } else {
                                     levels[cnt] = 1;
                                 }
                             } else {
                                 levels[cnt] = 1;
                             }
                         } else {
                             levels[cnt] = 0;
                         }
                     } else {
                         if (cnt != 0) {
                             levels[cnt] = levels[cnt - 1];
                         }
                         else {
                             levels[cnt] = 0;
                         }
                     }
                     cnt++;
                     lineAv = l;
                 }
                 for (int i = 0; i < levels.lengthi++) {
                     Element eLine = result.addElement();
                     eLine.addAttribute("" + levels[i]);
                     eLine.setText(lines[i].trim());
                 }
             }
         }
         endPeek();
         return result;
     }

    
read doctest block
 >>> print 'this is a Doctest block'
 this is a Doctest block
 

Returns:
Element
Throws:
java.io.IOException
 
    private Element peekDoctestBlock() throws IOException {
        beginPeek();
        Element result = null;
        String line = .readLine();
        if (line != null) {
            if (line.matches("^\\s*>>>\\s.*")) {
                int level = level(line);
                result = DocumentHelper.createElement()
                        .addAttribute(, String.valueOf(level));
                result.addAttribute("preserve");
                line += "\n" + joinBlock(readBlock(level));
                result.setText(line);
            }
        }
        endPeek();
        return result;
    }

    
read block quote
 As a great paleontologist once said,
 
     This theory, that is mine, is mine.
 
     -- Anne Elk (Miss)
 

Returns:
Element
Throws:
java.io.IOException
    private Element peekBlockQuote() throws IOException {
        beginPeek();
        Element result = null;
        String line = .readLine();
        if (line != null) {
            if (line.matches("\\s.*")) {
                int level = level(line);
                String savedLine = line + " " + joinBlock(readBlock(level));
                line = .readLine();
                if (line != null) {
                    level = level(line);
                    String blockQuote = null;
                    if (level != 0) {
                        String txt = line;
                        String[] lines = .readWhile("(^ {" + level
                                + "}.*)|(\\s*)");
                        for (String l : lines) {
                            if (l.matches("^ {" + level + "}--\\s*.*")) {
                                blockQuote = l;
                                blockQuote = blockQuote.replaceAll("--""")
                                        .trim();
                            } else {
                                txt += "\n" + l;
                            }
                        }
                        result = DocumentHelper.createElement()
                                .addAttribute(, String.valueOf(level));
                        if (blockQuote != null) {
                            result.addAttribute(blockQuote);
                        }
                        result.setText(savedLine + txt);
                    }
                }
            }
        }
        endPeek();
        return result;
    }

    
read admonitions : admonition|attention|caution|danger|error|hint|important|note|tip|warning
 .. Attention:: All your base are belong to us.
 .. admonition:: And, by the way...
 
    You can make up your own admonition too.
 

Returns:
Element
Throws:
java.io.IOException
    protected Element peekAdmonition() throws IOException {
        beginPeek();
        Element result = null;
        String line = .readLine();
        if (line != null) {
            String lineTest = line.toLowerCase();
            Pattern pAdmonition = Pattern.compile("^\\.\\.\\s*("
                    +  + ")::\\s*(.*)$");
            Matcher matcher = pAdmonition.matcher(lineTest);
            if (matcher.matches()) {
                boolean admonition = false;
                matcher = Pattern.compile().matcher(lineTest);
                matcher.find();
                int level = level(line);
                result = DocumentHelper.createElement().addAttribute(
                        "" + level);
                if (matcher.group().equals()) { // Il y a un titre
                    // pour un
                    // admonition
                    // general
                    admonition = true;
                    result.addAttribute();
                    String title = line.substring(matcher.end() + 2, line
                            .length());
                    result.addAttribute(title);
                } else {
                    result.addAttribute(matcher.group());
                }
                
                String firstLine = "";
                if (!admonition && matcher.end() + 2 < line.length()) {
                    firstLine = line
                            .substring(matcher.end() + 2, line.length());
                }
                line = .readLine();
                if (line != null) {
                    if (line.matches("\\s*")) {
                        line = .readLine();
                    }
                    if (line != null && !line.matches("\\s*")) {
                        level = level(line);
                        String txt = firstLine.trim() + "\n" + line + "\n";
                        txt += "\n" + readBlockWithBlankLine(level);
                        result.setText(txt);
                    } else {
                        result.setText(firstLine);
                    }
                } else {
                    result.setText(firstLine);
                }
            }
        }
        endPeek();
        return result;
    }

    
read blank line

Returns:
Element
Throws:
java.io.IOException
    public Element peekBlankLine() throws IOException {
        beginPeek();
        Element result = null;
        // must have one blank line before
        String line = .readLine();
        if (line != null && line.matches("\\s*")) {
            int level = level(line);
            result = DocumentHelper.createElement().addAttribute(
                    , String.valueOf(level));
        }
        endPeek();
        return result;
    }

    
read directive or reference

Returns:
Element
Throws:
java.io.IOException
    public Element peekDirectiveOrReference() throws IOException {
        beginPeek();
        Element result = null;
        String line = .readLine();
        if (line != null) {
            Pattern pImage = Pattern
                    .compile("^\\.\\.\\s*(?:\\|([^|]+)\\|)?\\s*(\\w+)::\\s*(.*)$");
            Matcher matcher = pImage.matcher(line);
            if (matcher.matches()) {
                String ref = matcher.group(1);
                String directiveType = matcher.group(2);
                String directiveValue = matcher.group(3);
                Element directive = null;
                if (ref != null && !"".equals(ref)) {
                    result = DocumentHelper
                            .createElement();
                    result.addAttribute(ref);
                    directive = result.addElement();
                } else {
                    result = DocumentHelper.createElement();
                    directive = result;
                }
                result.addAttribute("0");
                directive.addAttribute(directiveType);
                directive.addAttribute(directiveValue);
                String[] lines = readBlock(1);
                String text = joinBlock(lines"\n"false);
                directive.setText(text);
            }
        }
        endPeek();
        return result;
    }

    
read transition

Returns:
Element
Throws:
java.io.IOException
    public Element peekTransition() throws IOException {
        beginPeek();
        Element result = null;
        // no eat blank line, see next comment
        // must have one blank line before
        String line = .readLine();
        if (line != null && line.matches("\\s*")) {
            // in.skipBlankLines();
            line = .readLine();
            if (line != null && line.matches("-{3,}\\s*")) {
                line = .readLine();
                // must have one blank line after
                if (line != null && line.matches("\\s*")) {
                    result = DocumentHelper.createElement()
                            .addAttribute(, String.valueOf(0));
                }
            }
        }
        endPeek();
        return result;
    }

    
read paragraph with attribut level that represente the space numbers at left side

Returns:
<paragraph level="[int]"&gt[text]</paragraph>
Throws:
java.io.IOException
    public Element peekPara() throws IOException {
        beginPeek();
        Element result = null;
        // in.skipBlankLines();
        String[] lines;
        do {
            lines = readBlock(0);
            if (lines.length > 0) {
                int level = level(lines[0]);
                String para = joinBlock(lines);
                boolean literal = false;
                if (para.endsWith(": ::")) {
                    para = para.substring(0, para.length() - " ::".length());
                    .unread("::"true);
                    for(int i=0;i<level;i++) {                    
                        .add(' ');
                    }
                    
                    literal = true;
                } else if (para.endsWith("::")) {
                    para = para.substring(0, para.length() - ":".length()); // keep
                    // one
                    // :
                    
                    .unread("::"true);
                    
                    for(int i=0;i<level;i++) {                    
                        .add(' ');
                    }
                    
                    literal = true;
                }
                if (para.length() == 0 || ":".equals(para)) {
                    if (literal) {
                        .readLine(); // eat "::"
                    }
                } else {
                    // if para is empty, there are error and possible
                    // infiny loop on para, force read next line
                    result = DocumentHelper.createElement()
                            .addAttribute(, String.valueOf(level))
                            .addText(para);
                }
            }
        } while (result == null && lines.length > 0);
        endPeek();
        return result;
    }

    
read literal block
 ::
 
     LiteralBlock
 

Returns:
Element
Throws:
java.io.IOException
    public Element peekLiteralBlock() throws IOException {
        beginPeek();
        Element result = null;
        // in.skipBlankLines();
        
        
        String[] prefix = .readLines(2);
        if (prefix.length == 2 && prefix[0].matches("\\s*::\\s*")
                && prefix[1].matches("\\s*")) {
            
            int level = level(prefix[0]);
            String para = .readLine();
            if (para != null) {
                level=level+1;
                para = para.substring(level) + "\n";
                // it's literal block until level is down
                String[] lines = .readWhile("(^ {" + level + "}.*|\\s*)");
                while (lines.length > 0) {
                    for (String line : lines) {
                        if (!line.matches("\\s*")) {
                            para += line.substring(level) + "\n";
                        }
                        else {
                            para += "\n";
                        }
                    }
                    lines = .readWhile("(^ {" + level + "}.*|\\s*)");
                }
                result = DocumentHelper.createElement()
                        .addAttribute(, String.valueOf(level)).addText(