]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/winterwell.markdown/src/winterwell/markdown/editors/EmphasisRule.java
migrated to svn revision 33108
[simantics/platform.git] / bundles / winterwell.markdown / src / winterwell / markdown / editors / EmphasisRule.java
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/EmphasisRule.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/EmphasisRule.java
new file mode 100644 (file)
index 0000000..06f1420
--- /dev/null
@@ -0,0 +1,112 @@
+/**\r
+ * Copyright winterwell Mathematics Ltd.\r
+ * @author Daniel Winterstein\r
+ * 11 Jan 2007\r
+ */\r
+package winterwell.markdown.editors;\r
+\r
+import org.eclipse.core.runtime.Assert;\r
+import org.eclipse.jface.text.rules.ICharacterScanner;\r
+import org.eclipse.jface.text.rules.IRule;\r
+import org.eclipse.jface.text.rules.IToken;\r
+import org.eclipse.jface.text.rules.MultiLineRule;\r
+import org.eclipse.jface.text.rules.Token;\r
+\r
+/**\r
+ * \r
+ *\r
+ * @author Daniel Winterstein\r
+ */\r
+public class EmphasisRule implements IRule {\r
+       private static char[][] fDelimiters = null;\r
+       private char[] fSequence;\r
+       protected IToken fToken;\r
+\r
+\r
+       public EmphasisRule(String marker, IToken token) {\r
+               assert marker.equals("*") || marker.equals("_") || marker.equals("**")\r
+                               || marker.equals("***") || marker.equals("`") || marker.equals("``");\r
+               Assert.isNotNull(token);\r
+               fSequence = marker.toCharArray();\r
+               fToken = token;\r
+       }\r
+       \r
+       // Copied from org.eclipse.jface.text.rules.PatternRule\r
+       protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) {\r
+               for (int i = 1; i < sequence.length; i++) {\r
+                       int c = scanner.read();\r
+                       if (c == ICharacterScanner.EOF && eofAllowed) {\r
+                               return true;\r
+                       } else if (c != sequence[i]) {\r
+                               // Non-matching character detected, rewind the scanner back to\r
+                               // the start.\r
+                               // Do not unread the first character.\r
+                               for (int j = i; j > 0; j--)\r
+                                       scanner.unread();\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /*\r
+        * @see IRule#evaluate(ICharacterScanner)\r
+        * \r
+        * @since 2.0\r
+        */\r
+       public IToken evaluate(ICharacterScanner scanner) {\r
+               // Should be connected only on the right side\r
+               scanner.unread();\r
+               boolean sawSpaceBefore = Character.isWhitespace(scanner.read());\r
+               if (!sawSpaceBefore && scanner.getColumn() != 0) {\r
+                       return Token.UNDEFINED;\r
+               }\r
+\r
+               int c = scanner.read();\r
+               // Should be connected only on right side\r
+               if (c != fSequence[0] || !sequenceDetected(scanner, fSequence, false)) {\r
+                       scanner.unread();\r
+                       return Token.UNDEFINED;\r
+               }\r
+               int readCount = fSequence.length;\r
+               if (fDelimiters == null) {\r
+                       fDelimiters = scanner.getLegalLineDelimiters();\r
+               }\r
+               // Start sequence detected\r
+               int delimiterFound = 0;\r
+               // Is it a list item marker, or just a floating *?\r
+               if (sawSpaceBefore) {\r
+                       boolean after = Character.isWhitespace(scanner.read());\r
+                       scanner.unread();\r
+                       if (after)\r
+                               delimiterFound = 2;\r
+               }\r
+\r
+               while (delimiterFound < 2\r
+                               && (c = scanner.read()) != ICharacterScanner.EOF) {\r
+                       readCount++;\r
+\r
+                       if (!sawSpaceBefore && c == fSequence[0]\r
+                                       && sequenceDetected(scanner, fSequence, false)) {\r
+                               return fToken;\r
+                       }\r
+\r
+                       int i;\r
+                       for (i = 0; i < fDelimiters.length; i++) {\r
+                               if (c == fDelimiters[i][0]\r
+                                               && sequenceDetected(scanner, fDelimiters[i], true)) {\r
+                                       delimiterFound++;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if (i == fDelimiters.length)\r
+                               delimiterFound = 0;\r
+                       sawSpaceBefore = Character.isWhitespace(c);\r
+               }\r
+               // Reached ICharacterScanner.EOF\r
+               for (; readCount > 0; readCount--)\r
+                       scanner.unread();\r
+               return Token.UNDEFINED;\r
+       }\r
+       \r
+}\r