r644 - in branches/jrst-docutils-jython/jrst/src: main/java/org/nuiton/jrst test/java/org/nuiton/jrst test/java/org/nuiton/jrst/bugs test/resources/bugs
Author: jpages Date: 2012-04-24 11:23:11 +0200 (Tue, 24 Apr 2012) New Revision: 644 Url: http://nuiton.org/repositories/revision/jrst/644 Log: Certaines classes sont ?\195?\169t?\195?\169 supprim?\195?\169es car elles n'avaient plus d'utilit?\195?\169 (convertisor, etc...). De plus certains fichiers ont ?\195?\169t?\195?\169 ajout?\195?\169s comme le pom du projet par exemple. Removed: branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/AdvancedReader.java branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRSTLexer.java branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRSTReader.java branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/directive/ branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/AdvancedReaderTest.java branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/Compare.java branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTCompareDocutils.java branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTReaderTest.java branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/InfiniteLoopTest.java Modified: branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRST.java branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTGeneratorTest.java branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/AdmonitionTest.java branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/TitlesTest.java branches/jrst-docutils-jython/jrst/src/test/resources/bugs/testAdminitionInList1787.rst Deleted: branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/AdvancedReader.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/AdvancedReader.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/AdvancedReader.java 2012-04-24 09:23:11 UTC (rev 644) @@ -1,406 +0,0 @@ -/* - * #%L - * JRst :: Api - * - * $Id$ - * $HeadURL$ - * %% - * 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 org.apache.commons.collections.primitives.ArrayCharList; -import org.apache.commons.collections.primitives.CharList; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.io.PushbackReader; -import java.io.Reader; -import java.util.ArrayList; - -/** - * Le principe est d'avoir dans cette classe le moyen de lire, et de retourner - * la ou on etait avant la lecture (mark et reset de {@link BufferedReader}). - * <p> - * Mais il faut aussi pouvoir dire qu'en fin de compte on ne souhaite pas lire - * les caracteres que l'on vient de lire ({@link #unread(int)} a peu pres egal a - * {@link PushbackReader}) - * <p> - * Le pointer nextChar pointe toujours sur le prochain caractere qui sera lu - * <p> - * Lorsque l'on appelle la method {@link #mark()} on vide aussi le buffer pour - * liberer de la place, car on a plus le moyen de retourner avant le mark que - * l'on vient de positionner. - * <p> - * On contraire du mark de {@link BufferedReader} ou {@link LineNumberReader} il - * n'y a pas a specifier le nombre de caractere a garder au maximum, seul la - * memoire nous limite. Du coup si l'on utilise cette classe sans mark, au final - * on aura dans le buffer tout le contenu du reader, il faut donc utiliser mark - * avec cette classe - * - * buffer - * - * <pre> - * ######################### - * 0 ˆ ˆ - * | | - * | + nextChar - * + markChar - * </pre> - * - * Created: 27 oct. 06 00:24:57 - * - * @author poussin - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - */ -public class AdvancedReader { - - /** le nombre d'espace pour remplacer les tabulations */ - protected static final String TAB = " "; - /** nombre de caractere lu au minimum sur le vrai reader */ - protected static final int READ_AHEAD = 80; - - protected Reader in; - protected CharList buffer; - - protected int charNumber; - protected int charNumberMark; - protected int lineNumber; - protected int lineNumberMark; - - protected int nextChar; - protected int markChar; - - protected int readInMark; - - protected boolean nlTwoCtrlChars = false; - protected boolean noNlAtEOF = false; - - /** - * - * @param in the io reader - */ - public AdvancedReader(Reader in) { - this.in = new LineNumberReader(in); - buffer = new ArrayCharList(); - } - - public void mark() throws IOException { - markChar = nextChar; - charNumberMark = charNumber; - lineNumberMark = lineNumber; - - free(markChar); - } - - public void reset() throws IOException { - nextChar = markChar; - charNumber = charNumberMark; - lineNumber = lineNumberMark; - - } - - public int readSinceMark() { - return nextChar - markChar; - } - - /** - * @return the charNumber - */ - public int getCharNumber() { - return charNumber; - } - - /** - * @return the lineNumber - */ - public int getLineNumber() { - return lineNumber; - } - - /** - * remove number of char in buffer - * - * @param number - * @return the real number of char removed from the head of buffer - * @throws IOException - */ - private int free(int number) throws IOException { - // fill(number); - int result = Math.min(buffer.size(), number); - buffer.subList(0, result).clear(); - - nextChar -= result; - markChar -= result; - - return result; - } - - /** - * ensure that have number char available and not already read - * - * @param number ? - * @throws IOException - */ - private void fill(int number) throws IOException { - int needed = nextChar + number - buffer.size(); - if (needed > 0) { - char[] cbuf = new char[needed + READ_AHEAD]; - int read = in.read(cbuf); - if (read != -1) { - for (int i = 0; i < read; i++) { - buffer.add(cbuf[i]); - } - } - } - } - - public boolean eof() throws IOException { - boolean result = -1 == read(); - if (!result) { - unread(1); - } - return result; - } - - public int skip(int number) throws IOException { - int result = 0; - while (result < number && read() != -1) { - result++; - } - return result; - } - - /** - * Add a character at the current position - * @param character that you want to add - */ - public void add(char character) { - buffer.add(nextChar,character); - } - - - /** - * go left in reading char buffer - * - * @param number - * @return realy unread char number - */ - public int unread(int number) { - int result = Math.min(number, nextChar); - - nextChar -= result; - charNumber -= result; - for (int i = nextChar; i < nextChar + result; i++) { - if (buffer.get(i) == '\n' || (buffer.get(i) == '\r' && i + 1 < nextChar + result && buffer.get(i + 1) != '\n')) { - lineNumber--; - } - } - - return result; - } - - /** - * Unread the line length - * - * @param line - * line used to know the length to unread - * @param addNewLine - * if true then add +1 to unread lenght for not present '\n' - * @return number of unread char - */ - public int unread(String line, boolean addNewLine) { - int result = unread(line.length() + (addNewLine ? (nlTwoCtrlChars ? 2 : 1) : 0)); - return result; - } - - /** - * Unread the line length - * - * @param lines - * lines used to know the length to unread - * @param addNewLine - * if true then add +1 for each line to unread lenght for not - * present '\n' - * @return number of unread char - */ - public int unread(String[] lines, boolean addNewLine) { - int result = 0; - for (String line : lines) { - result += unread(line, addNewLine); - } - return result; - } - - /** - * read one char in buffer - * - * @return the next char - * @throws IOException pour tout pb de lecture - */ - public int read() throws IOException { - fill(1); - int result = -1; - if (nextChar < buffer.size()) { - result = buffer.get(nextChar++); - charNumber++; - if ((char)result == '\n' || ((char)result == '\r' && nextChar < buffer.size() && buffer.get(nextChar) != '\n')) { - lineNumber++; - } - } - return result; - } - - /** - * read one line - * - * @return one line without '\n' or null if end of file - * @throws IOException pour tout pb de lecture - */ - public String readLine() throws IOException { - StringBuffer result = new StringBuffer(READ_AHEAD); - int c = read(); - while (c != -1 && c != '\n' && c != '\r') { - result.append((char) c); - c = read(); - } - nlTwoCtrlChars = false; - if (c == '\r') { - c = read(); - if (c != '\n' && c != -1) { - unread(1); - } else { - nlTwoCtrlChars = true; - } - } - noNlAtEOF = false; - if (c == -1 && result.length() >= 0) { - if (c == -1 && result.length() == 0) { - return null; - } else { - noNlAtEOF = true; - return result.toString(); - } - } else { - return result.toString(); - } - } - - - - - /** - * passe les lignes blanches - * - * @throws IOException - */ - public void skipBlankLines() throws IOException { - readUntil("^\\s*\\S+.*"); - } - - /** - * lit toutes les lignes du fichier - * - * @return toutes les lignes du fichier - * @throws IOException pour tout pb de lecture - */ - String[] readAll() throws IOException { - String[] result = readLines(-1); - return result; - } - - /** - * lit un certain nombre de lignes - * - * @param count - * si negatif lit toutes les lignes - * @return un certain nombre de lignes - * @throws IOException pour tout pb de lecture - */ - public String[] readLines(int count) throws IOException { - ArrayList<String> result = new ArrayList<String>(); - - String tmp = ""; - for (int i = count; tmp != null && i != 0; i--) { - tmp = readLine(); - if (tmp != null) { - result.add(tmp); - } - } - return result.toArray(new String[result.size()]); - } - - /** - * lit les lignes jusqu'a la premiere ligne blanche (non retournée) - * - * @return toutes les ligne jusqu'à la première ligne blanche (non incluse) - * @throws IOException pour tout pb de lecture - */ - public String[] readUntilBlank() throws IOException { - String[] result = readUntil("\\s*"); - return result; - } - - /** - * lit les lignes jusqu'a la ligne qui correspond pas au pattern, cette - * ligne n'est pas mise dans le resultat retourne - * - * @param pattern ? - * @return les lignes jusqu'a la ligne qui correspond pas au pattern, cette - * ligne n'est pas mise dans le resultat retourne - * @throws IOException pour tout pb de lecture - */ - public String[] readUntil(String pattern) throws IOException { - ArrayList<String> result = new ArrayList<String>(); - String tmp = readLine(); - while (tmp != null && !tmp.matches(pattern)) { - result.add(tmp); - tmp = readLine(); - } - if (tmp != null) { - unread(tmp.length() + (!noNlAtEOF ? (nlTwoCtrlChars ? 2 : 1) : 0)); // +1 for '\n' not in line - } - return result.toArray(new String[result.size()]); - } - - /** - * lit les lignes tant que les lignes correspondent au pattern - * - * @param pattern ? - * @return les lignes tant que les lignes correspondent au pattern - * @throws IOException pour tout pb de lecture - */ - public String[] readWhile(String pattern) throws IOException { - ArrayList<String> result = new ArrayList<String>(); - String tmp = readLine(); - while (tmp != null && tmp.matches(pattern)) { - result.add(tmp); - tmp = readLine(); - } - if (tmp != null) { - unread(tmp.length() + (!noNlAtEOF ? (nlTwoCtrlChars ? 2 : 1) : 0)); // +1 for '\n' not in line - } - return result.toArray(new String[result.size()]); - } - -} Modified: branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRST.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRST.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRST.java 2012-04-24 09:23:11 UTC (rev 644) @@ -413,6 +413,8 @@ public static File generateDocument(String outputType, File in, File out) throws Exception { + out.createNewFile(); + URL resource = in.getClass().getResource("/__run__.py"); String docutilsPath = resource.getPath().replaceAll("__run__.py", ""); docutilsPath = docutilsPath.replaceAll("!", ""); Deleted: branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRSTLexer.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRSTLexer.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRSTLexer.java 2012-04-24 09:23:11 UTC (rev 644) @@ -1,2514 +0,0 @@ -/* - * #%L - * JRst :: Api - * - * $Id$ - * $HeadURL$ - * %% - * 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.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.dom4j.DocumentHelper; -import org.dom4j.Element; - -import java.io.IOException; -import java.io.Reader; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Le principe est de positionner la mark du {@link 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. - * <p> - * 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. - * <p> - * Pour mettre en place ce mecanisme le plus simple est d'utiliser les methodes - * {@link JRSTLexer#beginPeek()} et {@link JRSTLexer#endPeek()} - * - * Created: 28 oct. 06 00:44:20 - * - * @author poussin, letellier - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - */ -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. - * - * <pre> - * ===== - * Super - * ===== - * titre - * ----- - * </pre> - * - * donnera dans la liste ["==", "-"] - */ - private List<String> titleLevels; - - private AdvancedReader in; - - /** - * length of the last element returned (number of char need to this element) - */ - private int elementLength; - - - - - public JRSTLexer(Reader reader) { - titleLevels = new ArrayList<String>(); - in = new AdvancedReader(reader); - } - - /** - * true if no more element to read - * - * @return boolean - * @throws IOException - */ - public boolean eof() throws IOException { - in.mark(); - in.skipBlankLines(); - boolean result = in.eof(); - in.reset(); - return result; - } - - /** - * remove one element from list of element already read - * - * @throws IOException - */ - public void remove() throws IOException { - in.skip(elementLength); - } - - /** - * start peek - * - * @throws IOException - */ - private void beginPeek() throws IOException { - elementLength = 0; - in.mark(); - } - - /** - * end peek - * - * @throws IOException - */ - private void endPeek() throws IOException { - elementLength = in.readSinceMark(); - in.reset(); - } - - /** - * Read block text, block text have same indentation and is continu (no - * blank line) - * - * @param minLeftMargin - * min left blank needed to accept to read block - * @return String[] - * @throws IOException - */ - private String[] readBlock(int minLeftMargin) throws IOException { - String[] result = new String[0]; - String firstLine = in.readLine(); - if (firstLine != null) { - in.unread(firstLine, true); - int level = level(firstLine); - if (level >= minLeftMargin) { - result = in.readWhile("^\\s{" + level + "}\\S+.*"); - } - } - - return result; - } - - /** - * All lines are joined and left and right spaces are removed during join - * - * @param String - * [] lines - * @return 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 - * - * @param String - * [] lines - * @param String - * joinSep - * @param Boolean - * trim - * @return String - */ - private String joinBlock(String[] lines, String joinSep, boolean 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 - * - * <pre> - * .. header:: This space for rent. aaaa **aaaa** - * </pre> - * - * @return Element - * @throws IOException - */ - public Element peekHeader() throws IOException { - beginPeek(); - Element result = null; - String[] line = in.readAll(); - if (line != null) { - int i = 0; - for (String l : line) { - i++; - if (l.matches("^\\s*.. " + HEADER + ":: .*")) { - int level = level(l); - l = l.replaceAll("^\\s*.. " + HEADER + ":: ", ""); - result = DocumentHelper.createElement(HEADER).addAttribute( - LEVEL, String.valueOf(level)); - result.addAttribute(LINE, "" + i); - result.setText(l); - } - - } - } - endPeek(); - return result; - - } - - /** - * search if the doc have an header - * - * <pre> - * .. footer:: design by **LETELLIER Sylvain** - * </pre> - * - * @return Element - * @throws IOException - */ - public Element peekFooter() throws IOException { - beginPeek(); - Element result = null; - String[] line = in.readAll(); - if (line != null) { - int i = 0; - for (String l : line) { - i++; - - if (l.matches("^\\s*.. " + FOOTER + ":: .*")) { - int level = level(l); - l = l.replaceAll("^\\s*.. " + FOOTER + ":: ", ""); - result = DocumentHelper.createElement(FOOTER).addAttribute( - LEVEL, String.valueOf(level)); - result.addAttribute(LINE, "" + i); - result.setText(l); - } - } - } - endPeek(); - return result; - - } - - /** - * <pre> - * .. __: http://www.python.org - * </pre> - * - * @return Element - * @throws IOException - */ - public LinkedList<Element> peekTargetAnonymous() throws IOException { - beginPeek(); - LinkedList<Element> result = new LinkedList<Element>(); - String[] line = in.readAll(); - if (line != null) { - int i = 0; - for (String l : line) { - i++; - - if (l.matches("^\\s*__ .+$|^\\s*\\.\\. __\\:.+$")) { - log.debug(l); - Element resultTmp = DocumentHelper - .createElement(TARGETANONYMOUS); - resultTmp.addAttribute(LEVEL, "" + level(l)); - Matcher matcher = Pattern.compile("__ |.. __: ").matcher(l); - - if (matcher.find()) { - resultTmp.addAttribute(REFURI, l.substring(matcher - .end(), l.length())); - } - - result.add(resultTmp); - } - } - - } - endPeek(); - return result; - } - - /** - * Return title or para - * - * @return Element - * @throws 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 - * - * <pre> - * :author: Benjamin Poussin - * :address: - * Quelque part - * Dans le monde - * </pre> - * - * @return Element - * @throws IOException - */ - public Element peekDocInfo() throws IOException { - Element result = null; - if (result == null) { - result = peekDocInfoItem(); - - } - if (result == null) { - result = peekFieldList(); - } - - return result; - - } - - /** - * Return para - * - * @return Element - * @throws 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 - * - * @return Element - * @throws IOException - */ - public Element peekRemove() throws IOException { - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - // Le header est parse des le debut - if (line.matches("^\\s*.. " + HEADER + ":: .*")) { - result = DocumentHelper.createElement(REMOVE).addAttribute( - LEVEL, "" + level(line)); - } - // Le footer - if (line.matches("^\\s*.. " + FOOTER + ":: .*")) { - result = DocumentHelper.createElement(REMOVE).addAttribute( - LEVEL, "" + level(line)); - } - - } - endPeek(); - return result; - } - - /** - * read include - * - * <pre> - * .. include:: text.txt - * or - * .. include:: literal - * text.txt - * - * </pre> - * - * @return Element - * @throws IOException - */ - private Element peekInclude() throws IOException { - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - if (line.matches("^\\s*\\.\\.\\sinclude\\:\\:.+$")) { - result = DocumentHelper.createElement(INCLUDE); - result.addAttribute(LEVEL, "" + level(line)); - String option = line.substring(line.indexOf("::") + 2).trim(); - result.addAttribute(OPTION, ""); - if (option.trim().equalsIgnoreCase(LITERAL)) { - result.addAttribute(OPTION, LITERAL); - line = in.readLine(); - result.setText(line.trim()); - } else { - result.setText(option); - } - - } - } - endPeek(); - return result; - } - - /** - * read options - * - * <pre> - * 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 - * </pre> - * - * @return Element - * @throws IOException - */ - public Element peekOption() throws IOException { - - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - if (line.matches("^(\\s*((--?)|(//?))\\w+([ =][<a-zA-Z][\\w-><]*)?)\\s*.*$")) { - result = DocumentHelper.createElement(OPTION_LIST) - .addAttribute(LEVEL, "" + level(line)); - char delimiter; - do { - Matcher matcher = Pattern.compile("[-/][-/]?.+").matcher(line); - matcher.find(); - Element option = result.addElement(OPTION); - String option_stringTmp = matcher.group(); - matcher = Pattern.compile("^[-/][-/]?\\w+").matcher(option_stringTmp); - matcher.find(); - String option_string = matcher.group(); - option.addAttribute(OPTIONSTRING, 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(DELIMITEREXISTE, FALSE); - - 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(DELIMITEREXISTE, TRUE); - option.addAttribute(DELIMITER, "" + 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(OPTIONARGUMENT, option_argument); - int size = option_argument.length() + 1; - if (option_stringTmp.length() < size && option_stringTmp.charAt(size) == ',') { - delimiter = ','; - } else { - done = true; - } - } else { // Si la description n'est pas sur la meme - // ligne - option_argument = option_stringTmp; - option.addAttribute(OPTIONARGUMENT, - option_argument); - line = in.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 - * - * <pre> - * -.. topic:: Title - * Body. - * </pre> - * - * @return Element - * @throws IOException - */ - private Element peekTopic() throws IOException { - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - if (line.matches("^\\.\\.\\s+(" + TOPIC + ")::\\s+(.*)$")) { - Matcher matcher = Pattern.compile(TOPIC + "::").matcher(line); - matcher.find(); - result = DocumentHelper.createElement(TOPIC).addAttribute( - LEVEL, "" + level(line)); - String title = line.substring(matcher.end(), line.length()); - result.addAttribute(TITLE, title); - line = in.readLine(); - if (line.matches("\\s*")) { - line = in.readLine(); - } - int level = level(line); - String[] lines = null; - if (level != 0) { - lines = in.readWhile("(^ {" + level + "}.*)|(\\s*)"); - String txt = line; - for (String txtTmp : lines) { - txt += "\n" + txtTmp.trim(); - } - result.setText(txt); - } - - } - } - - endPeek(); - return result; - } - - /** - * read sidebar - * - * <pre> - * .. sidebar:: Title - * :subtitle: If Desired - * Body. - * </pre> - * - * @return Element - * @throws IOException - */ - private Element peekSidebar() throws IOException { - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - if (line.matches("^\\.\\.\\s*(" + SIDEBAR + ")::\\s*(.*)$")) { - Matcher matcher = Pattern.compile(SIDEBAR + "::").matcher(line); - matcher.find(); - result = DocumentHelper.createElement(SIDEBAR).addAttribute( - LEVEL, "" + level(line)); - String title = line.substring(matcher.end(), line.length()); - result.addAttribute(TITLE, title); - line = in.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(SUBEXISTE, TRUE); - result.addAttribute(SUBTITLE, subTitle); - line = in.readLine(); - } else { - result.addAttribute(SUBEXISTE, FALSE); - } - String txt = joinBlock(readBlock(level(line))); - result.setText(txt); - - } - } - - endPeek(); - return result; - } - - /** - * read line block - * - * <pre> - * | 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? - * </pre> - * - * @return Element - * @throws IOException - */ - private Element peekLineBlock() throws IOException { - beginPeek(); - Element result = null; - String line = in.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.length; i++) { - lines[i + 1] = linesTmp[i]; - } - int[] levelsTmp = new int[lines.length]; - int levelmin = 999; - result = DocumentHelper.createElement(LINE_BLOCK).addAttribute( - LEVEL, 0 + ""); - for (int i = 0; i < levelsTmp.length; i++) { - // on enleve | - lines[i] = lines[i].replaceAll("\\|\\s?", ""); - } - for (int i = 0; i < levelsTmp.length; i++) { - // determination des levels - levelsTmp[i] = level(lines[i]); - } - for (int i : levelsTmp) { - // level minimal - levelmin = Math.min(levelmin, i); - } - 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.length; i++) { - Element eLine = result.addElement(LINE); - eLine.addAttribute(LEVEL, "" + levels[i]); - eLine.setText(lines[i].trim()); - } - } - } - endPeek(); - return result; - } - - /** - * read doctest block - * - * <pre> - * >>> print 'this is a Doctest block' - * this is a Doctest block - * </pre> - * - * @return Element - * @throws IOException - */ - private Element peekDoctestBlock() throws IOException { - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - if (line.matches("^\\s*>>>\\s.*")) { - int level = level(line); - result = DocumentHelper.createElement(DOCTEST_BLOCK) - .addAttribute(LEVEL, String.valueOf(level)); - result.addAttribute(XMLSPACE, "preserve"); - line += "\n" + joinBlock(readBlock(level)); - result.setText(line); - } - } - endPeek(); - return result; - } - - /** - * read block quote - * - * <pre> - * As a great paleontologist once said, - * - * This theory, that is mine, is mine. - * - * -- Anne Elk (Miss) - * </pre> - * - * @return Element - * @throws IOException - */ - private Element peekBlockQuote() throws IOException { - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - if (line.matches("\\s.*")) { - int level = level(line); - String savedLine = line + " " + joinBlock(readBlock(level)); - line = in.readLine(); - - if (line != null) { - level = level(line); - String blockQuote = null; - if (level != 0) { - String txt = line; - String[] lines = in.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(BLOCK_QUOTE) - .addAttribute(LEVEL, String.valueOf(level)); - if (blockQuote != null) { - result.addAttribute(ATTRIBUTION, blockQuote); - } - result.setText(savedLine + txt); - } - } - } - } - endPeek(); - return result; - } - - /** - * read admonitions : - * admonition|attention|caution|danger|error|hint|important|note|tip|warning - * - * <pre> - * .. Attention:: All your base are belong to us. - * .. admonition:: And, by the way... - * - * You can make up your own admonition too. - * </pre> - * - * @return Element - * @throws IOException - */ - protected Element peekAdmonition() throws IOException { - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - String lineTest = line.toLowerCase(); - Pattern pAdmonition = Pattern.compile("^\\s*\\.\\.\\s(" - + ADMONITION_PATTERN + ")::\\s*(.*)$"); - Matcher matcher = pAdmonition.matcher(lineTest); - - if (matcher.matches()) { - - boolean admonition = false; - matcher = Pattern.compile(ADMONITION_PATTERN).matcher(lineTest); - matcher.find(); - int level = level(line); - result = DocumentHelper.createElement(ADMONITION).addAttribute( - LEVEL, "" + level); - - if (matcher.group().equals(ADMONITION)) { // Il y a un titre - // pour un - // admonition - // general - admonition = true; - result.addAttribute(TYPE, ADMONITION); - String title = line.substring(matcher.end() + 2, line - .length()); - - result.addAttribute(TITLEATTR, title); - } else { - result.addAttribute(TYPE, matcher.group()); - } - - String firstLine = ""; - if (!admonition && matcher.end() + 2 < line.length()) { - firstLine = line - .substring(matcher.end() + 2, line.length()); - } - line = in.readLine(); - if (line != null) { - if (line.matches("\\s*")) { - line = in.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 - * - * @return Element - * @throws IOException - */ - public Element peekBlankLine() throws IOException { - beginPeek(); - Element result = null; - - // must have one blank line before - String line = in.readLine(); - if (line != null && line.matches("\\s*")) { - int level = level(line); - result = DocumentHelper.createElement(BLANK_LINE).addAttribute( - LEVEL, String.valueOf(level)); - } - - endPeek(); - return result; - } - - /** - * read directive or reference - * - * @return Element - * @throws IOException - */ - public Element peekDirectiveOrReference() throws IOException { - beginPeek(); - Element result = null; - String line = in.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(SUBSTITUTION_DEFINITION); - result.addAttribute(NAME, ref); - directive = result.addElement(DIRECTIVE); - } else { - result = DocumentHelper.createElement(DIRECTIVE); - directive = result; - } - result.addAttribute(LEVEL, "0"); - - directive.addAttribute(DIRECTIVE_TYPE, directiveType); - directive.addAttribute(DIRECTIVE_VALUE, directiveValue); - - String[] lines = readBlock(1); - String text = joinBlock(lines, "\n", false); - - directive.setText(text); - } - } - endPeek(); - return result; - } - - /** - * read transition - * - * @return Element - * @throws 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 = in.readLine(); - if (line != null && line.matches("\\s*")) { - // in.skipBlankLines(); - line = in.readLine(); - if (line != null && line.matches("-{3,}\\s*")) { - line = in.readLine(); - // must have one blank line after - if (line != null && line.matches("\\s*")) { - result = DocumentHelper.createElement(TRANSITION) - .addAttribute(LEVEL, String.valueOf(0)); - } - } - } - endPeek(); - return result; - } - - /** - * read paragraph with attribut level that represente the space numbers at - * left side - * - * @return <paragraph level="[int]">[text]</paragraph> - * @throws 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()); - - in.unread("::", true); - for(int i=0;i<level;i++) { - in.add(' '); - } - - literal = true; - } else if (para.endsWith("::")) { - para = para.substring(0, para.length() - ":".length()); // keep - // one - // : - - in.unread("::", true); - - for(int i=0;i<level;i++) { - in.add(' '); - } - - literal = true; - } - - if (para.length() == 0 || ":".equals(para)) { - if (literal) { - in.readLine(); // eat "::" - } - } else { - // if para is empty, there are error and possible - // infiny loop on para, force read next line - result = DocumentHelper.createElement(PARAGRAPH) - .addAttribute(LEVEL, String.valueOf(level)) - .addText(para); - } - } - } while (result == null && lines.length > 0); - - endPeek(); - return result; - } - - /** - * read literal block - * - * <pre> - * :: - * - * LiteralBlock - * </pre> - * - * @return Element - * @throws IOException - */ - public Element peekLiteralBlock() throws IOException { - beginPeek(); - - Element result = null; - // in.skipBlankLines(); - - - String[] prefix = in.readLines(2); - if (prefix.length == 2 && prefix[0].matches("\\s*::\\s*") - && prefix[1].matches("\\s*")) { - - int level = level(prefix[0]); - - String para = in.readLine(); - if (para != null) { - level=level+1; - para = para.substring(level) + "\n"; - - // it's literal block until level is down - String[] lines = in.readWhile("(^ {" + level + "}.*|\\s*)"); - while (lines.length > 0) { - for (String line : lines) { - if (!line.matches("\\s*")) { - para += line.substring(level) + "\n"; - } - else { - para += "\n"; - } - } - lines = in.readWhile("(^ {" + level + "}.*|\\s*)"); - } - - result = DocumentHelper.createElement(LITERAL_BLOCK) - .addAttribute(LEVEL, String.valueOf(level)).addText( - para); - } - } - - endPeek(); - return result; - } - - /** - * read doc info author, date, version, ... - * - * <pre> - * :author: Benjamin Poussin - * :address: - * Quelque part - * Dans le monde - * </pre> - * - * @return Element - * @throws IOException - */ - public Element peekDocInfoItem() throws IOException { - beginPeek(); - - Element result = null; - // in.skipBlankLines(); - String line = in.readLine(); - // (?i) case inensitive on docinfo item - if (line != null && line.matches("^:((?i)" + DOCINFO_ITEM + "):.*$")) { - - result = DocumentHelper.createElement(DOCINFO); - result.addAttribute(LEVEL, "0"); - String infotype = line.substring(1, line.indexOf(":", 1)); - - /* - * if (!in.eof()) { String [] content = readBlock(1); line += - * joinBlock(content); } - */ - String text = line.substring(line.indexOf(":", 1) + 1).trim(); - String[] textTmp = in.readWhile("^\\s+.*"); - if (textTmp.length != 0) { - in.mark(); - } - - for (String txt : textTmp) { - text += "\n" + txt.trim(); - } - - // CVS, RCS support - text = text.replaceAll("\\$\\w+: (.+?)\\$", "$1"); - - result.addAttribute(TYPE, infotype).addText(text); - } - endPeek(); - return result; - } - - /** - * read table simple and complexe - * - * <pre> - * +------------------------+------------+----------+----------+ - * | Header row, column 1 | Header 2 | Header 3 | Header 4 | - * | (header rows optional) | | | | - * +========================+============+==========+==========+ - * | body row 1, column 1 | column 2 | column 3 | column 4 | - * +------------------------+------------+----------+----------+ - * | body row 2 | Cells may span columns. | - * +------------------------+------------+---------------------+ - * </pre> - * - * @return Element - * @throws IOException - */ - @SuppressWarnings("unchecked") - public Element peekTable() throws IOException { - beginPeek(); - - Element result = null; - // in.skipBlankLines(); - String line = in.readLine(); - - if (line != null) { - Pattern pTableBegin = Pattern.compile("^\\s*(\\+-+)+\\+\\s*$"); - Matcher matcher = null; - - matcher = pTableBegin.matcher(line); - if (matcher.matches()) { // complexe table - result = DocumentHelper.createElement(TABLE); - result.addAttribute(TABLE_HEADER, FALSE); - int level = level(line); - result.addAttribute(LEVEL, String.valueOf(level)); - line = line.trim(); - int tableWidth = line.length(); - result.addAttribute(TABLE_WIDTH, String.valueOf(tableWidth)); - - Pattern pCellEnd = Pattern - .compile("^\\s{" - + level - + "}(\\+-+\\+|\\|(?:[^+]+))([^+]+(?:\\+|\\|\\s*$)|-+\\+)*\\s*"); // fin - // de - // ligne - Pattern pCell = Pattern.compile("^\\s{" + level - + "}(\\|[^|]+)+\\|\\s*$"); // une ligne - Pattern pHeader = Pattern.compile("^\\s{" + level - + "}(\\+=+)+\\+\\s*$"); // fin du header - Pattern pEnd = Pattern.compile("^\\s{" + level - + "}(\\+-+)+\\+\\s*$"); // fin de table - - // used to know if | is cell separator or not - String lastSeparationLine = line; - String lastLine = line; - - Element row = DocumentHelper.createElement(ROW); - String[] table = in.readUntilBlank(); - - boolean done = false; - for (String l : table) { - done = false; - l = l.trim(); - if (l.length() != tableWidth) { - // Erreur dans la table, peut-etre lever une exception ? - result = null; - break; - } - matcher = pEnd.matcher(l); - if (!done && matcher.matches()) { - // fin normale de ligne, on peut directement l'assigner - lastSeparationLine = l; - for (Element cell : (List<Element>) row.elements()) { - cell.addAttribute(CELL_END, TRUE); - } - row.addAttribute(ROW_END_HEADER, FALSE); - result.add(row); - row = DocumentHelper.createElement(ROW); - done = true; - } - matcher = pHeader.matcher(l); - if (!done && matcher.matches()) { - // fin de du header, on peut directement l'assigner - lastSeparationLine = l; - for (Element cell : (List<Element>) row.elements()) { - cell.addAttribute(CELL_END, TRUE); - } - row.addAttribute(ROW_END_HEADER, TRUE); - result.add(row); - result.addAttribute(TABLE_HEADER, TRUE); - row = DocumentHelper.createElement(ROW); - done = true; - } - matcher = pCell.matcher(l); - if (!done && matcher.matches()) { - // debug - row.addAttribute("debug", "pCell"); - // recuperation des textes des cellules - int start = -1; - String content = ""; - matcher = Pattern.compile("([^|]+)\\|").matcher(l); - for (int cellNumber = 0; matcher.find(); cellNumber++) { - int tmpstart = matcher.start(1); - int end = matcher.end(1); - String tmpcontent = matcher.group(1); - // on a forcement un | ou un + au dessus du + - // et forcement un + sur lastSeparationLine - // sinon ca veut dire qu'il y avait un | dans la - // cell - if ((lastLine.charAt(end) == '|' || lastLine - .charAt(end) == '+') - && lastSeparationLine.charAt(end) == '+') { - if ("".equals(content)) { - content = tmpcontent; - } - else { - content += tmpcontent; - } - if (start == -1) { - start = tmpstart; - } - Element cell = null; - if (row.nodeCount() <= cellNumber) { - cell = row.addElement(CELL); - cell.addAttribute(CELL_END, FALSE); - } else { - cell = (Element) row.node(cellNumber); - } - cell.addAttribute(CELL_INDEX_START, String - .valueOf(start)); - cell.addAttribute(CELL_INDEX_END, String - .valueOf(end)); - cell.setText(cell.getText() + content + "\n"); - start = end + 1; // +1 to pass + or | at end - // of cell - content = ""; - } else { - // start = tmpstart; - if (start == -1) { - start = tmpstart; - } - content += tmpcontent + "|"; - cellNumber--; - } - } - done = true; - } - matcher = pCellEnd.matcher(l); - if (!done && matcher.matches()) { - // debug - row.addAttribute("debug", "pCellEnd"); - // fin d'une ligne, on ne peut pas l'assigner - // directement - // pour chaque continuation de cellule, il faut copier - // l'ancienne valeur - - // mais on commence tout de meme par fermer tout les - // cells - for (Element cell : (List<Element>) row.elements()) { - cell.addAttribute(CELL_END, TRUE); - } - - StringBuffer tmp = new StringBuffer(l); - int start = -1; - String content = ""; - matcher = Pattern.compile("([^+|]+|-+)([+|])").matcher( - l); - for (int cellNumber = 0; matcher.find(); cellNumber++) { - int tmpstart = matcher.start(1); - int end = matcher.end(1); - String tmpcontent = matcher.group(1); - String ender = matcher.group(2); - if (!tmpcontent.matches("-+")) { - // on a forcement un | au dessus du + ou du | - // sinon ca veut dire qu'il y avait un + dans la - // cell - if (lastLine.charAt(end) == '|') { - if (start == -1) { - start = tmpstart; - } - // -1 and +1 to take the + or | at begin and - // end - String old = lastSeparationLine.substring( - start - 1, end + 1); - tmp.replace(start - 1, end + 1, old); - if ("".equals(content)) { - content = tmpcontent; - } - Element cell = null; - if (row.nodeCount() <= cellNumber) { - cell = row.addElement(CELL); - } else { - cell = (Element) row.node(cellNumber); - - } - cell.setText(cell.getText() + content - + "\n"); - // on a ajouter des choses dans la cell, - // donc - // ce n'est pas la fin - cell.addAttribute(CELL_END, FALSE); - cell.addAttribute(CELL_INDEX_START, String - .valueOf(start)); - cell.addAttribute(CELL_INDEX_END, String - .valueOf(end)); - start = end + 1; // +1 to pass + or | at - // end of cell - content = ""; - } else { - // start = tmpstart; - content += tmpcontent + ender; - } - } - } - lastSeparationLine = tmp.toString(); - row.addAttribute(ROW_END_HEADER, FALSE); - result.add(row); - row = DocumentHelper.createElement(ROW); - done = true; - } - if (!done) { - log.warn("Bad table format line " + in.getLineNumber()); - } - lastLine = l; - } - - // - // line += "\n" + joinBlock(table, "\n", false); - // - // result.addText(line); - } else if (line.matches("^\\s*(=+ +)+=+\\s*$")) { - // Les donnees de la table peuvent depasser de celle-ci - /* - * ===== ===== ====== Inputs Output ------------ ------ A B A or - * B ===== ===== ====== False False Second column of row 1. True - * False Second column of row 2. - * - * True 2 - Second column of row 3. - * - * - Second item in bullet list (row 3, column 2). ============ - * ====== - */ - - result = DocumentHelper.createElement(TABLE); - line = line.trim(); - Pattern pBordersEquals = Pattern.compile("^\\s*(=+ +)+=+\\s*$"); // Separation - // = - Pattern pBordersTiret = Pattern.compile("^\\s*(-+ +)+-+\\s*$"); // Separation - // - - Pattern pBorders = Pattern.compile("^\\s*([=-]+ +)+[=-]+\\s*$"); // = - // ou - // - - String[] table = in.readUntilBlank(); // Recuperation de la - // table - - int tableWidth = line.length(); - int nbSeparations = 0; - for (String l : table) { - if (l.length() > tableWidth) { - tableWidth = l.length(); // Determination de la - } // Determination de la - // longueur max - matcher = pBordersEquals.matcher(l); - if (matcher.matches()) { - nbSeparations++; - } - - } - // Header if the table contains 3 equals separations - result.addAttribute(TABLE_HEADER, "" + (nbSeparations == 2)); - int level = level(line); - result.addAttribute(LEVEL, String.valueOf(level)); - result - .addAttribute(TABLE_WIDTH, String - .valueOf(tableWidth + 1)); - Element row = DocumentHelper.createElement(ROW); - // Determination of the columns positions - List<Integer> columns = new LinkedList<Integer>(); - matcher = Pattern.compile("=+\\s+").matcher(line); - for (int cellNumber = 0; matcher.find(); cellNumber++) { - columns.add(matcher.end()); - } - columns.add(tableWidth); - - // Traitement du tbl - /* - * ===== ===== ====== Inputs Output ------------ ------ A B A or - * B ===== ===== ====== False False Second column of row 1. True - * False Second column of row 2. - * - * True 2 - Second column of row 3. - * - * - Second item in bullet list (row 3, column 2). ============ - * ====== devient l'equivalent : ===== ===== ====== Inputs - * Output ------------ ------ A B A or B ===== ===== ====== - * False False Second column of row 1. ----- ----- ------ True - * False Second column of row 2. ----- ----- ------ True 2 - - * Second column of row 3. - Second item in bullet list (row 3, - * column 2). ============ ====== - */ - String lineRef = line.replace('=', '-'); - Matcher matcher2; - List<String> tableTmp = new LinkedList<String>(); - - for (int i = 0; i < table.length - 1; i++) { - tableTmp.add(table[i]); - if (!table[i].equals("")) { - if (!table[i + 1] - .substring(0, columns.get(0)) - .matches("\\s*")) { - matcher = pBorders.matcher(table[i]); - matcher2 = pBorders.matcher(table[i + 1]); - if (!matcher.matches() && !matcher2.matches() - && !table[i + 1].equals("")) { - tableTmp.add(lineRef); - } - } - } - } - tableTmp.add(table[table.length - 1]); - table = new String[tableTmp.size()]; - for (int i = 0; i < tableTmp.size(); i++) { - table[i] = tableTmp.get(i); - } - - boolean done = false; - LinkedList<String> lastLines = new LinkedList<String>(); - int separation = 1; - for (String l : table) { - if (l != null) { - done = false; - matcher = pBordersTiret.matcher(l); - matcher2 = pBordersEquals.matcher(l); - if (matcher.matches() || matcher2.matches()) { // Intermediate - // separation - while (!lastLines.isEmpty()) { - matcher = Pattern.compile("[-=]+\\s*").matcher( - l); - String tmpLine = lastLines.getLast(); - lastLines.removeLast(); - int cellNumber; - for (cellNumber = 0; matcher.find(); cellNumber++) { - Element cell = null; - if (row.nodeCount() <= cellNumber) { - cell = row.addElement(CELL); - } else { - cell = (Element) row.node(cellNumber); - } - if (matcher.start() < tmpLine.length()) { - if (columns.size() - 1 == cellNumber) { - cell.setText(tmpLine.substring( - matcher.start(), tmpLine - .length()) - + "\n"); - } else { - if (matcher.end() < tmpLine - .length()) { - cell.setText(tmpLine.substring(matcher.start(), matcher.end()) + "\n"); - } - else { - cell.setText(tmpLine.substring(matcher.start(), tmpLine.length()) + "\n"); - } - } - } - - if (lastLines.size() == 0) { - row.addAttribute("debug", "pCell"); - cell.addAttribute(CELL_END, TRUE); - } else { - row.addAttribute("debug", "pCellEnd"); - cell.addAttribute(CELL_END, FALSE); - } - cell.addAttribute(CELL_INDEX_START, String - .valueOf(matcher.start() + 1)); - if (line.length() == matcher.end()) { - cell.addAttribute(CELL_INDEX_END, String.valueOf(columns.get(columns.size() - 1))); - } - else { - cell.addAttribute(CELL_INDEX_END, String.valueOf(matcher.end())); - } - } - - if (matcher2.matches()) { - separation++; - row.addAttribute(ROW_END_HEADER, "" - + (separation == 2)); - } else { - row.addAttribute(ROW_END_HEADER, FALSE); - } - - result.add(row); - row = DocumentHelper.createElement(ROW); - done = true; - } - } - if (!done && l.matches("^\\s*(.+ +)+.+\\s*$")) { - // Data - lastLines.addFirst(l); // Les donnees sont stoquee - // dans une file d'attente - // lastLines (FIFO) - done = true; - } - if (!done) { - log.warn("Bad table format line " - + in.getLineNumber()); - } - } - } - } - } - endPeek(); - - return result; - } - - /** - * read list - * - * <pre> - * - first line - * - next line - * </pre> - * - * @return <bullet_list level="[int]" - * bullet="char"><[text];</bullet_list> - * @throws IOException - */ - public Element peekBulletList() throws IOException { - beginPeek(); - - Element result = null; - // in.skipBlankLines(); - String line = in.readLine(); - if (line != null - && line.matches("^\\s*[" + escapeRegex(BULLET_CHAR) - + "] +\\S.*")) { - int level = level(line); - String bullet = line.substring(level, level + 1); - - result = DocumentHelper.createElement(BULLET_LIST).addAttribute( - LEVEL, String.valueOf(level)).addAttribute(BULLET, - bullet); - - if (!in.eof()) { - String[] content = readBlock(level + 1); - line += " " + joinBlock(content); - } - String text = line.substring(level + 1).trim(); - - result.addText(text); - in.skipBlankLines(); - } - - endPeek(); - return result; - } - - /** - * read field list - * - * <pre> - * :first: text - * :second: text - * and other text - * :last empty: - * </pre> - * - * @return <field_list level="[int]" - * name="[text]">[text]</field_list> - * @throws IOException - */ - public Element peekFieldList() throws IOException { - beginPeek(); - - Element result = null; - // in.skipBlankLines(); - String line = in.readLine(); - if (line != null) { - Pattern pattern = Pattern.compile("^\\s*:([^:]+): [^\\s].*"); - Matcher matcher = pattern.matcher(line); - if (matcher.matches()) { - int level = level(line); - String name = matcher.group(1); - int begin = matcher.end(1) + 1; - - result = DocumentHelper.createElement(FIELD_LIST).addAttribute( - LEVEL, String.valueOf(level)).addAttribute(NAME, - name); - - if (!in.eof()) { - String[] content = readBlock(level + 1); - line += " " + joinBlock(content); - } - String text = line.substring(begin).trim(); - - result.addText(text); - } - } - - endPeek(); - return result; - } - - /** - * read definition list - * - * <pre> - * un autre mot - * une autre definition - * le mot : la classe - * la definition - * le mot : la classe 1 : la classe 2 - * la definition - * </pre> - * - * @return <definition_list level="[int]" term="[text]" - * classifiers="[text]">[text]</definition_list> - * @throws IOException - */ - public Element peekDefinitionList() throws IOException { - beginPeek(); - - Element result = null; - // in.skipBlankLines(); - String[] lines = in.readLines(2); - if (lines.length == 2) { - int level = level(lines[0]); - int levelDef = level(lines[1]); - if ((levelDef != lines[1].length()) && (level < levelDef)) { - in.unread(lines[1], true); - Pattern pattern = Pattern.compile("^\\s*([^:]+)(?: : (.*))?"); - Matcher matcher = pattern.matcher(lines[0]); - if (matcher.matches()) { - String term = matcher.group(1); - String classifiers = matcher.group(2); - - result = DocumentHelper.createElement(DEFINITION_LIST) - .addAttribute(LEVEL, String.valueOf(level)) - .addAttribute(TERM, term).addAttribute( - CLASSIFIERS, classifiers); - - // poussin 20070207 don't read block here because can't - // interpret it correctly in JRSTReader - // if (!in.eof()) { - // String [] content = readBlock(level + 1); - // String text = joinBlock(content); - // result.addText(text); - // } - } - } - } - - endPeek(); - return result; - } - - /** - * read enumarted list - * - * can be: <li>1, 2, 3, ... <li>a, b, c, ... <li>A, B, C, ... <li>i, ii, - * iii, iv, ... <li>I, II, III, IV, ... - * - * or # for auto-numbered - * - * <pre> - * - * 1. next line 1) next line (1) first line - * - * </pre> - * - * @return <enumerated_list level="[int]" start="[number]" - * prefix="[char]" suffix="[char]" - * enumtype="[(arabic|loweralpha|upperalpha|lowerroman|upperroman]"> - * ;[text]</enumerated_list> - * @throws IOException - */ - public Element peekEnumeratedList() throws IOException { - beginPeek(); - - Element result = null; - // in.skipBlankLines(); - - String line = in.readLine(); - if (line != null) { - Pattern pattern = Pattern - .compile("^\\s*(\\(?)(#|\\d+|[a-z]|[A-Z]|[ivxlcdm]+|[IVXLCDM]+)([\\.)]) [^\\s].*"); - Matcher matcher = pattern.matcher(line); - if (matcher.matches()) { - int level = level(line); - String prefix = matcher.group(1); - String start = matcher.group(2); - String suffix = matcher.group(3); - int begin = matcher.end(3); - - // arabic|loweralpha|upperalpha|lowerroman|upperroman - String enumtype = "auto"; - if (start.matches("\\d+")) { - enumtype = "arabic"; - } else if (start.matches("(i|[ivxlcdm][ivxlcdm]+)")) { - enumtype = "lowerroman"; - start = "1"; // TODO transform romain to arabic - } else if (start.matches("(I|[IVXLCDM][IVXLCDM]+)")) { - enumtype = "upperroman"; - start = "1"; // TODO transform romain to arabic - } else if (start.matches("[a-z]+")) { - enumtype = "loweralpha"; - start = String.valueOf((int) start.charAt(0) - (int) 'a'); - } else if (start.matches("[A-Z]+")) { - enumtype = "upperalpha"; - start = String.valueOf((int) start.charAt(0) - (int) 'A'); - } - - result = DocumentHelper.createElement(ENUMERATED_LIST) - .addAttribute(LEVEL, String.valueOf(level)) - .addAttribute(START, start).addAttribute(PREFIX, - prefix).addAttribute(SUFFIX, suffix) - .addAttribute(ENUMTYPE, enumtype); - - if (line.endsWith(": ::")) { - line = line.substring(0, line.length() - " ::".length()); - in.unread("::", true); - - } else if (line.endsWith("::")) { - line = line.substring(0, line.length() - ":".length()); // keep - // one - // : - in.unread("::", true); - } - - - if (!in.eof()) { - String[] content = readBlock(level + 1); - String tempLine = " " + joinBlock(content); - - if (tempLine.endsWith(": ::")) { - tempLine = tempLine.substring(0, tempLine.length() - " ::".length()); - in.unread("::", true); - - } else if (tempLine.endsWith("::")) { - tempLine = tempLine.substring(0, tempLine.length() - ":".length()); // keep - // one - // : - in.unread("::", true); - } - - line+=tempLine; - - - } - String text = line.substring(begin).trim(); - - result.addText(text); - in.skipBlankLines(); - } - } - - endPeek(); - return result; - } - - /** - * Parse un titre simple ou double - * - * simple: - * - * <pre> - * - * Le titre ======== - * - * </pre> - * - * double: - * - * <pre> - * - * ============ le titre ============ - * - * </pre> - * - * @return <title level="[int]" type="[simple|double]" char="[underline - * char]"> - * @throws IOException - */ - public Element peekTitle() throws IOException { - beginPeek(); - - Element result = null; - // in.skipBlankLines(); - String line = in.readLine(); - - if (line != null) { - if (startsWithTitleChar(line)) { - String[] titles = in.readLines(2); - if (titles.length == 2 && line.length() >= titles[0].length() - && line.length() == titles[1].length() - && line.equals(titles[1])) { - result = DocumentHelper.createElement(TITLE).addAttribute( - TYPE, "double").addAttribute(CHAR, - titles[1].substring(0, 1)).addText(titles[0]); - } - } else { - String title = in.readLine(); - if (title != null - && startsWithTitleChar(title) - && line.replaceFirst("\\s*$", "").length() == title - .length()) { - - result = DocumentHelper.createElement(TITLE).addAttribute( - TYPE, "simple").addAttribute(CHAR, - title.substring(0, 1)).addText( - line.replaceFirst("\\s*$", "")); - } - } - } - - if (result != null) { - // add level information - String titleLevel = result.attributeValue(CHAR); - - if ("double".equals(result.attributeValue(TYPE))) { - titleLevel += titleLevel; - } - int level = titleLevels.indexOf(titleLevel); - if (level == -1) { - level = titleLevels.size(); - titleLevels.add(titleLevel); - } - result.addAttribute(LEVEL, String - .valueOf(JRSTReader.MAX_SECTION_DEPTH + level)); - } - - endPeek(); - return result; - } - - public Element peekTarget() throws IOException { - beginPeek(); - - String line = in.readLine(); - Element result = null; - if (line != null) { - if (line.matches("^\\s*\\.\\.\\s_[^_:].+:.*")) { - result = DocumentHelper.createElement(TARGET); - Matcher matcher = Pattern.compile("\\.\\.\\s_").matcher(line); - if (matcher.find()) { - int i = line.indexOf(':'); - result.addAttribute(ID, URLEncoder.encode(line.substring(matcher.end(), i) - .toLowerCase().replaceAll(" ", "-"), "UTF-8")); - result.addAttribute(LEVEL, "" + level(line)); - } - } - } - endPeek(); - return result; - } - - /** - * .. _frungible doodads: http://www.example.org/ - * - * @return Element - * @throws IOException - */ - public LinkedList<Element> refTarget() throws IOException { - beginPeek(); - - String[] lines = in.readAll(); - LinkedList<Element> result = new LinkedList<Element>(); - for (String line : lines) { - if (line.matches("^\\s*\\.\\.\\s_[^_:].+:.*")) { - result.add(DocumentHelper.createElement(TARGET)); - Matcher matcher = Pattern.compile("\\.\\.\\s_").matcher(line); - if (matcher.find()) { - boolean done = false; - for (int i = matcher.end(); i < line.length() && !done; i++) { - if (line.charAt(i) == ':') { - result.getLast().addAttribute(LEVEL, - "" + level(line)); - result.getLast().addAttribute( - ID, - URLEncoder.encode(line.substring(matcher.end(), i) - .replaceAll(" ", "-").toLowerCase(), "UTF-8")); - result.getLast().addAttribute( - NAME, - line.substring(matcher.end(), i) - .toLowerCase()); - if (i + 2 > line.length()) { - line = in.readLine(); - // FIXME 20071129 chatellier - // line = null if link is non well formed - // .. _Unifying types and classes in Python: - // miss uri - if (line == null) { - line = ""; - } - result.getLast().addAttribute(REFURI, - line.trim()); - } else { - result.getLast().addAttribute(REFURI, line.substring(i + 2, line.length())); - } - - done = true; - } - } - } - } - } - endPeek(); - return result; - } - - /** - * .. __: http://www.python.org - * - * @return Element - * @throws IOException - */ - private Element peekTargetAnonymousBody() throws IOException { - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - if (line.matches("^\\s*__ .+$|^\\s*\\.\\. __\\:.+$")) { - result = DocumentHelper.createElement(TARGETANONYMOUS); - result.addAttribute(LEVEL, "" + level(line)); - - } - } - - endPeek(); - return result; - } - - /** - * .. comment - * - * @return Element - * @throws IOException - */ - private Element peekComment() throws IOException { - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - if (line.matches("^\\.\\.\\s+.*$")) { - result = DocumentHelper.createElement(COMMENT); - result.addAttribute(LEVEL, "0"); - result.addAttribute(XMLSPACE, "preserve"); - - // first line is part of comment - result.setText(line.substring(2).trim()); - line = in.readLine(); - if(line != null) { - int level = level(line); - if (level > 0) { - String[] lines = readBlock(level); - String text = line.substring(level); - for (String l : lines) { - text += "\n" + l.substring(level); - } - result.addText(text); - } - } - } - } - - endPeek(); - return result; - } - - /** - * .. comment - * - * @return Element - * @throws IOException - */ - public List<Element> peekAllComment() throws IOException { - beginPeek(); - List<Element> result = new ArrayList<Element>(); - String[] lines = in.readWhile("^\\.\\.\\s*.*$"); - if (lines != null) { -// int levelRef = level(line); - for (String line : lines) { - Element comment = DocumentHelper.createElement(COMMENT); - comment.addAttribute(LEVEL, "0"); - comment.addAttribute(XMLSPACE, "preserve"); - - // first line is part of comment - comment.setText(line.substring(2).trim()); - result.add(comment); - -// int level = level(line); -// if (level == levelRef) { -// String[] lines = readBlock(level); -// String text = line.substring(level); -// for (String l : lines) { -// text += "\n" + l.substring(level); -// } -// result.addText(text); -// } - } - in.mark(); - } - - endPeek(); - return result; - } - - /** - * .. _frungible doodads: http://www.example.org/ - * - * @return Element - * @throws IOException - */ - public Element peekFootnote() throws IOException { - beginPeek(); - Element result = null; - String line = in.readLine(); - if (line != null) { - if (line.matches("^\\s*\\.\\.\\s\\[(#|[0-9]|\\*).*\\]\\s.+$")) { - result = DocumentHelper.createElement(FOOTNOTES); - boolean bLine = false; - do { - - bLine = false; - Element footnote = result.addElement(FOOTNOTE); - Matcher matcher = Pattern.compile("\\.\\.\\s\\[").matcher( - line); - - if (matcher.find()) { - - boolean done = false; - for (int i = matcher.end(); i < line.length() && !done; i++) { - if (line.charAt(i) == ']') { - - result.addAttribute(LEVEL, "" + level(line)); - String id = line.substring(matcher.end(), i); - if (id.matches("\\*")) { - footnote.addAttribute(TYPE, AUTOSYMBOL); - } else if (id.matches("[0-9]")) { - footnote.addAttribute(TYPE, NUM); - footnote.addAttribute(NAME, id); - } else if (id.equals("#")) { - footnote.addAttribute(TYPE, AUTONUM); - } else { - footnote.addAttribute(TYPE, - AUTONUMLABEL); - footnote.addAttribute(NAME, id - .substring(1)); - } - String text = line.substring(i + 2, line - .length()); - - int levelAv = level(line); - line = in.readLine(); - if (line != null) { - if (line - .matches("^\\s*\\.\\.\\s\\[(#|[0-9]|\\*).*\\]\\s.+$")) { - bLine = true; - } else { - - int level = level(line); - if (levelAv < level) { - String[] lines = in - .readWhile("(^ {" + level - + "}.*)|(\\s*)"); - text += "\n" + line.trim(); - for (String l : lines) { - text += "\n" + l.trim(); - } - - } else if (line.matches("\\s*")) { - level = levelAv + 1; - String[] lines = in - .readWhile("(^ {" + level - + "}.*)|(\\s*)"); - text += "\n" + line.trim(); - for (String l : lines) { - text += "\n" + l.trim(); - } - - } - } - if (!bLine) { - in.skipBlankLines(); - String[] linesTmp = in - .readWhile("^\\s*\\.\\.\\s\\[(#|[0-9]|\\*).*\\]\\s.+$"); - - if (linesTmp.length > 0) { - line = linesTmp[0]; - bLine = true; - } - } - - } - if (line == null) { - line = ""; - } - footnote.setText(text); - done = true; - } - - } - } - - } while (bLine); - } - } - endPeek(); - return result; - } - - /** - * Read block text, block text have same indentation - * - * @param minLeftMargin - * min left blank needed to accept to read block - * @return String - * @throws IOException - */ - private String readBlockWithBlankLine(int level) throws IOException { - String txt = ""; - String[] lines = in.readWhile("(^ {" + level + "}.*)|(\\s*)"); - while (lines.length > 0) { - for (String l : lines) { - l = l.trim(); - txt += l + "\n"; - - } - lines = in.readWhile("(^ {" + level + "}.*)|(\\s*)"); - } - return txt; - } - - /** - * Lit les premieres ligne non vide et les retourne, rien n'est modifier par - * rapport aux positions dans le fichier. Util pour afficher a l'utilisateur - * les lignes qui ont produit une erreur - * - * @return les lignes non vides - * @throws IOException - */ - public String readNotBlanckLine() throws IOException { - beginPeek(); - in.skipBlankLines(); - String line = joinBlock(in.readUntilBlank(), "\n", false); - endPeek(); - return line; - } - - /** - * return the number of line read - * - * @return int - */ - public int getLineNumber() { - return in.getLineNumber(); - } - - /** - * return the number of char read - * - * @return int - */ - public int getCharNumber() { - return in.getCharNumber(); - } - - /** - * return true if line can be underline or overline for title - * - * @param line - * @return boolean - */ - private boolean startsWithTitleChar(String line) { - if (line == null || line.length() < 2) { - return false; - } - // est-ce que la ligne est constituer entierement du meme caractere et - // qu'il y en a au moins 2 - boolean result = line - .matches("([" + escapeRegex(TITLE_CHAR) + "])\\1+"); - return result; - } - - /** - * @param title_charescapeRegex - * @return String - */ - private String escapeRegex(String text) { - String result = text.replaceAll("([()[\\\\]*+?.])", "\\\\$1"); - return result; - } - - /** - * @param String - * line - * @return int - * @throws IOException - */ - private int level(String line) { - int result = 0; - String sTmp = line.replaceAll("\\s", " "); - while (sTmp.length() > result && sTmp.charAt(result) == ' ') { - result++; - } - return result; - } -} Deleted: branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRSTReader.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRSTReader.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/main/java/org/nuiton/jrst/JRSTReader.java 2012-04-24 09:23:11 UTC (rev 644) @@ -1,2418 +0,0 @@ -/* - * #%L - * JRst :: Api - * - * $Id$ - * $HeadURL$ - * %% - * 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% - */ - -/* * - * JRSTReader.java - * - * Created: 27 oct. 06 00:15:34 - * - * @author poussin - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - */ - -package org.nuiton.jrst; - -import static org.nuiton.i18n.I18n._; -import static org.nuiton.jrst.ReStructuredText.ADDRESS; -import static org.nuiton.jrst.ReStructuredText.ADMONITION; -import static org.nuiton.jrst.ReStructuredText.ATTRIBUTION; -import static org.nuiton.jrst.ReStructuredText.AUTHOR; -import static org.nuiton.jrst.ReStructuredText.AUTHORS; -import static org.nuiton.jrst.ReStructuredText.BLOCK_QUOTE; -import static org.nuiton.jrst.ReStructuredText.BULLET_LIST; -import static org.nuiton.jrst.ReStructuredText.COLSPEC; -import static org.nuiton.jrst.ReStructuredText.COMMENT; -import static org.nuiton.jrst.ReStructuredText.CONTACT; -import static org.nuiton.jrst.ReStructuredText.COPYRIGHT; -import static org.nuiton.jrst.ReStructuredText.DATE; -import static org.nuiton.jrst.ReStructuredText.DECORATION; -import static org.nuiton.jrst.ReStructuredText.DEFINITION; -import static org.nuiton.jrst.ReStructuredText.DEFINITION_LIST; -import static org.nuiton.jrst.ReStructuredText.DEFINITION_LIST_ITEM; -import static org.nuiton.jrst.ReStructuredText.DESCRIPTION; -import static org.nuiton.jrst.ReStructuredText.DOCINFO; -import static org.nuiton.jrst.ReStructuredText.DOCTEST_BLOCK; -import static org.nuiton.jrst.ReStructuredText.DOCUMENT; -import static org.nuiton.jrst.ReStructuredText.EMPHASIS; -import static org.nuiton.jrst.ReStructuredText.ENTRY; -import static org.nuiton.jrst.ReStructuredText.ENUMERATED_LIST; -import static org.nuiton.jrst.ReStructuredText.FIELD; -import static org.nuiton.jrst.ReStructuredText.FIELD_BODY; -import static org.nuiton.jrst.ReStructuredText.FIELD_LIST; -import static org.nuiton.jrst.ReStructuredText.FIELD_NAME; -import static org.nuiton.jrst.ReStructuredText.FOOTER; -import static org.nuiton.jrst.ReStructuredText.FOOTNOTE; -import static org.nuiton.jrst.ReStructuredText.FOOTNOTE_REFERENCE; -import static org.nuiton.jrst.ReStructuredText.FOOTNOTE_SYMBOL; -import static org.nuiton.jrst.ReStructuredText.GENERATED; -import static org.nuiton.jrst.ReStructuredText.HEADER; -import static org.nuiton.jrst.ReStructuredText.IMAGE; -import static org.nuiton.jrst.ReStructuredText.LABEL; -import static org.nuiton.jrst.ReStructuredText.LINE; -import static org.nuiton.jrst.ReStructuredText.LINE_BLOCK; -import static org.nuiton.jrst.ReStructuredText.LIST_ITEM; -import static org.nuiton.jrst.ReStructuredText.LITERAL; -import static org.nuiton.jrst.ReStructuredText.LITERAL_BLOCK; -import static org.nuiton.jrst.ReStructuredText.OPTION; -import static org.nuiton.jrst.ReStructuredText.OPTION_ARGUMENT; -import static org.nuiton.jrst.ReStructuredText.OPTION_GROUP; -import static org.nuiton.jrst.ReStructuredText.OPTION_LIST; -import static org.nuiton.jrst.ReStructuredText.OPTION_LIST_ITEM; -import static org.nuiton.jrst.ReStructuredText.OPTION_STRING; -import static org.nuiton.jrst.ReStructuredText.ORGANIZATION; -import static org.nuiton.jrst.ReStructuredText.PARAGRAPH; -import static org.nuiton.jrst.ReStructuredText.REFERENCE; -import static org.nuiton.jrst.ReStructuredText.REGEX_ANONYMOUS_HYPERLINK_REFERENCE; -import static org.nuiton.jrst.ReStructuredText.REGEX_EMAIL; -import static org.nuiton.jrst.ReStructuredText.REGEX_EMPHASIS; -import static org.nuiton.jrst.ReStructuredText.REGEX_FOOTNOTE_REFERENCE; -import static org.nuiton.jrst.ReStructuredText.REGEX_HYPERLINK_REFERENCE; -import static org.nuiton.jrst.ReStructuredText.REGEX_INLINE_REFERENCE; -import static org.nuiton.jrst.ReStructuredText.REGEX_LITERAL; -import static org.nuiton.jrst.ReStructuredText.REGEX_REFERENCE; -import static org.nuiton.jrst.ReStructuredText.REGEX_STRONG; -import static org.nuiton.jrst.ReStructuredText.REGEX_SUBSTITUTION_REFERENCE; -import static org.nuiton.jrst.ReStructuredText.REVISION; -import static org.nuiton.jrst.ReStructuredText.ROW; -import static org.nuiton.jrst.ReStructuredText.SECTION; -import static org.nuiton.jrst.ReStructuredText.SIDEBAR; -import static org.nuiton.jrst.ReStructuredText.STATUS; -import static org.nuiton.jrst.ReStructuredText.STRONG; -import static org.nuiton.jrst.ReStructuredText.SUBSTITUTION_DEFINITION; -import static org.nuiton.jrst.ReStructuredText.SUBTITLE; -import static org.nuiton.jrst.ReStructuredText.TABLE; -import static org.nuiton.jrst.ReStructuredText.TARGET; -import static org.nuiton.jrst.ReStructuredText.TBODY; -import static org.nuiton.jrst.ReStructuredText.TERM; -import static org.nuiton.jrst.ReStructuredText.TGROUP; -import static org.nuiton.jrst.ReStructuredText.THEAD; -import static org.nuiton.jrst.ReStructuredText.TITLE; -import static org.nuiton.jrst.ReStructuredText.TOPIC; -import static org.nuiton.jrst.ReStructuredText.TRANSITION; -import static org.nuiton.jrst.ReStructuredText.VERSION; - - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; -import java.io.UnsupportedEncodingException; -import java.net.URL; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.NoSuchElementException; - -import org.apache.commons.lang.ObjectUtils; -import org.apache.commons.lang.StringEscapeUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.jrst.directive.ContentDirective; -import org.nuiton.jrst.directive.DateDirective; -import org.nuiton.jrst.directive.ImageDirective; -import org.nuiton.jrst.directive.SectnumDirective; -import org.nuiton.util.StringUtil; -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.DocumentHelper; -import org.dom4j.Element; -import org.dom4j.IllegalAddException; -import org.dom4j.Node; -import org.dom4j.VisitorSupport; - -/* - * - * <pre> +--------------------------------------------------------------------+ | - * document [may begin with a title, subtitle, decoration, docinfo] | | - * +--------------------------------------+ | | sections [each begins with a - * title] | - * +-----------------------------+-------------------------+------------+ | - * [body elements:] | (sections) | | | - literal | - lists | | - hyperlink - * +------------+ | | blocks | - tables | | targets | | para- | - doctest | - - * block | foot- | - sub. defs | | graphs | blocks | quotes | notes | - comments | - * +---------+-----------+----------+-------+--------------+ | [text]+ | [text] | - * (body elements) | [text] | | (inline - * +-----------+------------------+--------------+ | markup) | +---------+ - * </pre> - * - * - * Inline support: http://docutils.sourceforge.net/docs/user/rst/quickref.html - * - * <li> STRUCTURAL ELEMENTS: document, section, topic, sidebar <li> STRUCTURAL - * SUBELEMENTS: title, subtitle, decoration, docinfo, transition <li> docinfo: - * address, author, authors, contact, copyright, date, field, organization, - * revision, status, version <li> decoration: footer, header <li> BODY ELEMENTS: - * admonition, attention, block_quote, bullet_list, caution, citation, comment, - * compound, container, danger, definition_list, doctest_block, enumerated_list, - * error, field_list, figure, footnote, hint, image, important, line_block, - * literal_block, note, option_list, paragraph, pending, raw, rubric, - * substitution_definition, system_message, table, target, tip, warning <li> - * SIMPLE BODY ELEMENTS: comment, doctest_block, image, literal_block, - * paragraph, pending, raw, rubric, substitution_definition, target <li> - * COMPOUND BODY ELEMENTS: admonition, attention, block_quote, bullet_list, - * caution, citation, compound, container, danger, definition_list, - * enumerated_list, error, field_list, figure, footnote, hint, important, - * line_block, note, option_list, system_message, table, tip, warning <li> BODY - * SUBELEMENTS: attribution, caption, classifier, colspec, field_name, label, - * line, option_argument, option_string, term definition, definition_list_item, - * description, entry, field, field_body, legend, list_item, option, - * option_group, option_list_item, row, tbody, tgroup, thead <li> INLINE - * ELEMENTS: abbreviation, acronym, citation_reference, emphasis, - * footnote_reference, generated, image, inline, literal, problematic, - * reference, strong, subscript, substitution_reference, superscript, target, - * title_reference, raw - * - * <pre> DOCUMENT :: ( (title, subtitle?)?, decoration?, (docinfo, - * transition?)?, STRUCTURE.MODEL; ) decoration :: (header?, footer?) header, - * footer, definition, description, attention, caution, danger, error, hint, - * important, note, tip, warning :: (BODY.ELEMENTS;)+ transition :: EMPTY - * docinfo :: (BIBLIOGRAPHIC.ELEMENTS;)+ BIBLIOGRAPHIC.ELEMENTS :: author | - * authors | organization | contact | address | version | revision | status | - * date | copyright | field authors :: ( (author)+ ) field :: (field_name, - * field_body) field_body, list_item :: (BODY.ELEMENTS;)* STRUCTURE.MODEL :: ( ( - * (BODY.ELEMENTS; | topic | sidebar)+, transition? )*, ( (section), - * (transition?, (section) )* )? ) BODY.ELEMENTS :: paragraph | compound | - * container | literal_block | doctest_block | line_block | block_quote | table | - * figure | image | footnote | citation | rubric | bullet_list | enumerated_list | - * definition_list | field_list | option_list | attention | caution | danger | - * error | hint | important | note | tip | warning | admonition | reference | - * target | substitution_definition | comment | pending | system_message | raw - * topic :: (title?, (BODY.ELEMENTS;)+) sidebar :: (title, subtitle?, - * (BODY.ELEMENTS; | topic)+) section :: (title, STRUCTURE.MODEL;) line_block :: - * (line | line_block)+ block_quote:: ((BODY.ELEMENTS;)+, attribution?) - * bullet_list, enumerated_list :: (list_item +) definition_list :: - * (definition_list_item +) definition_list_item :: (term, classifier?, - * definition) field_list :: (field +) option_list :: (option_list_item +) - * option_list_item :: (option_string, option_argument *, description) - * option_string, option_argument :: (#PCDATA) admonition :: (title, - * (BODY.ELEMENTS;)+) - * - * title, subtitle, author, organization, contact, address, version, revision, - * status, date, copyright, field_name, paragraph, compound, container, - * literal_block, doctest_block, attribution, line, term, classifier :: - * TEXT.MODEL; - * - * TEXT.MODEL :: (#PCDATA | INLINE.ELEMENTS;)* INLINE.ELEMENTS :: emphasis | - * strong | literal | reference | footnote_reference | citation_reference | - * substitution_reference | title_reference | abbreviation | acronym | subscript | - * superscript | inline | problematic | generated | target | image | raw - * emphasis :: '*' #PCDATA '*' strong :: '**' #PCDATA '**' literal :: '``' - * #PCDATA '``' footnote_reference :: '[' ([0-9]+|#) ']' citation_reference :: - * '[' [a-zA-Z]+ ']' - * - * </pre> - */ - -/** - * Le principe est d'utiliser les methodes peek* {@link JRSTLexer} pour - * prendre l'element que l'on attend, si la methode retourne null ou un autre - * element et bien c que ce n'est pas le bon choix, cela veut dire que l'element - * courant est fini d'etre lu (plus de paragraphe dans la section par exemple) - * ou qu'il y a une erreur dans le fichier en entre. - * <p> - * On construit un arbre XML representant le RST au fur et a mesure, on peut - * ensuite appliquer une feuille de style ou autre chose avec - * {@link JRSTGenerator} - * - * <p> - * Tous les elements ont un attribut level qui permet de savoir on il est dans - * la hierarchie. Le Document a le level -1001, et les sections/titres on pour - * level les valeurs 1000, -999, -998, ... - * <p> - * de cette facon les methods isUpperLevel et isSameLevel fonctionne pour tous - * les elements de la meme facon - * - * <pre> - * abbreviation - * acronym - * address (done) - * admonition (done) - * attention (done) - * attribution - * author (done) - * authors (done) - * block_quote (done) - * bullet_list (done) - * caption - * caution (done) - * citation - * citation_reference - * classifier (done) - * colspec (done) - * comment - * compound - * contact (done) - * container - * copyright (done) - * danger (done) - * date (done) - * decoration (done) - * definition (done) - * definition_list (done) - * definition_list_item (done) - * description (done) - * docinfo (done) - * doctest_block (done) - * document (done) - * emphasis (done) - * entry (done) - * enumerated_list (done) - * error (done) - * field (done) - * field_body (done) - * field_list (done) - * field_name (done) - * figure - * footer (done) - * footnote (done) - * footnote_reference (done) - * generated - * header (done) - * hint (done) - * image (done) - * important (done) - * inline - * label - * legend - * line (done) - * line_block (done) - * list_item (done) - * literal (done) - * literal_block (done) - * note (done) - * option (done) - * option_argument (done) - * option_group (done) - * option_list (done) - * option_list_item (done) - * option_string (done) - * organization (done) - * paragraph (done) - * pending - * problematic - * raw - * reference (done) - * revision (done) - * row (done) - * rubric - * section (done) - * sidebar (done) - * status (done) - * strong (done) - * subscript - * substitution_definition - * substitution_reference - * subtitle (done) - * superscript - * system_message - * table (done) - * target (done) - * tbody (done) - * term (done) - * tgroup (done) - * thead (done) - * tip (done) - * title (done) - * title_reference - * topic (done) - * transition (done) - * version (done) - * warning (done) - * </pre> - * - * Created: 27 oct. 06 00:15:34 - * - * @author poussin, letellier - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - */ -public class JRSTReader { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - private static Log log = LogFactory.getLog(JRSTReader.class); - - protected static final String ANONYMOUS = "anonymous"; - - protected static final String AUTO = "auto"; - - protected static final String AUTONUM = "autoNum"; - - protected static final String AUTONUMLABEL = "autoNumLabel"; - - protected static final String AUTOSYMBOL = "autoSymbol"; - - protected static final String ATTR_REFID = "refid"; - - protected static final String ATTR_INLINE = "inline"; - - protected static final String ATTR_IDS = "ids"; - - protected static final String BACKREFS = "backrefs"; - - protected static final String BULLET = "bullet"; - - protected static final String CLASS = "class"; - - protected static final String CONTENTS = "contents"; - - protected static final String DELIMITER = "delimiter"; - - protected static final String DELIMITEREXISTE ="delimiterExiste"; - - protected static final String ENUMTYPE = "enumtype"; - - protected static final String FOOTNOTES = "footnotes"; - - protected static final String ID = "id"; - - protected static final String INCLUDE = "include"; - - protected static final String LEVEL = "level"; - - protected static final String NAME = "name"; - - protected static final String NAMES = "names"; - - protected static final String NUM = "num"; - - protected static final String REFURI = "refuri"; - - protected static final String PREFIX = "prefix"; - - protected static final String REMOVE = "remove"; - - protected static final String START = "start"; - - protected static final String SECTNUM = "sectnum"; - - protected static final String SUBEXISTE = "subExiste"; - - protected static final String SUFFIX = "suffix"; - - protected static final String TRUE = "true"; - - protected static final String TYPE = "type"; - - protected static final String TARGETANONYMOUS = "targetAnonymous"; - - protected static final String VALUE = "value"; - - protected boolean ERROR_MISSING_ITEM; - - protected static int MAX_SECTION_DEPTH = -1000; - - protected static Map<String, JRSTDirective> defaultDirectives; - - protected Map<String, JRSTDirective> directives = new HashMap<String, JRSTDirective>(); - - private boolean sectnum; - - private Element footer; - - private int idMax; - - private int symbolMax; - - private int symbolMaxRef; - - private LinkedList<Integer> lblFootnotes = new LinkedList<Integer>(); - - private LinkedList<Integer> lblFootnotesRef = new LinkedList<Integer>(); - - private LinkedList<Element> eFootnotes = new LinkedList<Element>(); - - private LinkedList<Element> eTarget = new LinkedList<Element>(); - - private LinkedList<Element> eTargetAnonymous = new LinkedList<Element>(); - - private LinkedList<Element> eTargetAnonymousCopy = new LinkedList<Element>(); - - private LinkedList<Element> eTitle = new LinkedList<Element>(); - - static { - defaultDirectives = new HashMap<String, JRSTDirective>(); - defaultDirectives.put(IMAGE, new ImageDirective()); - 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 - } - - /** - * - */ - public JRSTReader() { - } - - /** - * @param name - * @return the defaultDirectives - */ - public static JRSTDirective getDefaultDirective(String name) { - return defaultDirectives.get(name); - } - - /** - * @param name - * @param directive the defaultDirectives to set - */ - public static void addDefaultDirectives(String name, JRSTDirective directive) { - JRSTReader.defaultDirectives.put(name, directive); - } - - /** - * @param name - * @return the defaultDirectives - */ - public JRSTDirective getDirective(String name) { - return directives.get(name); - } - - /** - * @param name - * @param directive the defaultDirectives to set - */ - public void addDirectives(String name, JRSTDirective directive) { - directives.put(name, directive); - } - - /** - * On commence par decouper tout le document en Element, puis on construit - * l'article a partir de ces elements. - * - * @param reader - * @return le document cree - * @throws Exception - */ - public Document read(Reader reader) throws Exception { - JRSTLexer lexer = new JRSTLexer(reader); - try { - Element root = composeDocument(lexer); - - Document result = DocumentHelper.createDocument(); - result.setRootElement(root); - - root.accept(new VisitorSupport() { - @Override - 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)) { - composeContents(e); - e.addAttribute(TYPE, null); - } - } - - if (TRUE.equalsIgnoreCase(e.attributeValue(ATTR_INLINE))) { - e.addAttribute(ATTR_INLINE, null); - try { - inline(e); - } catch (DocumentException eee) { - if (log.isWarnEnabled()) { - log.warn("Can't inline text for " + e, eee); - } - } catch (UnsupportedEncodingException ee) { - if (log.isWarnEnabled()) { - log.warn("Unsupported encoding " + e, ee); - } - } - } - } - }); - - return result; - } catch (Exception eee) { - log.error(_("JRST parsing error line %d char %s:\n%s", lexer - .getLineNumber(), lexer.getCharNumber(), lexer - .readNotBlanckLine())); - throw eee; - } - } - - /** - * <p> - * exemple : - * </p> - * - * <pre> - * ..contents : Sommaire - * depth: 3 - * </pre> - * - * <p> - * depth sert a limiter la profondeur du sommaire - * </p> - * - * @param Element - * - */ - 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()) { - pattern = Pattern.compile("\\p{Digit}+"); - matcher = pattern.matcher(matcher.group()); - if (matcher.find()) { - depth = Integer.parseInt(matcher.group()); - } - } - int levelInit = 0; - boolean noTitle = false; - - try { - levelInit = Integer.parseInt(eTitle.getFirst().attributeValue( - LEVEL)); - } catch (NumberFormatException eee) { - log.error("Can't parse level in: " - + eTitle.getFirst().asXML(), eee); - return; - } catch (NoSuchElementException eee) { - noTitle = true; - } - - LinkedList<Element> title = new LinkedList<Element>(); - // on rajoute les refid - for (int i = 0; i < eTitle.size(); i++) { - idMax++; - eTitle.get(i).addAttribute(ATTR_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); - if (depth == -1) { - title.add(el); - } - else { - if (depth > level) { - title.add(el); - } - } - } - e.addAttribute(CLASS, CONTENTS); - 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"; - } - e.addAttribute(ATTR_IDS, value); - e.addAttribute(NAMES, value); - result.addElement(TITLE).setText(titleValue); - // on compose les lignes - if (!noTitle) { //Si il y a des titres à lier à la table des matières - result.add(composeLineContent(title, "")); - } - e.setText(""); - e.appendContent(result); - } - - /** - * @param title - * <Element> title, String num - * @return Element - */ - private Element composeLineContent(LinkedList<Element> title, String num) { - Element result = DocumentHelper.createElement(BULLET_LIST); - if (sectnum) { - result.addAttribute(CLASS, "auto-toc"); - } - Element item = null; - int cnt = 0; - while (!title.isEmpty()) { - - Element e = title.getFirst(); - int level = Integer.parseInt(e.attributeValue(LEVEL)); - LinkedList<Element> child = new LinkedList<Element>(); - - if (level <= 0) { - cnt++; - title.removeFirst(); - item = result.addElement(LIST_ITEM); - Element para = item.addElement(PARAGRAPH); - Element reference = para.addElement(REFERENCE); - String text = e.getText(); - String id = e.attributeValue(ATTR_REFID); - reference.addAttribute(ATTR_IDS, id); - reference.addAttribute(ATTR_REFID, text.replaceAll("\\W+", " ") - .trim().toLowerCase().replaceAll("\\W+", "-")); - // si l'on doit les numeroter - if (sectnum) { - Element generated = reference.addElement(GENERATED) - .addAttribute(CLASS, SECTNUM); - generated.setText(num + cnt + " "); - for (int i = 0; i < eTitle.size(); i++) { - if (eTitle.get(i).attributeValue(ATTR_REFID).equals(id)) { - Element generatedTitle = eTitle.get(i).addElement( - GENERATED); - generatedTitle.addAttribute(CLASS, SECTNUM); - generatedTitle.setText(num + cnt + " "); - } - - } - } - - text = text.trim(); - text = text.replaceAll("_", ""); - - text = REGEX_STRONG.matcher(text).replaceAll( - "<" + STRONG + ">$1</" + STRONG + ">"); - text = REGEX_EMPHASIS.matcher(text).replaceAll( - "<" + EMPHASIS + ">$1</" + EMPHASIS + ">"); - - try { - Element textElement = DocumentHelper.parseText("<TMP>" + text + "</TMP>").getRootElement(); - reference.appendContent(textElement); - - } catch (DocumentException eee) { - if (log.isWarnEnabled()) { - log.warn("Can't inline text for " + e, eee); - } - } - - } else { - do { - e.addAttribute(LEVEL, "" + (level - 1)); - child.add(e); - title.removeFirst(); - if (!title.isEmpty()) { - e = title.getFirst(); - level = Integer.parseInt(e.attributeValue(LEVEL)); - } - } while (!title.isEmpty() && level > 0); - String numTmp = ""; - // numerotation - if (sectnum) { - numTmp = num + cnt + "."; - } - if (item != null) { - item.add(composeLineContent(child, numTmp)); // Appel - // recursif - } else { - result.add(composeLineContent(child, numTmp)); // Appel - // recursif - } - } - } - return result; - } - - /** - * @param lexer - * @return Element - * @throws Exception - */ - private Element composeDocument(JRSTLexer lexer) throws Exception { - Element result = DocumentHelper.createElement(DOCUMENT); - result.addAttribute(LEVEL, String.valueOf(MAX_SECTION_DEPTH - 1)); - - Element item = null; - - // skip blank line - skipBlankLine(lexer); - - // les liens anonymes - LinkedList<Element> items = lexer.refTarget(); - for (Element e : items) { - eTarget.add(e); - - } - - // le header - item = lexer.peekHeader(); - if (itemEquals(HEADER, item)) { - Element decoration = result.addElement(DECORATION); - Element header = decoration.addElement(HEADER); - header.addAttribute(ATTR_INLINE, TRUE).setText(item.getText()); - } - - // le footer - item = lexer.peekFooter(); - if (itemEquals(FOOTER, item)) { - footer = DocumentHelper.createElement(DECORATION); - Element header = footer.addElement(FOOTER); - header.addAttribute(ATTR_INLINE, TRUE).setText(item.getText()); - } - - // les hyperlinks - LinkedList<Element> listItem = lexer.peekTargetAnonymous(); - if (listItem != null) { - for (Element e : listItem) { - Element anonym = DocumentHelper.createElement(TARGET); - anonym.addAttribute(ANONYMOUS, "1"); - idMax++; - anonym.addAttribute(ATTR_IDS, ID + idMax); - - 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(); - } - - // skip blank line - skipBlankLine(lexer); - - // les commentaires - List<Element> comments = lexer.peekAllComment(); - - // le titre du doc - item = lexer.peekTitle(); - if (itemEquals(TITLE, item)) { - lexer.remove(); - Element title = result.addElement(TITLE); - String txt = item.getText(); - result.addAttribute(ATTR_IDS, txt.replaceAll("[(\\W+)_]", " ") - .toLowerCase().trim().replaceAll("\\s+", "-")); - result.addAttribute(NAMES, txt.toLowerCase().replaceAll( - "[(\\W+)_&&[^\\:]]+", " ").trim()); - copyLevel(item, title); - title.addAttribute(ATTR_INLINE, TRUE).setText(txt.trim()); - } - - // skip blank line - skipBlankLine(lexer); - - // le sous titre du doc - item = lexer.peekTitle(); - if (itemEquals(TITLE, item)) { - lexer.remove(); - Element subtitle = result.addElement(SUBTITLE); - String txt = item.getText(); - subtitle.addAttribute(ATTR_IDS, txt.replaceAll("[(\\W+)_]", " ") - .toLowerCase().trim().replaceAll("\\s+", "-")); - subtitle.addAttribute(NAMES, txt.toLowerCase().replaceAll( - "[(\\W+)_]", " ").trim()); - copyLevel(item, subtitle); - DocumentHelper.createElement(FOOTNOTES); - subtitle.addAttribute(ATTR_INLINE, TRUE).setText(txt.trim()); - } - - // skip blank line - skipBlankLine(lexer); - - // les infos du doc - item = lexer.peekDocInfo(); - Element documentinfo = null; - while (itemEquals(DOCINFO, item) || itemEquals(FIELD_LIST, item)) { - - if (documentinfo == null) { - documentinfo = result.addElement(DOCINFO); - } - skipBlankLine(lexer); - if (itemEquals(FIELD_LIST, item)) { - Element field = composeFieldItemList(lexer); - documentinfo.add(field); - } else { - if ("author".equalsIgnoreCase(item.attributeValue(TYPE))) { - documentinfo.addElement(AUTHOR).addAttribute(ATTR_INLINE, - TRUE).setText(item.getText()); - } else if ("date".equalsIgnoreCase(item.attributeValue(TYPE))) { - documentinfo.addElement(DATE) - .addAttribute(ATTR_INLINE, TRUE).setText( - item.getText().trim()); - } else if ("organization".equalsIgnoreCase(item - .attributeValue(TYPE))) { - documentinfo.addElement(ORGANIZATION).addAttribute( - ATTR_INLINE, TRUE).setText(item.getText().trim()); - } else if ("contact".equalsIgnoreCase(item - .attributeValue(TYPE))) { - documentinfo.addElement(CONTACT).addAttribute(ATTR_INLINE, - TRUE).setText(item.getText().trim()); - } else if ("address".equalsIgnoreCase(item - .attributeValue(TYPE))) { - documentinfo.addElement(ADDRESS).addAttribute(ATTR_INLINE, - TRUE).setText(item.getText().trim()); - } else if ("version".equalsIgnoreCase(item - .attributeValue(TYPE))) { - documentinfo.addElement(VERSION).addAttribute(ATTR_INLINE, - TRUE).setText(item.getText().trim()); - } else if ("revision".equalsIgnoreCase(item - .attributeValue(TYPE))) { - documentinfo.addElement(REVISION).addAttribute(ATTR_INLINE, - TRUE).setText(item.getText().trim()); - } else if ("status".equalsIgnoreCase(item - .attributeValue(TYPE))) { - documentinfo.addElement(STATUS).addAttribute(ATTR_INLINE, - TRUE).setText(item.getText().trim()); - } else if ("copyright".equalsIgnoreCase(item - .attributeValue(TYPE))) { - documentinfo.addElement(COPYRIGHT).addAttribute(ATTR_INLINE, - TRUE).setText(item.getText().trim()); - } else if ("authors".equalsIgnoreCase(item - .attributeValue(TYPE))) { - Element authors = documentinfo.addElement(AUTHORS); - int t = 0; - String line = item.getText(); - for (int i = 0; i < line.length(); i++) { - if (line.charAt(i) == ';' || line.charAt(i) == ',') { - authors.addElement(AUTHOR).addAttribute(ATTR_INLINE, - TRUE) - .setText(line.substring(t, i).trim()); - t = i + 1; - } - - } - authors.addElement(AUTHOR).addAttribute(ATTR_INLINE, TRUE) - .setText(line.substring(t, line.length()).trim()); - } - lexer.remove(); - } - // skip blank line - // skipBlankLine(lexer); - item = lexer.peekDocInfo(); - - } - - // Ajout des commentaires - // System.out.println(comment.asXML()); - for (Element comment : comments){ - result.add(composeComment(comment)); - } - - // l'abstract du doc - item = lexer.peekTitle(); - while (itemNotEquals(TITLE, item) && !lexer.eof()) { - composeBody(lexer, result); - item = lexer.peekTitle(); - } - - // les sections - item = lexer.peekTitle(); - while (itemEquals(TITLE, item, true, lexer.eof())) { - Element section = composeSection(lexer); - result.add(section); - item = lexer.peekTitle(); - } - - // on ajoute le footer a la fin - if (footer != null) { - result.add(footer); - } - - return result; - } - - /** - * <p> - * skip blank line - * </p> - * - * @param lexer - * @throws DocumentException - * @throws IOException - */ - private void skipBlankLine(JRSTLexer lexer) throws IOException, - DocumentException { - Element item = lexer.peekBlankLine(); - // skip blank line - while (itemEquals(JRSTLexer.BLANK_LINE, item)) { - // go to the next element - lexer.remove(); - item = lexer.peekBlankLine(); - } - } - - /** - * * - * <p> - * Corps du document - * </p> - * - * @param lexer - * @return Element - * @throws DocumentException - * @throws IOException - */ - private Element composeBody(JRSTLexer lexer, Element parent) - throws Exception { - - Element item = lexer.peekTitleOrBodyElement(); - if (item == null && !lexer.eof()) { - item = lexer.peekTitleOrBodyElement(); - } - - while (!lexer.eof() && itemNotEquals(TITLE, item) - && isUpperLevel(item, parent)) { - if (itemEquals(JRSTLexer.BLANK_LINE, item)) { - // go to the next element - lexer.remove(); - } else if (itemEquals(REMOVE, item)) { - lexer.remove(); - } else if (itemEquals(INCLUDE, item)) { - lexer.remove(); - Element list = composeInclude(item); - parent.add(list); - } else if (itemEquals(DOCTEST_BLOCK, item)) { - lexer.remove(); - Element list = composeDoctestBlock(item); - parent.add(list); - } else if (itemEquals(ADMONITION, item)) { - lexer.remove(); - Element list = composeAdmonition(item); - parent.add(list); - } else if (itemEquals(SIDEBAR, item)) { - lexer.remove(); - Element list = composeSidebar(item); - parent.add(list); - } else if (itemEquals(TOPIC, item)) { - lexer.remove(); - Element list = composeTopic(item); - parent.add(list); - } else if (itemEquals(TRANSITION, item)) { - lexer.remove(); - Element para = parent.addElement(TRANSITION); - copyLevel(item, para); - } else if (itemEquals(PARAGRAPH, item)) { - lexer.remove(); - Element para = parent.addElement(PARAGRAPH); - copyLevel(item, para); - para.addAttribute(ATTR_INLINE, TRUE).setText(item.getText()); - } else if (itemEquals(JRSTLexer.DIRECTIVE, item)) { - lexer.remove(); - Node directive = composeDirective(item); - parent.add(directive); - } else if (itemEquals(SUBSTITUTION_DEFINITION, item)) { - lexer.remove(); - Element subst = composeSubstitutionDefinition(item); - parent.add(subst); - } else if (itemEquals(LITERAL_BLOCK, item)) { - lexer.remove(); - Element para = parent.addElement(LITERAL_BLOCK); - copyLevel(item, para); - para.setText(item.getText()); - } else if (itemEquals(JRSTLexer.TABLE, item)) { - lexer.remove(); - Element table = composeTable(item); - parent.add(table); - // Element para = parent.addElement(TABLE); - // copyLevel(item, para); - // para.setText(item.getText()); - } else if (itemEquals(LINE_BLOCK, item)) { - lexer.remove(); - Element list = composeLineBlock(lexer, item); - parent.add(list); - } else if (itemEquals(BULLET_LIST, item)) { - Element list = composeBulletList(lexer); - parent.add(list); - } else if (itemEquals(ENUMERATED_LIST, item)) { - Element list = composeEnumeratedList(lexer); - parent.add(list); - } else if (itemEquals(DEFINITION_LIST, item)) { - Element list = composeDefinitionList(lexer); - parent.add(list); - } else if (itemEquals(FIELD_LIST, item)) { - Element list = composeFieldList(lexer); - parent.add(list); - } else if (itemEquals(BLOCK_QUOTE, item)) { - lexer.remove(); - Element list = composeBlockQuote(item); - parent.add(list); - } else if (itemEquals(OPTION_LIST, item)) { - Element list = composeOptionList(lexer); - parent.add(list); - } else if (itemEquals(TARGET, item)) { - lexer.remove(); - Element list = composeTarget(item); - if (list != null) { - try { - parent.add(list); - } catch (IllegalAddException e) {} - } else - System.err.println("Unknown target name : \"" + item.attributeValue(ATTR_IDS) + "\""); - } else if (itemEquals(TARGETANONYMOUS, item)) { - lexer.remove(); - Element list = composeTargetAnonymous(item); - parent.add(list); - } else if (itemEquals(FOOTNOTES, item)) { - lexer.remove(); - Element[] list = composeFootnote(item); - for (Element l : list) { - parent.add(l); - } - } else if (itemEquals(COMMENT, item)) { - lexer.remove(); - Element list = composeComment(item); - parent.add(list); - } - - else { - if (ERROR_MISSING_ITEM) { - throw new DocumentException("Unknow item type: " - + item.getName()); - } else { - lexer.remove(); - } - } - - // Pour afficher le "PseudoXML" - // if (item!=null) System.out.println(item.asXML()); - - item = lexer.peekTitleOrBodyElement(); - } - - return parent; - } - - /** - * <p> - * include un document rst - * </p> - * - * <pre> - * .. include:: doc.rst - * </pre> - * - * <p> - * include un document literal (code...) - * </p> - * - * <pre> - * .. include:: literal - * doc.rst - * </pre> - * - * @param item - * @return Element - * @throws Exception - */ - private Element composeInclude(Element item) throws Exception { - String option = item.attributeValue(OPTION); - String path = item.getText(); - Element result = null; - if (option.equals(LITERAL)) { - result = DocumentHelper.createElement(LITERAL_BLOCK); - FileReader reader = new FileReader(path); - BufferedReader bf = new BufferedReader(reader); - String line = ""; - String lineTmp = bf.readLine(); - while (lineTmp != null) { - line += '\n' + lineTmp; - lineTmp = bf.readLine(); - } - result.setText(line); - } else { - File fileIn = new File(path); - URL url = fileIn.toURI().toURL(); - Reader in = new InputStreamReader(url.openStream()); - - Document doc = newJRSTReader(in); - - result = doc.getRootElement(); - } - return result; - } - - /** - * <pre> - * .. - * So this block is not "lost", - * despite its indentation. - * </pre> - * - * @param item - * @return Element - */ - private Element composeComment(Element item) { - - return item; - } - - /** - * <pre> - * __ http://truc.html - * </pre> - * - * @param item - * @return Element - */ - private Element composeTargetAnonymous(Element item) { - Element result = null; - result = eTargetAnonymousCopy.getFirst(); - eTargetAnonymousCopy.removeFirst(); - return result; - } - - /** - * <pre _ target: target.html </pre> - * - * @param item - * @return Element - */ - private Element composeTarget(Element item) { - Element result = null; - for (Element e : eTarget) { - if (e.attributeValue(ID).equals(item.attributeValue(ID))) { - result = e; - } - } - return result; - } - - /** - * <pre> - * .. [#] This is a footnote - * </pre> - * - * @param item - * @return Element - * @throws Exception - */ - private Element[] composeFootnote(Element item) throws Exception { - Element[] result = null; - if (itemEquals(FOOTNOTES, item)) { - List<Element> footnotes = (List<Element>) item - .selectNodes(FOOTNOTE); - result = new Element[footnotes.size()]; - int cnt = 0; - for (Element footnote : footnotes) { - result[cnt] = DocumentHelper.createElement(FOOTNOTE); - Element efootnote = DocumentHelper.createElement(FOOTNOTE); - int labelMax = 0; - - for (int i = 0; i < lblFootnotes.size(); i++) { - int lbl = lblFootnotes.get(i); - labelMax = Math.max(lbl, labelMax); - } - - boolean[] labels = new boolean[labelMax]; - for (int i = 0; i < labels.length; i++) { - labels[i] = false; - } - for (int i = 0; i < lblFootnotes.size(); i++) { - labels[lblFootnotes.get(i) - 1] = true; - } - idMax++; - String name = null; - String id = ""; - String label = null; - String type = footnote.attributeValue(TYPE); - if (type.equals(AUTONUM) || type.equals(AUTONUMLABEL)) { - result[cnt].addAttribute(AUTO, "1"); - } - if (type.equals(AUTOSYMBOL)) { - result[cnt].addAttribute(AUTO, "*"); - } - result[cnt].addAttribute(BACKREFS, ID + idMax); - efootnote.addAttribute(BACKREFS, ID + idMax); - if (type.equals(NUM) || type.equals(AUTONUMLABEL)) { - name = footnote.attributeValue(NAME); - if (type.equals(AUTONUMLABEL)) { - id = name; - } - else { - label = name; - } - } - if (type.equals(AUTONUM) || type.equals(AUTONUMLABEL)) { - boolean done = false; - - for (int i = 0; i < labels.length && !done; i++) { - if (!labels[i]) { - done = true; - label = "" + (i + 1); - } - } - if (!done) { - label = "" + (labels.length + 1); - } - if (type.equals(AUTONUM)) { - name = label; - } - } - if (type.equals(AUTOSYMBOL)) { - - int nb = Math.abs(symbolMax / 10) + 1; - char symbol = FOOTNOTE_SYMBOL.charAt(symbolMax % 10); - label = ""; - for (int j = 0; j < nb; j++) { - label += symbol; - } - symbolMax++; - - } - result[cnt].addAttribute(ATTR_IDS, "" + id); - efootnote.addAttribute(ATTR_IDS, "" + id); - if (!type.equals(AUTOSYMBOL)) { - result[cnt].addAttribute(NAME, "" + name); - efootnote.addAttribute(NAME, "" + name); - } - result[cnt].addElement(LABEL).setText("" + label); - efootnote.addAttribute(LABEL, "" + label); - if (!type.equals(AUTOSYMBOL)) { - lblFootnotes.add(Integer.parseInt(label)); - } - efootnote.addAttribute(TYPE, type); - eFootnotes.add(efootnote); - String text = footnote.getText(); - Document doc = newJRSTReader(new StringReader(text)); - result[cnt].appendContent(doc.getRootElement()); - - cnt++; - } - } - for (int i = 0; i < result.length; i++) { - if (result[i].attributeValue(ATTR_IDS).equals("")) { - idMax++; - result[i].addAttribute(ATTR_IDS, ID + idMax); - (eFootnotes.get(i)).addAttribute(ATTR_IDS, ID + idMax); - } - - } - - return result; - } - - /** - * <pre> - * -a command-line option "a" -1 file, --one=file, --two file Multiple - * options with arguments. - * </pre> - * - * @param lexer - * @return Element - * @throws Exception - * @throws DocumentException - */ - private Element composeOptionList(JRSTLexer lexer) - throws DocumentException, Exception { - Element item = lexer.peekOption(); - Element result = DocumentHelper.createElement(OPTION_LIST); - while (itemEquals(OPTION_LIST, item)) { - lexer.remove(); - Element optionListItem = result.addElement(OPTION_LIST_ITEM); - Element optionGroup = optionListItem.addElement(OPTION_GROUP); - List<Element> option = (List<Element>) item.selectNodes(OPTION); - for (Element e : option) { - Element eOption = optionGroup.addElement(OPTION); - eOption.addElement(OPTION_STRING).setText( - e.attributeValue(OPTION_STRING)); - if (e.attributeValue(DELIMITEREXISTE).equals(TRUE)) { - eOption.addElement(OPTION_ARGUMENT).addAttribute( - DELIMITER, e.attributeValue(DELIMITER)) - .setText(e.attributeValue(OPTION_ARGUMENT)); - } - } - Element description = optionListItem.addElement(DESCRIPTION); - - String text = item.getText(); - Document doc = newJRSTReader(new StringReader(text)); - description.appendContent(doc.getRootElement()); - - item = lexer.peekOption(); - } - return result; - } - - /** - * <pre> - * .. topic:: Title - * - * Body. - * </pre> - * - * @param Element - * item - * @return Element - * @throws Exception - */ - - private Element composeTopic(Element item) throws Exception { - Element result = null; - result = DocumentHelper.createElement(TOPIC); - result.addElement(TITLE).addAttribute(ATTR_INLINE, TRUE).setText( - item.attributeValue(TITLE)); - String text = item.getText(); - Document doc = newJRSTReader(new StringReader(text)); - result.appendContent(doc.getRootElement()); - - return result; - } - - /** - * <pre> - * .. sidebar:: Title - * :subtitle: If Desired - * - * Body. - * </pre> - * - * @param Element - * @return Element - * @throws Exception - */ - - private Element composeSidebar(Element item) throws Exception { - Element result = null; - result = DocumentHelper.createElement(SIDEBAR); - result.addElement(TITLE).addAttribute(ATTR_INLINE, TRUE).setText( - item.attributeValue(TITLE)); - if (item.attributeValue(SUBEXISTE).equals(TRUE)) { - result.addElement(SUBTITLE).addAttribute(ATTR_INLINE, TRUE).setText( - item.attributeValue(SUBTITLE)); - } - - String text = item.getText(); - Document doc = newJRSTReader(new StringReader(text)); - result.appendContent(doc.getRootElement()); - - return result; - } - - /** - * <pre> - * | line block - * | - * | indent - * </pre> - * - * @param lexer - * @param item - * @return Element - * @throws Exception - */ - private Element composeLineBlock(JRSTLexer lexer, Element item) - throws Exception { - Element result = null; - result = DocumentHelper.createElement(LINE_BLOCK); - List<Element> lines = (List<Element>) item.selectNodes(LINE); - int[] levels = new int[lines.size()]; - int cnt = 0; - for (Element l : lines) { - levels[cnt] = Integer.parseInt(l.attributeValue(LEVEL)); - cnt++; - } - cnt = 0; - boolean[] lineDone = new boolean[lines.size()]; - for (int i = 0; i < lineDone.length; i++) { - lineDone[i] = false; - } - for (Element l : lines) { - if (levels[cnt] == 0) { - result.addElement(LINE).addAttribute(ATTR_INLINE, TRUE).setText( - l.getText()); - } - else { - if (!lineDone[cnt]) { - Element newItem = DocumentHelper.createElement(LINE_BLOCK); - Boolean done = false; - for (int i = cnt; i < lines.size() && !done; i++) { - if (levels[i] > 0) { - Element eLine = newItem.addElement(LINE); - eLine.addAttribute(LEVEL, "" + (levels[i] - 1)); - eLine.setText(lines.get(i).getText()); - lineDone[i] = true; - } else { - done = true; - } - - } - Element eLineBlock = result.addElement(LINE_BLOCK); - // Appel recursif - eLineBlock.appendContent(composeLineBlock(lexer, newItem)); - } - } - cnt++; - - } - return result; - } - - /** - * <pre> - * >>> print 'this is a Doctest block' - * this is a Doctest block - * </pre> - * - * @param Element - * @return Element - */ - private Element composeDoctestBlock(Element item) { - return item; - } - - /** - * <pre> - * As a great paleontologist once said, - * - * This theory, that is mine, is mine. - * - * -- Anne Elk (Miss) - * </pre> - * - * @param Element - * @return Element - * @throws Exception - * - */ - private Element composeBlockQuote(Element item) throws Exception { - Element result = null; - result = DocumentHelper.createElement(BLOCK_QUOTE); - - String text = item.getText(); - Document doc = newJRSTReader(new StringReader(text)); - result.appendContent(doc.getRootElement()); - String sAttribution = item.attributeValue(ATTRIBUTION); - if (sAttribution != null) { - Element attribution = result.addElement(ATTRIBUTION); - attribution.setText(sAttribution); - attribution.addAttribute(ATTR_INLINE, TRUE); - } - return result; - } - - /** - * <pre> - * .. admonition:: And, by the way... - * - * You can make up your own admonition too. - * </pre> - * - * @param Element - * @return Element - * @throws Exception - * - */ - private Element composeAdmonition(Element item) throws Exception { - Element result = null; - if (item.attributeValue(TYPE).equalsIgnoreCase(ADMONITION)) { - result = DocumentHelper.createElement(ADMONITION); - String title = item.attributeValue(TITLE); - String admonitionClass = "admonition_" + title; - admonitionClass = admonitionClass.toLowerCase().replaceAll( - "\\p{Punct}", ""); - admonitionClass = admonitionClass.replace(' ', '-'); - admonitionClass = admonitionClass.replace('\n', '-'); - result.addAttribute(CLASS, admonitionClass); - result.addElement(TITLE).addAttribute(ATTR_INLINE, TRUE).setText( - title.trim()); - } else { - result = DocumentHelper.createElement(item.attributeValue(TYPE) - .toLowerCase()); - } - - String text = item.getText(); - Document doc = newJRSTReader(new StringReader(text)); - result.appendContent(doc.getRootElement()); - return result; - } - - /** - * parse all directives - * - * @param Element - * @return Node - */ - private Node composeDirective(Element item) { - Node result = item; - String type = item.attributeValue(JRSTLexer.DIRECTIVE_TYPE); - if (type.equals(SECTNUM)) { - sectnum = true; - } - JRSTDirective directive = getDirective(type); - if (directive == null) { - directive = getDefaultDirective(type); - } - if (directive != null) { - result = directive.parse(item); - } else { - log.warn("Unknow directive type '" + type + "' in: " + item); - } - return result; - } - - /** - * <pre> - * .. |biohazard| image:: biohazard.png - * </pre> - * - * @param Element - * @return Element - */ - private Element composeSubstitutionDefinition(Element item) { - Element result = item; - Element child = (Element) item.selectSingleNode("*"); - Node newChild = composeDirective(child); - result.remove(child); // remove old after composeDirective, because - // directive can be used this parent - result.add(newChild); - return result; - } - - /** - * <p> - * Complexe Table - * </p> - * - * <pre> - * +------------------------+------------+---------------------+ - * | body row 3 | Cells may | - Table cells | - * +------------------------+ span rows. | - contain | - * | body row 4 | | - body elements. | - * +------------------------+------------+---------------------+ - * </pre> - * - * <p> - * And simple table - * </p> - * - * <pre> - * ===== ===== ====== - * Inputs Output - * ============ ====== - * A B A or B - * ------------ ------ - * A B A or B - * ===== ===== ====== - * </pre> - * - * @param Element - * @return Element - * - */ - private Element composeTable(Element item) throws Exception { - - Element result = DocumentHelper.createElement(TABLE); - - int tableWidth = Integer.parseInt(item - .attributeValue(JRSTLexer.TABLE_WIDTH)); - - TreeSet<Integer> beginCellList = new TreeSet<Integer>(); - - for (Element cell : (List<Element>) item.selectNodes(JRSTLexer.ROW - + "/" + JRSTLexer.CELL)) { - Integer begin = Integer.valueOf(cell - .attributeValue(JRSTLexer.CELL_INDEX_START)); - beginCellList.add(begin); - } - - int[] beginCell = new int[beginCellList.size() + 1]; // + 1 to put - // table width - // to simulate - // new cell - int[] lengthCell = new int[beginCellList.size()]; - - int cellNumber = 0; - for (int b : beginCellList) { - beginCell[cellNumber] = b; - if (cellNumber > 0) { - lengthCell[cellNumber - 1] = beginCell[cellNumber] - - beginCell[cellNumber - 1]; - } - cellNumber++; - } - beginCell[cellNumber] = tableWidth; - lengthCell[cellNumber - 1] = beginCell[cellNumber] - - beginCell[cellNumber - 1]; - - Element tgroup = result.addElement(TGROUP).addAttribute("cols", - String.valueOf(cellNumber)); - for (int width : lengthCell) { - tgroup.addElement(COLSPEC).addAttribute("colwidth", - String.valueOf(width)); - } - - Element rowList = null; - if (TRUE.equals(item.attributeValue(JRSTLexer.TABLE_HEADER))) { - rowList = tgroup.addElement(THEAD); - } else { - rowList = tgroup.addElement(TBODY); - } - List<Element> rows = (List<Element>) item.selectNodes(JRSTLexer.ROW); - for (int r = 0; r < rows.size(); r++) { - Element row = rowList.addElement(ROW); - List<Element> cells = (List<Element>) rows.get(r).selectNodes( - JRSTLexer.CELL); - for (int c = 0; c < cells.size(); c++) { - Element cell = cells.get(c); - // si la cellule a ete utilise pour un regroupement vertical on - // la passe - if (!TRUE.equals(cell.attributeValue("used"))) { - Element entry = row.addElement(ENTRY); - String text = ""; - - // on regroupe les cellules verticalement - int morerows = -1; - Element tmpCell = null; - String cellStart = cell - .attributeValue(JRSTLexer.CELL_INDEX_START); - do { - morerows++; - tmpCell = (Element) rows.get(r + morerows) - .selectSingleNode( - JRSTLexer.CELL + "[@" - + JRSTLexer.CELL_INDEX_START - + "=" + cellStart + "]"); - text += tmpCell.getText(); - // on marque la cellule comme utilise - tmpCell.addAttribute("used", TRUE); - } while (!TRUE.equals(tmpCell - .attributeValue(JRSTLexer.CELL_END))); - - if (morerows > 0) { - entry - .addAttribute("morerows", String - .valueOf(morerows)); - } - - // on compte le nombre de cellules regroupees - // horizontalement - int morecols = 0; - tmpCell = cells.get(c + morecols); - int cellEnd = Integer.parseInt(tmpCell - .attributeValue(JRSTLexer.CELL_INDEX_END)); - while (cellEnd + 1 != beginCell[c + morecols + 1]) { - morecols++; - // tmpCell = cells.get(c + morecols); - // cellEnd = - // Integer.parseInt(tmpCell.attributeValue(JRSTLexer. - // CELL_INDEX_END)); - } - if (morecols > 0) { - entry - .addAttribute("morecols", String - .valueOf(morecols)); - } - // parse entry text in table - Document doc = newJRSTReader(new StringReader(text)); - entry.appendContent(doc.getRootElement()); - } - } - if (TRUE.equals(rows.get(r).attributeValue( - JRSTLexer.ROW_END_HEADER))) { - rowList = tgroup.addElement(TBODY); - } - } - - return result; - } - - /** - * <p> - * items begin with "-", "+", or "*" - * </p> - * - * <pre> - * * aaa - * - bbb - * * ccc - * - ddd - * + eee - * </pre> - * - * @param lexer - * @return Element - * @throws Exception - */ - private Element composeBulletList(JRSTLexer lexer) throws Exception { - Element item = lexer.peekBulletList(); - Element result = DocumentHelper.createElement(BULLET_LIST); - copyLevel(item, result); - result.addAttribute(BULLET, item.attributeValue(BULLET)); - while (itemEquals(BULLET_LIST, item) && isSameLevel(item, result) - && hasSameAttribute(item, result, BULLET)) { - lexer.remove(); - Element bullet = result.addElement(LIST_ITEM); - copyLevel(item, bullet); - bullet.addElement(PARAGRAPH).addAttribute(ATTR_INLINE, TRUE) - .setText(item.getText()); - composeBody(lexer, bullet); - - item = lexer.peekBulletList(); - } - return result; - } - - /** - * <pre> - * 3. et meme - * * #. pour voir - * * I) de tout - * (a) pour tout - * (#) vraiment tout - * </pre> - * - * @param lexer - * @return Element - * @throws Exception - */ - private Element composeEnumeratedList(JRSTLexer lexer) throws Exception { - Element item = lexer.peekEnumeratedList(); - Element result = DocumentHelper.createElement(ENUMERATED_LIST); - copyLevel(item, result); - String enumType = item.attributeValue(ENUMTYPE); - if (!enumType.equals("arabic")) { - result.addAttribute(START, item.attributeValue(START)); - } - result.addAttribute(PREFIX, item.attributeValue(PREFIX)); - result.addAttribute(SUFFIX, item.attributeValue(SUFFIX)); - result.addAttribute(ENUMTYPE, enumType); - while (itemEquals(ENUMERATED_LIST, item) - && isSameLevel(item, result) - && hasSameAttribute(item, result, PREFIX, SUFFIX) - && (AUTO.equals(item.attributeValue(ENUMTYPE)) || hasSameAttribute( - item, result, ENUMTYPE))) { - lexer.remove(); - Element e = result.addElement(LIST_ITEM); - copyLevel(item, e); - e.addElement(PARAGRAPH).addAttribute(ATTR_INLINE, TRUE).setText( - item.getText()); - composeBody(lexer, e); - - item = lexer.peekEnumeratedList(); - } - return result; - } - - /** - * <pre> - * le mot : la classe - * la definition - * </pre> - * - * @param lexer - * @return Element - * @throws Exception - */ - private Element composeDefinitionList(JRSTLexer lexer) throws Exception { - Element item = lexer.peekBodyElement(); - Element result = DocumentHelper.createElement(DEFINITION_LIST); - copyLevel(item, result); - while (itemEquals(DEFINITION_LIST, item) && isSameLevel(item, result)) { - lexer.remove(); - Element def = result.addElement(DEFINITION_LIST_ITEM); - copyLevel(item, def); - - Element term = def.addElement(TERM); - copyLevel(item, term); - term.addAttribute(ATTR_INLINE, TRUE).setText( - item.attributeValue("term")); - - String[] classifiers = StringUtil.split(item - .attributeValue("classifiers"), " : "); - for (String classifierText : classifiers) { - Element classifier = def.addElement("classifier"); - copyLevel(item, classifier); - classifier.addAttribute(ATTR_INLINE, TRUE).setText( - classifierText); - } - - Element definition = def.addElement(DEFINITION); - definition.addElement(PARAGRAPH).addAttribute(ATTR_INLINE, TRUE) - .setText(item.getText()); - copyLevel(item, definition); - - composeBody(lexer, definition); - - item = lexer.peekBodyElement(); - } - return result; - } - - /** - * <pre> - * :un peu: de field - * ca ne fait pas - * de mal - * </pre> - * - * @param lexer - * @return Element - * @throws Exception - */ - private Element composeFieldList(JRSTLexer lexer) throws Exception { - Element item = lexer.peekBodyElement(); - Element result = DocumentHelper.createElement(FIELD_LIST); - copyLevel(item, result); - while (itemEquals(FIELD_LIST, item) && isSameLevel(item, result)) { - Element field = composeFieldItemList(lexer); - result.add(field); - item = lexer.peekBodyElement(); - } - return result; - } - - /** - * <pre> - * :field1: avec un - * petit texte - * - et meme un - * - debut - * - de list - * </pre> - * - * @param lexer - * @return Element - * @throws Exception - */ - private Element composeFieldItemList(JRSTLexer lexer) throws Exception { - Element item = lexer.peekFieldList(); - if (itemEquals(FIELD_LIST, item)) { - lexer.remove(); - Element field = DocumentHelper.createElement(FIELD); - copyLevel(item, field); - Element fieldName = field.addElement(FIELD_NAME); - copyLevel(item, fieldName); - fieldName.addAttribute(ATTR_INLINE, TRUE).setText( - item.attributeValue(NAME)); - Element fieldBody = field.addElement(FIELD_BODY); - fieldBody.addElement(PARAGRAPH).addAttribute(ATTR_INLINE, TRUE) - .setText(item.getText()); - copyLevel(item, fieldBody); - composeBody(lexer, fieldBody); - - return field; - } else { - throw new DocumentException("Waiting for " + FIELD_LIST - + " and found " + item.getName()); - } - } - - /** - * <pre> - * DEFINITIONS - * ----------- - * </pre> - * - * @param lexer - * @return Element - * @throws Exception - */ - private Element composeSection(JRSTLexer lexer) throws Exception { - Element result = DocumentHelper.createElement(SECTION); - Element firstTitle = null; - - Element item = null; - - // le titre de la section - item = lexer.peekTitle(); - if (itemEquals(TITLE, item, true, lexer.eof())) { - lexer.remove(); - firstTitle = item; - Element title = result.addElement(TITLE); - copyLevel(item, result); - copyLevel(item, title); - title.addAttribute(ATTR_INLINE, TRUE).setText(item.getText().trim()); - result.addAttribute(ID, item.getText().replaceAll("\\W+", " ") - .trim().toLowerCase().replaceAll("\\W+", "-")); - result.addAttribute(NAME, item.getText().toLowerCase().trim()); - eTitle.add(title); - } - - // le contenu de la section - item = lexer.peekTitle(); - while (itemNotEquals(TITLE, item) && !lexer.eof()) { - composeBody(lexer, result); - item = lexer.peekTitle(); - } - - // les sous sections - item = lexer.peekTitle(); - while (itemEquals(TITLE, item) && isUpperLevel(item, firstTitle)) { - Element section = composeSection(lexer); - result.add(section); - item = lexer.peekTitle(); - } - - return result; - } - - /** - * Indique si la sous section est bien une sous section, c-a-d dire que son - * level est superieur a celui de la section - * - * @param item - * @param firstTitle - * @return boolean - * @throws DocumentException - */ - private boolean isUpperLevel(Element subSection, Element section) - throws DocumentException { - // if (!(itemEquals(SECTION, subSection) && itemEquals(SECTION, - // section)) - // || itemEquals(DOCUMENT, section) || itemEquals(SECTION, section)) { - // // all element is upper than Document or section - // return true; - // } - int subSectionLevel = Integer.parseInt(subSection - .attributeValue(LEVEL)); - int sectionLevel = Integer.parseInt(section.attributeValue(LEVEL)); - boolean result = subSectionLevel > sectionLevel; - return result; - } - - /** - * Indique si les deux elements sont au meme niveau - * - * @param item - * @param firstTitle - * @return boolean - * @throws DocumentException - */ - private boolean isSameLevel(Element subSection, Element section) - throws DocumentException { - // if (itemEquals(DOCUMENT, section) || itemEquals(SECTION, section)) { - // // all element is upper than Document or section - // return false; - // } - int subSectionLevel = Integer.parseInt(subSection - .attributeValue(LEVEL)); - int sectionLevel = Integer.parseInt(section.attributeValue(LEVEL)); - boolean result = subSectionLevel == sectionLevel; - return result; - } - - /** - * @param Element - * e1 - * @param Element - * e2 - * @param String - * ... attnames - * @return boolean - */ - private boolean hasSameAttribute(Element e1, Element e2, String... attnames) { - boolean result = true; - for (String attname : attnames) { - String a1 = e1.attributeValue(attname); - String a2 = e2.attributeValue(attname); - if (!ObjectUtils.equals(a1, a2)) { - result = false; - break; - } - } - return result; - } - - /** - * @param Element - * from - * @param Element - * to - * @throws DocumentException - */ - private void copyLevel(Element from, Element to) throws DocumentException { - String level = from.attributeValue(LEVEL); - if (level == null) { - throw new DocumentException("Element without level: " + from); - } - to.addAttribute(LEVEL, level); - } - - /** - * @param String - * name - * @param Element - * e - * @return boolean - * @throws DocumentException - */ - private boolean itemEquals(String name, Element e) throws DocumentException { - boolean result = itemEquals(name, e, false, false); - return result; - } - - /** - * @param String - * name - * @param Element - * e - * @param throwError - * @param eof - * @return boolean - * @throws DocumentException - */ - private boolean itemEquals(String name, Element e, boolean throwError, - boolean eof) throws DocumentException { - boolean result = e != null && name.equals(e.getName()); - if (ERROR_MISSING_ITEM && !result && throwError && !eof) { - throw new DocumentException("Malformed document waiting " + name - + " and found " + (e != null ? e.getName() : "null")); - } - return result; - } - - /** - * @param String - * name - * @param Element - * e - * @return boolean - */ - private boolean itemNotEquals(String name, Element e) { - boolean result = e == null || !name.equals(e.getName()); - 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); - - } - - /** - * <p> - * Initialises les variables d'environements par ex, les hyperlinks peuvent - * etre referencer dans tous le document - * </p> - * - * @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<Integer> lblFootnotes, - LinkedList<Integer> lblFootnotesRef, - LinkedList<Element> eFootnotes, LinkedList<Element> eTarget, - LinkedList<Element> eTargetAnonymous, - LinkedList<Element> 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 - * - * @param Element - * e - * @throws DocumentException - * @throws UnsupportedEncodingException - */ - - private void inline(Element e) throws DocumentException, UnsupportedEncodingException { - String text = e.getText(); - - text = StringEscapeUtils.escapeXml(text); - // search all LITERAL and replace it with special mark - // this prevent substitution in literal, example **something** must not - // change in literal - Map<String, String> temporaries = new HashMap<String, String>(); - Matcher matcher = REGEX_LITERAL.matcher(text); - int index = 0; - while (matcher.find()) { - int start = matcher.start(); - int end = matcher.end(); - String literal = "<" + LITERAL + ">" + matcher.group(1) + "</" - + LITERAL + ">"; - String key = LITERAL + index++; - temporaries.put(key, literal); - text = text.substring(0, start) + "<tmp>" + key + "</tmp>" - + text.substring(end); - matcher = REGEX_LITERAL.matcher(text); - } - // search all REGEX_INLINE_REFERENCE and replace it with special mark - // this prevent substitution of URL with REGEX_REFERENCE. Use same - // mechanisme as literal for that - matcher = REGEX_INLINE_REFERENCE.matcher(text); - index = 0; - while (matcher.find()) { - int start = matcher.start(); - int end = matcher.end(); - Element ref = DocumentHelper.createElement(REFERENCE); - ref.addAttribute(REFURI, StringEscapeUtils.unescapeXml(matcher.group(2))); - ref.setText(StringEscapeUtils.unescapeXml(matcher.group(1))); - String key = "inlineReference" + index++; - temporaries.put(key, ref.asXML()); - text = text.substring(0, start) + "<tmp>" + key + "</tmp>" - + text.substring(end); - matcher = REGEX_INLINE_REFERENCE.matcher(text); - - } - // do all substitution inline - text = REGEX_EMAIL.matcher(text).replaceAll( - "$1<" + REFERENCE + " refuri='mailto:$2'>$2</" + REFERENCE - + ">$3"); - text = REGEX_STRONG.matcher(text).replaceAll( - "<" + STRONG + ">$1</" + STRONG + ">"); - text = REGEX_EMPHASIS.matcher(text).replaceAll( - "<" + EMPHASIS + ">$1</" + EMPHASIS + ">"); - text = REGEX_REFERENCE.matcher(text).replaceAll( - "<" + REFERENCE + " refuri='$1'>$1</" + REFERENCE + ">$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()-1); - Element footnote = DocumentHelper.createElement(FOOTNOTE_REFERENCE); - String sFootnote = matcher.group(); - boolean done = false; - for (int i = 0; i < sFootnote.length() && !done; i++) { - if (sFootnote.charAt(i) == ']') { - String id = sFootnote.substring(1, i); - if (id.equals("*")) { - int nb = Math.abs(symbolMaxRef / 10) + 1; - char symbol = FOOTNOTE_SYMBOL.charAt(symbolMaxRef % 10); - String label = ""; - for (int j = 0; j < nb; j++) { - label += symbol; - } - symbolMaxRef++; - footnote.addAttribute(AUTO, "*"); - for (int j = 0; j < eFootnotes.size(); j++) { - Element eFootnote = eFootnotes.get(j); - if (eFootnote.attributeValue(LABEL).equals(label)) { - - footnote.addAttribute(ATTR_IDS, eFootnote - .attributeValue(BACKREFS)); - footnote.addAttribute(ATTR_REFID, eFootnote - .attributeValue(ATTR_IDS)); - - } - } - footnote.setText(label); - - } else if (id.matches("[1-9]+")) { - - for (int j = 0; j < eFootnotes.size(); j++) { - Element eFootnote = eFootnotes.get(j); - if (eFootnote.attributeValue(LABEL).equals(id)) { - footnote.addAttribute(ATTR_IDS, eFootnote - .attributeValue(BACKREFS)); - footnote.addAttribute(ATTR_REFID, eFootnote - .attributeValue(ATTR_IDS)); - } - } - footnote.setText(id); - lblFootnotesRef.add(Integer.parseInt(id)); - - } else if (id.equals("#")) { - int lblMax = 0; - for (int j = 0; j < lblFootnotesRef.size(); j++) { - lblMax = Math.max(lblMax, lblFootnotesRef.get(j)); - } - - boolean[] lbls = new boolean[lblMax]; - for (int j = 0; j < lbls.length; j++) { - lbls[j] = false; - } - for (int j = 0; j < lblFootnotesRef.size(); j++) { - lbls[lblFootnotesRef.get(j) - 1] = true; - } - boolean valide = false; - do { - boolean trouve = false; - String label = null; - for (int j = 0; j < lbls.length && !trouve; j++) { - - if (!lbls[j]) { - trouve = true; - label = "" + (j + 1); - } - } - if (!trouve) { - label = "" + (lbls.length + 1); - } - footnote.addAttribute(AUTO, "1"); - for (int j = 0; j < eFootnotes.size(); j++) { - Element eFootnote = eFootnotes.get(j); - if (eFootnote.attributeValue(LABEL).equals( - label)) { - if (!(eFootnote.attributeValue(TYPE) - .equals(AUTONUMLABEL))) { - footnote.addAttribute(ATTR_IDS, eFootnote - .attributeValue(BACKREFS)); - footnote.addAttribute(ATTR_REFID, - eFootnote.attributeValue(ATTR_IDS)); - footnote.setText(label); - lblFootnotesRef.add(Integer - .parseInt(label)); - valide = true; - } else { - valide = false; - lbls[Integer.parseInt(label) - 1] = true; - } - } - } - } while (!valide); - - } - - else { - footnote.addAttribute(AUTO, "1"); - - String name = id.substring(1); - boolean trouve = false; - for (int j = 0; j < eFootnotes.size() && !trouve; j++) { - Element eFootnote = eFootnotes.get(j); - if (eFootnote.attributeValue(NAMES).equals(name)) { - footnote.addAttribute(ATTR_IDS, eFootnote - .attributeValue(BACKREFS)); - footnote.addAttribute(ATTR_REFID, eFootnote - .attributeValue(ATTR_IDS)); - String label = eFootnote - .attributeValue(LABEL); - footnote.setText(label); - lblFootnotesRef.add(Integer.parseInt(label)); - trouve = true; - } - } - - footnote.addAttribute(NAMES, name); - } - done = true; - } - } - 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()); - String txtFin = text.substring(matcher.end(), text.length()); - String ref = text.substring(matcher.start(), matcher.end() - 2); - ref = ref.replaceAll("`", ""); - Element anonym = DocumentHelper.createElement(REFERENCE); - anonym.addAttribute(ANONYMOUS, "1"); - anonym.addAttribute(NAME, ref.trim()); - if (!eTargetAnonymous.isEmpty()) { - Element target = eTargetAnonymous.getFirst(); - eTargetAnonymous.removeFirst(); - anonym.addAttribute(REFURI, target.attributeValue(REFURI)); - } - anonym.setText(ref); - 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 = StringEscapeUtils.unescapeXml(ref); - ref = ref.replaceAll("('|_)", ""); - ref = ref.replaceAll("`", ""); - Element hyper = DocumentHelper.createElement(REFERENCE); - hyper.addAttribute(NAME, ref); - boolean trouve = false; - for (int i = 0; i < eTarget.size() && !trouve; i++) { - Element el = eTarget.get(i); - String refTmp = URLEncoder.encode(ref.replaceAll("\\s", "-").toLowerCase(), "UTF-8"); - if (el.attributeValue(ID).equalsIgnoreCase((refTmp))) { - hyper.addAttribute(REFURI, el.attributeValue(REFURI)); - trouve = true; - } - } - if (!trouve) { - hyper.addAttribute(ATTR_REFID, ref); - } - hyper.setText(ref); - text = txtDebut + hyper.asXML() + " " + txtFin; - matcher = REGEX_HYPERLINK_REFERENCE.matcher(text); - - } - - // substitution reference - matcher = REGEX_SUBSTITUTION_REFERENCE.matcher(text); - int begin = 0; - while (matcher.find(begin)) { - String start = text.substring(0, matcher.start()); - String end = text.substring(matcher.end()); - String ref = matcher.group(1); - - Node subst = e.selectSingleNode("//" + SUBSTITUTION_DEFINITION - + "[@name='" + ref + "']/child::node()"); - - if (subst == null) { - text = start + "|" + ref + "|"; - } else { - text = start + subst.asXML(); - } - - begin = text.length(); - text += end; - matcher = REGEX_SUBSTITUTION_REFERENCE.matcher(text); - - } - // undo substitution in LITERAL - Pattern p = Pattern.compile("<tmp>([^<>]+)</tmp>"); - - matcher = p.matcher(text); - while (matcher.find()) { - String start = text.substring(0, matcher.start()); - String end = text.substring(matcher.end()); - - String tempKey = matcher.group(1); - text = start + temporaries.get(tempKey) + end; - matcher = p.matcher(text); - } - - String resultElementText = text.trim(); - Element result = DocumentHelper.parseText( - "<TMP>" + resultElementText + "</TMP>").getRootElement(); - - e.setText(""); - e.appendContent(result); - } -} Deleted: branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/AdvancedReaderTest.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/AdvancedReaderTest.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/AdvancedReaderTest.java 2012-04-24 09:23:11 UTC (rev 644) @@ -1,328 +0,0 @@ -/* - * #%L - * JRst :: Api - * - * $Id$ - * $HeadURL$ - * %% - * 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 java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.StringReader; -import java.io.Writer; - -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * AdvancedReaderTest. - * - * Created: 27 oct. 06 01:03:26 - * - * @author poussin - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - */ -public class AdvancedReaderTest extends JRSTAbstractTest { - - protected String text = "\t\t\n" + "1 toto tata tutu\n" + "2 toto tata tutu\n" - + "3 toto tata tutu\n" + "4 toto tata tutu\n" - + "5 toto tata tutu\n" + "6 toto tata tutu\n" - + "7 toto tata tutu\n" + "8 toto tata tutu\n" - + "9 toto tata tutu\n"; - - protected File file; - - /** - * Creates the temporary directory used by createTempFile - */ - @BeforeClass - static public void createTmpDir() { - File tmp = new File(System.getProperty("java.io.tmpdir")); - tmp.mkdirs(); - } - - /** - * setUp - create test file. - * @throws IOException - */ - @Before - public void setUp() throws IOException { - file = getOutputTestFile("test-AdvancedReader.txt"); - - Writer out = new BufferedWriter(new FileWriter(file)); - out.write(text); - out.close(); - } - - /** - * Test method for {@link org.nuiton.jrst.AdvancedReader#eof()}. - * @throws IOException - */ - @Test - public void testEof() throws IOException { - AdvancedReader in = new AdvancedReader(new FileReader(file)); - assertFalse(in.eof()); - in.readAll(); - assertTrue(in.eof()); - - in = new AdvancedReader(new StringReader(text)); - assertFalse(in.eof()); - in.readAll(); - assertTrue(in.eof()); - } - - /** - * Test method for - * {@link org.nuiton.jrst.AdvancedReader#skipBlankLines()}. - * @throws IOException - */ - @Test - public void testSkipBlankLines() throws IOException { - { - AdvancedReader in = new AdvancedReader(new FileReader(file)); - in.skipBlankLines(); - String line = in.readLine(); - assertEquals("1 toto tata tutu", line); - } - - { - AdvancedReader in = new AdvancedReader(new StringReader(text)); - in.skipBlankLines(); - String line = in.readLine(); - assertEquals("1 toto tata tutu", line); - } - } - - /** - * Test method for {@link org.nuiton.jrst.AdvancedReader#readAll()}. - * @throws IOException - */ - @Test - public void testReadAll() throws IOException { - { - AdvancedReader in = new AdvancedReader(new FileReader(file)); - String[] lines = in.readAll(); - assertEquals(10, lines.length); - assertEquals("\t\t", lines[0]); - assertEquals("1 toto tata tutu", lines[1]); - assertEquals("9 toto tata tutu", lines[9]); - } - - { - AdvancedReader in = new AdvancedReader(new StringReader(text)); - String[] lines = in.readAll(); - assertEquals(10, lines.length); - assertEquals("\t\t", lines[0]); - assertEquals("1 toto tata tutu", lines[1]); - assertEquals("9 toto tata tutu", lines[9]); - } - } - - /** - * Test method for {@link org.nuiton.jrst.AdvancedReader#readLines(int)}. - * @throws IOException - */ - @Test - public void testReadLines() throws IOException { - { - AdvancedReader in = new AdvancedReader(new FileReader(file)); - String[] lines = in.readLines(3); - assertEquals(3, lines.length); - assertEquals("\t\t", lines[0]); - assertEquals("1 toto tata tutu", lines[1]); - assertEquals("2 toto tata tutu", lines[2]); - } - - { - AdvancedReader in = new AdvancedReader(new StringReader(text)); - String[] lines = in.readLines(3); - assertEquals(3, lines.length); - assertEquals("\t\t", lines[0]); - assertEquals("1 toto tata tutu", lines[1]); - assertEquals("2 toto tata tutu", lines[2]); - } - } - - /** - * Test method for - * {@link org.nuiton.jrst.AdvancedReader#readUntil(java.lang.String)}. - * @throws IOException - */ - @Test - public void testReadUntil() throws IOException { - { - AdvancedReader in = new AdvancedReader(new FileReader(file)); - String[] lines = in.readUntil("^3.*$"); - assertEquals(3, lines.length); - assertEquals("\t\t", lines[0]); - assertEquals("1 toto tata tutu", lines[1]); - assertEquals("2 toto tata tutu", lines[2]); - - String line = in.readLine(); - assertEquals("3 toto tata tutu", line); - } - - { - AdvancedReader in = new AdvancedReader(new StringReader(text)); - String[] lines = in.readUntil("^3.*$"); - assertEquals(3, lines.length); - assertEquals("\t\t", lines[0]); - assertEquals("1 toto tata tutu", lines[1]); - assertEquals("2 toto tata tutu", lines[2]); - - String line = in.readLine(); - assertEquals("3 toto tata tutu", line); - } - } - - /** - * Test method for - * {@link org.nuiton.jrst.AdvancedReader#readUntil(java.lang.String)}. - * @throws IOException - */ - @Test - public void testReadWhile() throws IOException { - { - AdvancedReader in = new AdvancedReader(new FileReader(file)); - in.skipBlankLines(); - String[] lines = in.readWhile("^[123].*$"); - assertEquals(3, lines.length); - assertEquals("1 toto tata tutu", lines[0]); - assertEquals("2 toto tata tutu", lines[1]); - assertEquals("3 toto tata tutu", lines[2]); - - String line = in.readLine(); - assertEquals("4 toto tata tutu", line); - } - - { - AdvancedReader in = new AdvancedReader(new StringReader(text)); - in.skipBlankLines(); - String[] lines = in.readWhile("^[123].*$"); - assertEquals(3, lines.length); - assertEquals("1 toto tata tutu", lines[0]); - assertEquals("2 toto tata tutu", lines[1]); - assertEquals("3 toto tata tutu", lines[2]); - - String line = in.readLine(); - assertEquals("4 toto tata tutu", line); - } - } - - /** - * Test method for {@link org.nuiton.jrst.AdvancedReader#readLine()}. - * @throws IOException - */ - @Test - public void testReadLine() throws IOException { - { - AdvancedReader in = new AdvancedReader(new FileReader(file)); - String line = in.readLine(); - assertEquals("\t\t", line); - line = in.readLine(); - assertEquals("1 toto tata tutu", line); - line = in.readLine(); - assertEquals("2 toto tata tutu", line); - } - - { - AdvancedReader in = new AdvancedReader(new StringReader(text)); - String line = in.readLine(); - assertEquals("\t\t", line); - line = in.readLine(); - assertEquals("1 toto tata tutu", line); - line = in.readLine(); - assertEquals("2 toto tata tutu", line); - } - } - - @Test - public void testMark() throws IOException { - AdvancedReader in = new AdvancedReader(new StringReader(text)); - String line = in.readLine(); - in.mark(); - line = in.readLine(); - assertEquals("1 toto tata tutu", line); - in.reset(); - line = in.readLine(); - assertEquals("1 toto tata tutu", line); - } - - @Test - public void testUnread() throws IOException { - AdvancedReader in = new AdvancedReader(new StringReader(text)); - assertEquals(0, in.getCharNumber()); - assertEquals(0, in.getLineNumber()); - String line = in.readLine(); - assertEquals(3, in.getCharNumber()); - assertEquals(1, in.getLineNumber()); - line = in.readLine(); - assertEquals(4 + "1 toto tata tutu".length(), in.getCharNumber()); - assertEquals(2, in.getLineNumber()); - assertEquals("1 toto tata tutu", line); - in.unread(line.length() + 1); - assertEquals(3, in.getCharNumber()); - assertEquals(1, in.getLineNumber()); - line = in.readLine(); - assertEquals(4 + "1 toto tata tutu".length(), in.getCharNumber()); - assertEquals(2, in.getLineNumber()); - assertEquals("1 toto tata tutu", line); - } - - @Test - public void testSkip() throws IOException { - AdvancedReader in = new AdvancedReader(new StringReader(text)); - in.skip(3); - String line = in.readLine(); - assertEquals("1 toto tata tutu", line); - in.skip(text.length()); - line = in.readLine(); - assertNull(line); - } - - /** - * Test que les caracteres de fin de ligne \n et \r\n sont bien gérés. - * - * @throws IOException - */ - @Test - public void testEol() throws IOException { - String tmp = text; - AdvancedReader in = new AdvancedReader(new StringReader(tmp)); - String[] linesN = in.readAll(); - tmp = tmp.replace('\n', '\r'); - in = new AdvancedReader(new StringReader(tmp)); - String[] linesR = in.readAll(); - tmp = tmp.replaceAll("\r", "\r\n"); - in = new AdvancedReader(new StringReader(tmp)); - String[] linesRN = in.readAll(); - assertArrayEquals(linesN, linesR); - assertArrayEquals(linesN, linesRN); - } -} Deleted: branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/Compare.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/Compare.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/Compare.java 2012-04-24 09:23:11 UTC (rev 644) @@ -1,231 +0,0 @@ -/* - * #%L - * JRst :: Api - * - * $Id$ - * $HeadURL$ - * %% - * 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 java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.net.URL; -import java.util.LinkedList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTextArea; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.custommonkey.xmlunit.DetailedDiff; -import org.custommonkey.xmlunit.XMLUnit; -import org.dom4j.Document; -import org.dom4j.io.OutputFormat; -import org.dom4j.io.SAXReader; -import org.dom4j.io.XMLWriter; -import org.junit.Ignore; - -import sdoc.*; - -/** - * Class de test pour comparer le XML de DocUtils avec celui du JRST - */ -@Ignore -public class Compare { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - private static Log log = LogFactory.getLog(Compare.class); - - static boolean[] bColorRst; - - static boolean[] bColorPython; - - public static void main(String[] args) throws Exception { - File source = null; - if (args.length > 0) { - source = new File(args[0]); - parser(source); - } else { - JFileChooser fc = new JFileChooser(); - fc.showOpenDialog(new JFrame()); - parser(fc.getSelectedFile()); - } - } - - private static void parser(File source) throws Exception { - URL url = source.toURI().toURL(); - Reader in = new InputStreamReader(url.openStream()); - JRSTReader jrst = new JRSTReader(); - Document docRst = jrst.read(in); // JRST - String cmd = "rst2xml.py " + source.getPath(); - Process p = null; - try { - p = Runtime.getRuntime().exec(cmd); // Python - } catch (IOException eee) { - log.error("You must install python-docutils to compare rst files"); - System.exit(0); - } - ThreadRedirection t = new ThreadRedirection(p); - t.start(); - p.waitFor(); // On attend que le processus ce termine - t.stop(); - p.destroy(); - SAXReader sr = new SAXReader(); - Document docPython = sr.read(new StringReader(t.getOutput())); - String diff = test(docRst, docPython); - String sDocRst = indent(docRst); // On indente - String sDocPython = indent(docPython); - compare(sDocRst, sDocPython, diff); - } - - private static String test(Document docRst, Document docPython) - throws Exception { - String[] sDocRst = indent(docRst).split("\n"); - bColorRst = new boolean[sDocRst.length]; - for (int i = 0; i < bColorRst.length; i++) - bColorRst[i] = false; - String[] sDocPython = indent(docPython).split("\n"); - bColorPython = new boolean[sDocPython.length]; - for (int i = 0; i < bColorPython.length; i++) - bColorPython[i] = false; - XMLUnit.setIgnoreComments(true); - XMLUnit.setIgnoreAttributeOrder(true); - XMLUnit.setNormalizeWhitespace(true); - XMLCaseTest test = new XMLCaseTest("test"); - DetailedDiff myDiff = test.testAllDifferences(docPython.asXML(), docRst - .asXML()); - List allDifferences = myDiff.getAllDifferences(); - String text = ""; - Pattern pattern = Pattern.compile("at\\s(\\/\\w+\\[\\d+])+"); - for (int i = 0; i < allDifferences.size(); i++) { - String diff = allDifferences.get(i).toString(); - int nbLineRst = 0; - int nbLinePython = 0; - Matcher matcher = pattern.matcher(diff); - if (matcher.find()) { - nbLineRst = findLine(matcher.group(), sDocRst); - bColorRst[nbLineRst] = true; - } - if (matcher.find()) { - nbLinePython = findLine(matcher.group(), sDocPython); - bColorPython[nbLinePython] = true; - } - text += "L python : " + (nbLinePython + 1) + " L rst : " - + (nbLineRst + 1) + " " + diff + "\n\n"; - } - return text; - } - - private static int findLine(String match, String[] doc) { - Pattern pattern2 = Pattern.compile("\\/\\w+\\[\\d+]"); - Matcher matcher2 = pattern2.matcher(match); - LinkedList<String> names = new LinkedList<String>(); - LinkedList<Integer> rgs = new LinkedList<Integer>(); - while (matcher2.find()) { - names.add(matcher2.group().substring(1, - matcher2.group().indexOf("["))); - rgs.add(Integer.valueOf(matcher2.group().substring( - matcher2.group().indexOf("[") + 1, - matcher2.group().indexOf("]")))); - } - int cntName = 0; - int nbLine = 0; - for (String name : names) { - int trouve = 0; - for (int i = nbLine; i < doc.length; i++) { - String line = doc[i]; - if (line.matches(".*\\<" + name + ".*")) { - trouve++; - if (trouve == rgs.get(cntName)) { - nbLine = i; - } - } - } - cntName++; - } - return nbLine; - } - - private static void compare(String docRst, String docPython, String diff) { - JTextArea jrst = new JTextArea(); - JTextArea python = new JTextArea(); - jrst.setEditable(false); - python.setEditable(false); - SyntaxSupport support = SyntaxSupport.getInstance(); - support.addSupport(SyntaxSupport.XML_LEXER, jrst); // Coloration - support.addSupport(SyntaxSupport.XML_LEXER, python); - - jrst.getDocument().putProperty(SyntaxDocument.tabSizeAttribute, - new Integer(2)); - python.getDocument().putProperty(SyntaxDocument.tabSizeAttribute, - new Integer(2)); - - JScrollPane spJrst = new JScrollPane(jrst); - JScrollPane spPython = new JScrollPane(python); - - // Ajout de gutterColor : la numerotation des lignes et coloration des - // erreurs - spJrst.setRowHeaderView(new GutterColor(jrst, spJrst, bColorRst)); - spPython.setRowHeaderView(new GutterColor(python, spPython, - bColorPython)); - jrst.setText(docRst); - python.setText(docPython); - JScrollPane droit = new JScrollPane(spJrst); - JScrollPane gauche = new JScrollPane(spPython); - JFrame comparateur = new JFrame(); - JSplitPane separateurVert = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, - true, gauche, droit); - separateurVert.setResizeWeight(0.5); - separateurVert.setOneTouchExpandable(true); - separateurVert.setContinuousLayout(true); - JTextArea differences = new JTextArea(diff); - differences.setRows(10); - differences.setEditable(false); - JScrollPane scrollDiff = new JScrollPane(differences); - JSplitPane separateurHoriz = new JSplitPane(JSplitPane.VERTICAL_SPLIT, - true, separateurVert, scrollDiff); - separateurHoriz.setResizeWeight(0.7); - comparateur.add(separateurHoriz); - comparateur.setSize(1280, 900); - comparateur.setVisible(true); - comparateur.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - comparateur.setTitle("Comparateur"); - } - - private static String indent(Document xml) throws IOException { - // Indentation du document - OutputFormat of = new OutputFormat(" ", true); - StringWriter out = new StringWriter(); - XMLWriter writer = new XMLWriter(out, of); - writer.write(xml); - writer.close(); - return out.toString(); - } -} Deleted: branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTCompareDocutils.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTCompareDocutils.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTCompareDocutils.java 2012-04-24 09:23:11 UTC (rev 644) @@ -1,344 +0,0 @@ -/* - * #%L - * JRst :: Api - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2011 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 junit.framework.Assert; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.custommonkey.xmlunit.DetailedDiff; -import org.custommonkey.xmlunit.Diff; -import org.custommonkey.xmlunit.DifferenceListener; -import org.custommonkey.xmlunit.IgnoreTextAndAttributeValuesDifferenceListener; -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.io.SAXReader; -import org.dom4j.io.XMLWriter; -import org.nuiton.i18n.I18n; -import org.nuiton.i18n.init.ClassPathI18nInitializer; -import org.nuiton.util.FileUtil; - -import javax.xml.transform.TransformerException; -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.net.URL; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; - -public class JRSTCompareDocutils { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - private static Log log = LogFactory.getLog(JRSTCompareDocutils.class); - - /** Commande utilisee pour transformer le rst en xml */ - private static String rst2xml = "rst2xml"; - - /** Commande utilisee pour transformer le rst en html */ - private static String rst2html = "rst2html"; - - public static void prepareTmpDir() throws IOException { - - File testFile = new File(System.getProperty("java.io.tmpdir")); - - FileUtil.createDirectoryIfNecessary(testFile); - } - - public static void main(String[] args) throws Exception { - - I18n.init(new ClassPathI18nInitializer(), Locale.UK); - - JRSTCompareDocutils jT = new JRSTCompareDocutils(); - - File rep = null; - if (args.length > 0) { - rep = new File(args[0]); - jT.runCompare(rep); - } - else { - jT.runCompare(new File("src/test/resources/FilesTest/")); - } - - } - - - /** - * - * @param rep - * @throws Exception - */ - public void runCompare(File rep) throws Exception { - - if(testIfDocutils()) { - //File rep = new File("src/test/resources/FilesTest/"); - - LinkedList<File> rstFilesTests = new LinkedList<File>(); - - //1. recuperation des fichiers de test directement dans le repertoire des fichiers rst - class NormalFileFilter implements FileFilter { - @Override - public boolean accept(File f) { - return f.isFile(); - } - } - rstFilesTests.addAll(FileUtil.getFilteredElements(rep,new NormalFileFilter(),false)); - - //2. boucle sur les fichiers de test - Iterator<File> iteFiles = rstFilesTests.iterator(); - - File testFile; - - - String res=""; - - while(iteFiles.hasNext()) { - testFile = iteFiles.next(); - log.debug("fichier test : "+testFile.getName()); - res+="\nFichier test: "+testFile.getName(); - - //Compare XML - if (compareXML(getXMLJrst(testFile),getDocPython(testFile,rst2xml))) { - res+="\tXML->OK\n"; - } - else { - res+="\n\tXML->KO\n"; - } - - //Compare HTML - if (compareHTML(testFile)) { - res+="\tHTML->OK\n"; - } - else { - res+="\tHTML->KO\n"; - } - - //Compare RST - /*if (compareRST(testFile)) { - res+="\tRST->OK\n"; - } - else { - res+="\tRST->KO\n"; - }*/ - log.debug("=========================================================="); - } - - log.info(res); - } - Assert.assertTrue(true); - } - - - /** - * - * @param compare - * @param base - * @return - * @throws Exception - */ - private boolean compareXML(Document compare, Document base) throws Exception { - - Document docRst = compare; // JRST - - Document docPython = base; // docutils - - - XMLCaseTest test = new XMLCaseTest("testXML"); - DetailedDiff myDiff = test.testAllDifferences(docPython.asXML(), docRst.asXML()); - List<?> allDifferences = myDiff.getAllDifferences(); - - - log.debug("Nombre de difference XML: "+allDifferences.size()); - - - - return myDiff.similar(); - - } - - - /** - * - * @param testFile - * @return - * @throws Exception - */ - private boolean compareHTML(File testFile) throws Exception { - - String htmlJRST = getHTMLJrst(testFile); - - Document htmlPython = getDocPython(testFile,rst2html); - - String BadlyFormedJRST2HTML = htmlJRST; - - String BadlyFormedPython2HTML = toWriter(htmlPython).toString(); - - DifferenceListener myDifferenceListener = new IgnoreTextAndAttributeValuesDifferenceListener(); - - Diff myDiff = new Diff(BadlyFormedJRST2HTML, BadlyFormedPython2HTML); - - myDiff.overrideDifferenceListener(myDifferenceListener); - - return myDiff.similar(); - } - - - /** - * - * @param testFile - * @return - * @throws Exception - */ - /* private boolean compareRST(File testFile) throws Exception { - - //recuperation du XML cree depuis le RST avec JRST - Document rst2xml = getXMLJrst(testFile); - - //recuperation du rst genere depuis le xml - String rst2rst = getRSTJrst(testFile); - - JRSTReader jrst = new JRSTReader(); - - Document rst2rst2xml = jrst.read(new StringReader(rst2rst)); // JRST - - return compareXML(rst2xml, rst2rst2xml); - //return true; - - } */ - - - /** - * Permet de recuperer le fichier XML genere par JRST - * @param source - * @return Document le xml genere - * @throws Exception - */ - private Document getXMLJrst(File source) throws Exception { - URL url = source.toURI().toURL(); - Reader in = new InputStreamReader(url.openStream()); - - JRSTReader jrst = new JRSTReader(); - - return jrst.read(in); // JRST - - } - - /** - * - * @param source - * @return - * @throws Exception - */ - private String getHTMLJrst(File source) throws Exception { - return JRST.generateString(JRST.Format.HTML.name(), source); - } - - /** - * - * @param source - * @return - * @throws Exception - */ - /*private String getRSTJrst(File source) throws Exception { - return JRST.generateString(JRST.Format.RST.name(),source); - } */ - - - /** - * Permet de recuperer le fichier genere par docutils en specifiant son type - * @param source - * @return Document le xml genere - * @throws IOException - * @throws TransformerException - * @throws Exception - */ - private Document getDocPython(File source, String action) throws DocumentException, InterruptedException, TransformerException, IOException { - - ProcessBuilder processBuilder = new ProcessBuilder(action, source.getPath()); - processBuilder.redirectErrorStream(true); - Process p = processBuilder.start(); - - ThreadRedirection t = new ThreadRedirection(p); - t.start(); - p.waitFor(); - t.join(); - //On attend que le processus ce termine - //t.stop(); - p.destroy(); - - - SAXReader sr = new SAXReader(false); - - return sr.read(new StringReader(t.getOutput())); - - } - - - private static boolean testIfDocutils() { - - File file = new File("src/test/resources/FilesTest/rstTest.rst"); - - ProcessBuilder processBuilder = new ProcessBuilder(rst2xml, file.getPath()); - processBuilder.redirectErrorStream(true); - @SuppressWarnings("unused") - Process p =null; - - try { - p = processBuilder.start(); - } - catch(IOException ioe) { - rst2xml="rst2xml.py"; - rst2html="rst2html.py"; - processBuilder = new ProcessBuilder(rst2xml, file.getPath()); - try { - p = processBuilder.start(); - } catch (IOException e) { - log.warn("You must install python-docutils to compare rst files"); - return false; - } - } - p.destroy(); - return true; - - } - - - - private static StringWriter toWriter(org.dom4j.Document dom4jdoc) throws TransformerException, IOException { - - StringWriter writer = new StringWriter(); - XMLWriter xmlWriter = new XMLWriter(writer); - - xmlWriter.write(dom4jdoc); - return writer; - } - - - -} Modified: branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTGeneratorTest.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTGeneratorTest.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTGeneratorTest.java 2012-04-24 09:23:11 UTC (rev 644) @@ -66,6 +66,10 @@ JRST.main(new String[]{"-t", "rst", "--force", "-o", test1, getResourcesTestPath()}); } + /** + * Test ignoré car un des fichier contenu dans le jar de docutils n'est pas trouvé + * @throws Exception + */ @Ignore @Test public void testRstToHtml() throws Exception { Deleted: branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTReaderTest.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTReaderTest.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/JRSTReaderTest.java 2012-04-24 09:23:11 UTC (rev 644) @@ -1,210 +0,0 @@ -/* - * #%L - * JRst :: Api - * - * $Id$ - * $HeadURL$ - * %% - * 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 org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.dom4j.Document; - -import java.io.*; -import java.net.URL; -import java.util.Locale; - -import junit.framework.Assert; - -import org.junit.Test; -import org.nuiton.i18n.I18n; -import org.nuiton.i18n.init.ClassPathI18nInitializer; - -/** - * JRSTReaderTest. - * - * Created: 27 oct. 06 12:11:44 - * - * @author poussin - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - */ -public class JRSTReaderTest extends JRSTAbstractTest { - - /** to use log facility, just put in your code: log.info("..."); */ - protected static Log log = LogFactory.getLog(JRSTReaderTest.class); - - @Test - public void testRead() throws Exception { - URL url = JRSTReaderTest.class - .getResource("/test.rst"); - Reader in = new InputStreamReader(url.openStream()); - - JRSTReader jrst = new JRSTReader(); - Document doc = jrst.read(in); - - log.info(url + " result : \n" + doc.asXML()); - } - - @Test - public void testEmptyTableContents() throws Exception { - String fileName = "testEmptyTableContents.rst"; - InputStream testStream = getTestStream(fileName); - Reader in = new InputStreamReader(testStream); - JRSTReader jrst = new JRSTReader(); - Document doc = jrst.read(in); - String xmlexpected = "<topic class=\"contents\" ids=\"table des matières\" names=\"table des matières\">" + - "<title>Table des matières</title>" + - "</topic>" + - "<paragraph>Texte</paragraph>" + - "</document>"; - String actualXml = doc.asXML(); - - assertXmlContain(fileName, actualXml, xmlexpected); - } - - @Test - public void testExternalLink() throws Exception { - String fileName = "testExternalLink.rst"; - InputStream testStream = getTestStream(fileName); - Reader in = new InputStreamReader(testStream); - JRSTReader jrst = new JRSTReader(); - Document doc = jrst.read(in); - String xmlexpected = "<paragraph>External hyperlinks, like <reference name=\"Python\" refuri=\"http://www.python.org/\">Python</reference></paragraph>" + - "<target id=\"python\" name=\"python\" refuri=\"http://www.python.org/\"/>" + - "</document>"; - - String actualXml = doc.asXML(); - - assertXmlContain(fileName, actualXml, xmlexpected); - } - - @Test - public void testHyperlinkTarget() throws Exception { - String fileName = "testHyperlinkTarget.rst"; - InputStream testStream = getTestStream(fileName); - Reader in = new InputStreamReader(testStream); - JRSTReader jrst = new JRSTReader(); - Document doc = jrst.read(in); - String actualXml = doc.asXML(); - int index = actualXml.indexOf("<paragraph"); - actualXml = actualXml.substring(index).trim(); - URL xmlUrl = JRSTReaderTest.class.getResource("/testHyperlinkTarget.xml"); - Reader xmlIn = new InputStreamReader(xmlUrl.openStream()); - BufferedReader reader = new BufferedReader(xmlIn); - String line; - StringBuilder buffer = new StringBuilder(); - String ls = System.getProperty("line.separator"); - while ((line = reader.readLine()) != null) { - buffer.append(line); - buffer.append(ls); - } - String xmlexpected = buffer.toString(); - index = xmlexpected.indexOf("<paragraph"); - xmlexpected = xmlexpected.substring(index).trim(); - - assertXmlEqual(fileName, actualXml, xmlexpected); - } - - @Test - public void testAnonymous() throws Exception { - String fileName = "testAnonymous.rst"; - InputStream testStream = getTestStream(fileName); - Reader in = new InputStreamReader(testStream); - I18n.init(new ClassPathI18nInitializer(), Locale.UK); - - JRSTReader jrst = new JRSTReader(); - Document doc = jrst.read(in); - - - String xmlexpected ="<target anonymous=\"1\" ids=\"id1\" refuri=\"http://www.python.org\"/>" - +"<target anonymous=\"1\" ids=\"id2\" refuri=\"http://www.python.org\"/>"; - - - String actualXml = doc.asXML(); - - assertXmlContain(fileName, actualXml, xmlexpected); - } - - @Test - public void testLiteral() throws Exception { - String fileName = "testLiteral.rst"; - InputStream testStream = getTestStream(fileName); - Reader in = new InputStreamReader(testStream); - I18n.init(new ClassPathI18nInitializer(), Locale.UK); - - JRSTReader jrst = new JRSTReader(); - Document doc = jrst.read(in); - - - String xmlexpected = - "<literal_block> refcomp.admin.email=l'email des administrateurs. Example : admin@refcomp.com\n" + - "\n" + - "</literal_block></list_item></enumerated_list><paragraph>Paragraphe test</paragraph></document>"; - - String actualXml = doc.asXML(); - - assertXmlContain(fileName, actualXml, xmlexpected); - } - - @Test - public void testFootnote() throws Exception { - String fileName = "testFootnote.rst"; - Reader in = new InputStreamReader(getTestStream(fileName)); - I18n.init(new ClassPathI18nInitializer(), Locale.UK); - - JRSTReader jrst = new JRSTReader(); - Document doc = jrst.read(in); - - - String xmlexpected = - "<footnote_reference ids=\"id1\" refid=\"id2\">1</footnote_reference>" + - "</paragraph><footnote backrefs=\"id1\" ids=\"id2\" name=\"1\"><label>1</label>"; - - String actualXml = doc.asXML(); - - assertXmlContain(fileName, actualXml, xmlexpected); - } - - protected void assertXmlEqual(String fileName, String actualXml, String xmlexpected) { - log(fileName, actualXml, xmlexpected); - - Assert.assertEquals(xmlexpected, actualXml); - } - - protected void assertXmlContain(String fileName, String actualXml, String xmlexpected) { - log(fileName, actualXml, xmlexpected); - - Assert.assertTrue(actualXml.contains(xmlexpected)); - } - - protected void log(String fileName, String actualXml, String xmlexpected) { - - if (log.isDebugEnabled()) { - log.debug("Test file : " + fileName); - log.debug("Result :\n" + actualXml); - log.debug("Expected :\n" + xmlexpected); - } - } -} Modified: branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/AdmonitionTest.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/AdmonitionTest.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/AdmonitionTest.java 2012-04-24 09:23:11 UTC (rev 644) @@ -53,11 +53,13 @@ public void testAdmonitionInList() throws Exception { File in = getBugTestFile("testAdminitionInList1787.rst"); File out = getOutputTestFile("jrst-testAdminitionInList1787.html"); + + log.info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " + in.getPath()); + log.info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " + out.getPath()); // out.deleteOnExit(); JRST.generate(JRST.Format.HTML.name(), in, out, JRST.Overwrite.ALLTIME); String content = FileUtils.readFileToString(out); - // Must contains <div class="note"> assertTrue(content.contains("<div class=\"note\">")); } Deleted: branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/InfiniteLoopTest.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/InfiniteLoopTest.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/InfiniteLoopTest.java 2012-04-24 09:23:11 UTC (rev 644) @@ -1,77 +0,0 @@ -/* - * #%L - * JRst :: Api - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2010 CodeLutin, Chatellier Eric - * %% - * 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.bugs; - -import org.dom4j.Document; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.nuiton.jrst.JRSTAbstractTest; -import org.nuiton.jrst.JRSTCompareDocutils; -import org.nuiton.jrst.JRSTReader; -import org.nuiton.jrst.JRSTReaderTest; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; - -/** - * Test for infinite loop bug. - * - * @author chatellier - * @version $Revision$ - * <p/> - * Last update : $Date$ - * By : $Author$ - */ -public class InfiniteLoopTest extends JRSTAbstractTest { - - @BeforeClass - public static void beforeClass () throws IOException { - JRSTCompareDocutils.prepareTmpDir(); - } - - /** - * Test de parser un fichier et déclare le test en echec si il dure - * plus de 5s. (bug #697). - * - * @throws Exception if any - */ - @Test(timeout = 5000) - public void testInfiniteLoop() throws Exception { - URL url = JRSTReaderTest.class.getResource("/bugs/infiniteLoop.rst"); - Reader in = new InputStreamReader(url.openStream()); - try { - JRSTReader jrst = new JRSTReader(); - Document doc = jrst.read(in); - Assert.assertNotNull(doc); - } finally { - in.close(); - } - - } -} Modified: branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/TitlesTest.java =================================================================== --- branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/TitlesTest.java 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/test/java/org/nuiton/jrst/bugs/TitlesTest.java 2012-04-24 09:23:11 UTC (rev 644) @@ -27,14 +27,11 @@ import junit.framework.Assert; import org.apache.commons.io.FileUtils; -import org.junit.BeforeClass; import org.junit.Test; import org.nuiton.jrst.JRST; import org.nuiton.jrst.JRSTAbstractTest; -import org.nuiton.jrst.JRSTCompareDocutils; import java.io.File; -import java.io.IOException; /** * Test concernant les titres en général. @@ -47,11 +44,6 @@ */ public class TitlesTest extends JRSTAbstractTest { - @BeforeClass - public static void beforeClass () throws IOException { - JRSTCompareDocutils.prepareTmpDir(); - } - /** * Test que la génération fonctionne meme s'il n'y a pas de titre * de niveau 2. Modified: branches/jrst-docutils-jython/jrst/src/test/resources/bugs/testAdminitionInList1787.rst =================================================================== --- branches/jrst-docutils-jython/jrst/src/test/resources/bugs/testAdminitionInList1787.rst 2012-04-24 07:49:14 UTC (rev 643) +++ branches/jrst-docutils-jython/jrst/src/test/resources/bugs/testAdminitionInList1787.rst 2012-04-24 09:23:11 UTC (rev 644) @@ -22,6 +22,7 @@ .. * <http://www.gnu.org/licenses/lgpl-3.0.html>. .. * #L% .. - + * item .. Note:: note
participants (1)
-
jpages@users.nuiton.org