2 * Copyright winterwell Mathematics Ltd.
3 * @author Daniel Winterstein
6 package winterwell.markdown.editors;
8 import org.eclipse.core.runtime.Assert;
9 import org.eclipse.jface.text.rules.ICharacterScanner;
10 import org.eclipse.jface.text.rules.IRule;
11 import org.eclipse.jface.text.rules.IToken;
12 import org.eclipse.jface.text.rules.MultiLineRule;
13 import org.eclipse.jface.text.rules.Token;
18 * @author Daniel Winterstein
20 public class EmphasisRule implements IRule {
21 private static char[][] fDelimiters = null;
22 private char[] fSequence;
23 protected IToken fToken;
26 public EmphasisRule(String marker, IToken token) {
27 assert marker.equals("*") || marker.equals("_") || marker.equals("**")
28 || marker.equals("***") || marker.equals("`") || marker.equals("``");
29 Assert.isNotNull(token);
30 fSequence = marker.toCharArray();
34 // Copied from org.eclipse.jface.text.rules.PatternRule
35 protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) {
36 for (int i = 1; i < sequence.length; i++) {
37 int c = scanner.read();
38 if (c == ICharacterScanner.EOF && eofAllowed) {
40 } else if (c != sequence[i]) {
41 // Non-matching character detected, rewind the scanner back to
43 // Do not unread the first character.
44 for (int j = i; j > 0; j--)
53 * @see IRule#evaluate(ICharacterScanner)
57 public IToken evaluate(ICharacterScanner scanner) {
58 // Should be connected only on the right side
60 boolean sawSpaceBefore = Character.isWhitespace(scanner.read());
61 if (!sawSpaceBefore && scanner.getColumn() != 0) {
62 return Token.UNDEFINED;
65 int c = scanner.read();
66 // Should be connected only on right side
67 if (c != fSequence[0] || !sequenceDetected(scanner, fSequence, false)) {
69 return Token.UNDEFINED;
71 int readCount = fSequence.length;
72 if (fDelimiters == null) {
73 fDelimiters = scanner.getLegalLineDelimiters();
75 // Start sequence detected
76 int delimiterFound = 0;
77 // Is it a list item marker, or just a floating *?
79 boolean after = Character.isWhitespace(scanner.read());
85 while (delimiterFound < 2
86 && (c = scanner.read()) != ICharacterScanner.EOF) {
89 if (!sawSpaceBefore && c == fSequence[0]
90 && sequenceDetected(scanner, fSequence, false)) {
95 for (i = 0; i < fDelimiters.length; i++) {
96 if (c == fDelimiters[i][0]
97 && sequenceDetected(scanner, fDelimiters[i], true)) {
102 if (i == fDelimiters.length)
104 sawSpaceBefore = Character.isWhitespace(c);
106 // Reached ICharacterScanner.EOF
107 for (; readCount > 0; readCount--)
109 return Token.UNDEFINED;