-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
205 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
redpen-core/src/main/java/cc/redpen/parser/rest/MultiLineProcessUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package cc.redpen.parser.rest; | ||
|
||
import cc.redpen.parser.common.Line; | ||
import cc.redpen.parser.common.LineParser; | ||
|
||
public class MultiLineProcessUtils { | ||
static boolean processMultiLineMatch(Character prevChar, Character nextChar, LineParser.TargetLine target) { | ||
Line prevLine = target.previousLine; | ||
Line nextLine = target.nextLine; | ||
if (prevChar != null && nextChar != null) { | ||
return processLineMatch(nextChar, nextLine) && processLineMatch(prevChar, prevLine); | ||
} else if (prevChar == null && nextChar != null) { | ||
return processLineMatch(nextChar, nextLine); | ||
} else if (prevChar != null && nextChar == null) { | ||
return processLineMatch(prevChar, prevLine); | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
static private boolean processLineMatch(char ch, Line line) { | ||
if (line == null) { return false; } | ||
if (line.isAllSameCharacter() && (line.length() >= 4) && line.charAt(0) == ch) { | ||
line.erase(); | ||
return true; | ||
} | ||
return false; | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
redpen-core/src/main/java/cc/redpen/parser/rest/ReSTLine.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package cc.redpen.parser.rest; | ||
|
||
import cc.redpen.parser.common.Line; | ||
|
||
public class ReSTLine extends Line { | ||
/** | ||
* Construct a line using the supplied string | ||
* | ||
* @param str the text of the line | ||
* @param lineno the original line number | ||
*/ | ||
public ReSTLine(String str, int lineno) { | ||
super(str, lineno); | ||
this.lineNo = lineno; | ||
this.inlineMarkupDelimiters = " _*`#^~.,"; | ||
if (!str.isEmpty()) { | ||
allSameCharacter = true; | ||
char lastCh = 0; | ||
for (int i = 0; i < str.length(); i++) { | ||
char ch = str.charAt(i); | ||
|
||
if ((i < str.length() - 1) && (ch == '\\')) { | ||
i++; | ||
ch = str.charAt(i); | ||
escaped.add(true); | ||
} | ||
else { | ||
escaped.add(false); | ||
} | ||
|
||
offsets.add(i); | ||
characters.add(ch); | ||
valid.add(true); | ||
|
||
if ((lastCh != 0) && (lastCh != ch)) { | ||
allSameCharacter = false; | ||
} | ||
lastCh = ch; | ||
} | ||
} | ||
|
||
// trim the end | ||
while (!characters.isEmpty() && | ||
Character.isWhitespace(characters.get(characters.size() - 1))) { | ||
characters.remove(characters.size() - 1); | ||
} | ||
} | ||
} |
101 changes: 101 additions & 0 deletions
101
redpen-core/src/main/java/cc/redpen/parser/rest/ReSTParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package cc.redpen.parser.rest; | ||
|
||
import cc.redpen.parser.PreprocessingReader; | ||
import cc.redpen.parser.common.Line; | ||
import cc.redpen.parser.common.LineParser; | ||
import cc.redpen.parser.common.Model; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.io.InputStream; | ||
|
||
import static cc.redpen.parser.rest.MultiLineProcessUtils.processMultiLineMatch; | ||
|
||
public class ReSTParser extends LineParser { | ||
private static final Logger LOG = LoggerFactory.getLogger(ReSTParser.class); | ||
/** | ||
* current parser state | ||
*/ | ||
private class State { | ||
// are we in a block | ||
public boolean inBlock = false; | ||
// are we in a list? | ||
public boolean inList = false; | ||
// are we in a table? | ||
public boolean inTable = false; | ||
// should we erase lines within the current block? | ||
public boolean eraseBlock = true; | ||
// the sort of block we are in | ||
public String type; | ||
} | ||
|
||
@Override | ||
protected void populateModel(Model model, InputStream io) { | ||
State state = new State(); | ||
PreprocessingReader reader = createReader(io); | ||
|
||
int lineno = 0; | ||
try { | ||
// add the lines to the model | ||
while (true) { | ||
String line = reader.readLine(); | ||
if (line == null) { | ||
break; | ||
} | ||
lineno++; | ||
model.add(new ReSTLine(line, lineno)); | ||
} | ||
reader.close(); | ||
|
||
model.setPreprocessorRules(reader.getPreprocessorRules()); | ||
|
||
for (model.rewind(); model.isMore(); model.getNextLine()) { | ||
processLine(model.getCurrentLine(), model, state); | ||
} | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
LOG.error("Exception when parsing reST file", e); | ||
} | ||
if (LOG.isDebugEnabled()) { | ||
LOG.debug("reST parser model (X=erased line,[=block,section-listlevel-lineno,*=list item):\n" + model.toString()); | ||
} | ||
} | ||
|
||
private void processLine(Line line, Model model, State state) { | ||
if (line.isErased()) { return; } | ||
|
||
TargetLine target = new TargetLine(line, | ||
model.getLine(line.getLineNo() - 1), | ||
model.getLine(line.getLineNo() + 1)); | ||
|
||
// handle section | ||
int level = extractSectionLevel(target); | ||
if (level > 0) {line.setSectionLevel(level);} | ||
} | ||
|
||
private int extractSectionLevel(TargetLine target) { | ||
if (processMultiLineMatch('#', '#', target)) { | ||
return 1; | ||
} if (processMultiLineMatch('*', '*', target)) { | ||
return 2; | ||
} else if (processMultiLineMatch('=', '=', target)) { | ||
return 3; | ||
} else if (processMultiLineMatch(null, '=', target)) { | ||
return 4; | ||
} else if (processMultiLineMatch('-', '-', target)) { // this is a subtitle? | ||
return 0; | ||
} else if (processMultiLineMatch(null, '-', target)) { | ||
return 5; | ||
} else if (processMultiLineMatch('~', '~', target)) { | ||
return 6; | ||
} else if (processMultiLineMatch(null, '~', target)) { | ||
return 7; | ||
} else if (processMultiLineMatch('^', '^', target)) { | ||
return 8; | ||
} else if (processMultiLineMatch(null, '^', target)) { | ||
return 9; | ||
} | ||
return -1; | ||
} | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
redpen-core/src/test/java/cc/redpen/parser/rest/MultiLineProcessUtilsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package cc.redpen.parser.rest; | ||
|
||
import cc.redpen.parser.common.LineParser; | ||
import org.junit.Test; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
public class MultiLineProcessUtilsTest { | ||
@Test | ||
public void testDetectThreeLineHeader() { | ||
LineParser.TargetLine target = new LineParser.TargetLine( | ||
new ReSTLine("This is a part", 1), | ||
new ReSTLine("#############", 0), | ||
new ReSTLine("#############", 2)); | ||
assertEquals(true, MultiLineProcessUtils.processMultiLineMatch('#', '#', target)); | ||
} | ||
|
||
@Test | ||
public void testDetectTwoLineHeader() { | ||
LineParser.TargetLine target = new LineParser.TargetLine( | ||
new ReSTLine("This is a part", 1), | ||
new ReSTLine("", 0), | ||
new ReSTLine("#############", 2)); | ||
assertEquals(true, MultiLineProcessUtils.processMultiLineMatch(null, '#', target)); | ||
} | ||
} |