]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/winterwell.markdown/src/winterwell/markdown/editors/EmphasisRule.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / winterwell.markdown / src / winterwell / markdown / editors / EmphasisRule.java
1 /**
2  * Copyright winterwell Mathematics Ltd.
3  * @author Daniel Winterstein
4  * 11 Jan 2007
5  */
6 package winterwell.markdown.editors;
7
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;
14
15 /**
16  * 
17  *
18  * @author Daniel Winterstein
19  */
20 public class EmphasisRule implements IRule {
21         private static char[][] fDelimiters = null;
22         private char[] fSequence;
23         protected IToken fToken;
24
25
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();
31                 fToken = token;
32         }
33         
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) {
39                                 return true;
40                         } else if (c != sequence[i]) {
41                                 // Non-matching character detected, rewind the scanner back to
42                                 // the start.
43                                 // Do not unread the first character.
44                                 for (int j = i; j > 0; j--)
45                                         scanner.unread();
46                                 return false;
47                         }
48                 }
49                 return true;
50         }
51
52         /*
53          * @see IRule#evaluate(ICharacterScanner)
54          * 
55          * @since 2.0
56          */
57         public IToken evaluate(ICharacterScanner scanner) {
58                 // Should be connected only on the right side
59                 scanner.unread();
60                 boolean sawSpaceBefore = Character.isWhitespace(scanner.read());
61                 if (!sawSpaceBefore && scanner.getColumn() != 0) {
62                         return Token.UNDEFINED;
63                 }
64
65                 int c = scanner.read();
66                 // Should be connected only on right side
67                 if (c != fSequence[0] || !sequenceDetected(scanner, fSequence, false)) {
68                         scanner.unread();
69                         return Token.UNDEFINED;
70                 }
71                 int readCount = fSequence.length;
72                 if (fDelimiters == null) {
73                         fDelimiters = scanner.getLegalLineDelimiters();
74                 }
75                 // Start sequence detected
76                 int delimiterFound = 0;
77                 // Is it a list item marker, or just a floating *?
78                 if (sawSpaceBefore) {
79                         boolean after = Character.isWhitespace(scanner.read());
80                         scanner.unread();
81                         if (after)
82                                 delimiterFound = 2;
83                 }
84
85                 while (delimiterFound < 2
86                                 && (c = scanner.read()) != ICharacterScanner.EOF) {
87                         readCount++;
88
89                         if (!sawSpaceBefore && c == fSequence[0]
90                                         && sequenceDetected(scanner, fSequence, false)) {
91                                 return fToken;
92                         }
93
94                         int i;
95                         for (i = 0; i < fDelimiters.length; i++) {
96                                 if (c == fDelimiters[i][0]
97                                                 && sequenceDetected(scanner, fDelimiters[i], true)) {
98                                         delimiterFound++;
99                                         break;
100                                 }
101                         }
102                         if (i == fDelimiters.length)
103                                 delimiterFound = 0;
104                         sawSpaceBefore = Character.isWhitespace(c);
105                 }
106                 // Reached ICharacterScanner.EOF
107                 for (; readCount > 0; readCount--)
108                         scanner.unread();
109                 return Token.UNDEFINED;
110         }
111         
112 }