You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ha...@apache.org on 2022/01/16 21:49:40 UTC
[royale-asjs] branch feature/markdown updated: Filled in rules
This is an automated email from the ASF dual-hosted git repository.
harbs pushed a commit to branch feature/markdown
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
The following commit(s) were added to refs/heads/feature/markdown by this push:
new ea54f6f Filled in rules
ea54f6f is described below
commit ea54f6fc6d6d598888c4c945af97c2e1619757eb
Author: Harbs <ha...@in-tools.com>
AuthorDate: Sun Jan 16 23:49:28 2022 +0200
Filled in rules
---
.../org/apache/royale/markdown/BlockParser.as | 80 +
.../org/apache/royale/markdown/BlockState.as | 182 +-
.../org/apache/royale/markdown/BlockToken.as | 55 +-
.../org/apache/royale/markdown/ContentToken.as | 38 +-
.../org/apache/royale/markdown/CoreParser.as | 13 +-
.../royale/org/apache/royale/markdown/CoreState.as | 42 +
.../org/apache/royale/markdown/Environment.as | 5 +
.../royale/org/apache/royale/markdown/IState.as | 8 +-
.../royale/org/apache/royale/markdown/IToken.as | 12 +
.../org/apache/royale/markdown/InlineParser.as | 59 +
.../org/apache/royale/markdown/InlineState.as | 92 +-
.../markdown/{CoreParser.as => LinkToken.as} | 19 +-
.../block/BlockQuote.as => MarkdownOptions.as} | 35 +-
.../org/apache/royale/markdown/MarkdownParser.as | 20 +-
.../royale/org/apache/royale/markdown/TagToken.as | 37 +-
.../royale/markdown/{BlockToken.as => Token.as} | 110 +-
.../helpers/{normalizeReference.as => HRef.as} | 11 +-
.../apache/royale/markdown/helpers/decodeEntity.as | 1769 ++++++++++++++++++++
.../royale/markdown/helpers/normalizeReference.as | 6 +
.../markdown/helpers/parseLinkDestination.as | 102 ++
.../royale/markdown/helpers/parseLinkLabel.as | 76 +
.../{normalizeReference.as => parseLinkTitle.as} | 39 +-
.../{normalizeReference.as => unescapeMd.as} | 17 +-
...normalizeReference.as => wrappedInParagraph.as} | 21 +-
.../apache/royale/markdown/rules/RulesManager.as | 121 +-
.../royale/markdown/rules/block/BlockQuote.as | 148 +-
.../org/apache/royale/markdown/rules/block/Code.as | 42 +-
.../apache/royale/markdown/rules/block/Deflist.as | 254 ++-
.../apache/royale/markdown/rules/block/Fences.as | 102 +-
.../apache/royale/markdown/rules/block/Footnote.as | 75 +-
.../apache/royale/markdown/rules/block/Heading.as | 76 +-
.../org/apache/royale/markdown/rules/block/Hr.as | 52 +-
.../royale/markdown/rules/block/Htmlblock.as | 135 +-
.../apache/royale/markdown/rules/block/Lheading.as | 72 +-
.../org/apache/royale/markdown/rules/block/List.as | 264 ++-
.../royale/markdown/rules/block/Paragraph.as | 77 +-
.../apache/royale/markdown/rules/block/Table.as | 209 ++-
.../org/apache/royale/markdown/rules/core/Abbr.as | 72 +-
.../org/apache/royale/markdown/rules/core/Abbr2.as | 90 +-
.../org/apache/royale/markdown/rules/core/Block.as | 14 +-
.../royale/markdown/rules/core/Footnote_tail.as | 86 +-
.../apache/royale/markdown/rules/core/Inline.as | 19 +-
.../royale/markdown/rules/core/References.as | 105 +-
.../royale/markdown/rules/core/Replacements.as | 72 +-
.../royale/markdown/rules/core/Smartquotes.as | 141 +-
.../royale/markdown/rules/inline/Autolink.as | 100 +-
.../royale/markdown/rules/inline/Backticks.as | 57 +-
.../org/apache/royale/markdown/rules/inline/Del.as | 92 +-
.../royale/markdown/rules/inline/Emphasis.as | 166 +-
.../apache/royale/markdown/rules/inline/Entity.as | 77 +-
.../apache/royale/markdown/rules/inline/Escape.as | 58 +-
.../royale/markdown/rules/inline/FootnoteRef.as | 62 +-
.../apache/royale/markdown/rules/inline/Htmltag.as | 143 +-
.../royale/markdown/rules/inline/InlineFootnote.as | 59 +-
.../org/apache/royale/markdown/rules/inline/Ins.as | 95 +-
.../apache/royale/markdown/rules/inline/Links.as | 187 ++-
.../apache/royale/markdown/rules/inline/Mark.as | 92 +-
.../apache/royale/markdown/rules/inline/Newline.as | 66 +-
.../org/apache/royale/markdown/rules/inline/Sub.as | 65 +-
.../org/apache/royale/markdown/rules/inline/Sup.as | 60 +-
.../apache/royale/markdown/rules/inline/Text.as | 58 +-
61 files changed, 6169 insertions(+), 342 deletions(-)
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockParser.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockParser.as
index 81cd6b6..7c45b63 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockParser.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockParser.as
@@ -22,7 +22,87 @@ package org.apache.royale.markdown
{
public function BlockParser()
{
+ }
+
+ public var rules:RulesManager;
+
+ public function tokenize (state:BlockState, startLine:int, endLine:int):void {
+ var line:int = startLine;
+ var hasEmptyLines:Boolean = false;
+
+ while (line < endLine) {
+ state.line = line = state.skipEmptyLines(line);
+ if (line >= endLine) {
+ break;
+ }
+
+ // Termination condition for nested calls.
+ // Nested calls currently used for blockquotes & lists
+ if (state.tShift[line] < state.blkIndent) {
+ break;
+ }
+
+ // do we care?
+ var success:Boolean = rules.runBlockRules(state,false,line,endLine);
+
+ // set state.tight if we had an empty line before current tag
+ // i.e. latest empty line should not count
+ state.tight = !hasEmptyLines;
+
+ // paragraph might "eat" one newline after it in nested lists
+ if (state.isEmpty(state.line - 1)) {
+ hasEmptyLines = true;
+ }
+
+ line = state.line;
+
+ if (line < endLine && state.isEmpty(line)) {
+ hasEmptyLines = true;
+ line++;
+
+ // two empty lines should stop the parser in list mode
+ if (line < endLine && state.parentType === 'list' && state.isEmpty(line)) { break; }
+ state.line = line;
+ }
+ }
+ }
+
+ private var TABS_SCAN_RE:RegExp = /[\n\t]/g;
+ private var NEWLINES_RE:RegExp = /\r[\n\u0085]|[\u2424\u2028\u0085]/g;
+ private var SPACES_RE:RegExp = /\u00a0/g;
+
+ public function parse(str:String, options:MarkdownOptions, env:Environment, outTokens:Vector.<IToken>):void {
+ // var state,
+ var lineStart:int = 0
+ var lastTabPos:int = 0;
+ if (!str) { return; }
+
+ // Normalize spaces
+ str = str.replace(SPACES_RE, ' ');
+
+ // Normalize newlines
+ str = str.replace(NEWLINES_RE, '\n');
+
+ // Replace tabs with proper number of spaces (1..4)
+ if (str.indexOf('\t') >= 0) {
+ str = str.replace(TABS_SCAN_RE, function (match:String, offset:int):String{
+ var result:String;
+ if (str.charCodeAt(offset) === 0x0A) {
+ lineStart = offset + 1;
+ lastTabPos = 0;
+ return match;
+ }
+ result = ' '.slice((offset - lineStart - lastTabPos) % 4);
+ lastTabPos = offset - lineStart + 1;
+ return result;
+ });
+ }
+
+ rules = env.rules;
+ var state:BlockState = new BlockState(str, this, options, env, outTokens);
+ this.tokenize(state, state.line, state.lineMax);
}
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockState.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockState.as
index 791cffe..dbdb689 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockState.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockState.as
@@ -20,9 +20,189 @@ package org.apache.royale.markdown
{
public class BlockState implements IState
{
- public function BlockState()
+ public function BlockState(str:String, parser:BlockParser, options:MarkdownOptions, env:Environment, tokens:Vector.<IToken>)
{
+ this.src = src;
+
+ // Shortcuts to simplify nested calls
+ this.parser = parser;
+
+ this.options = options;
+
+ this.env = env;
+
+ this.tokens = tokens;
+
+ bMarks = []; // line begin offsets for fast jumps
+ eMarks = []; // line end offsets for fast jumps
+ tShift = []; // indent for each line
+
+ // Create caches
+ // Generate markers.
+ var s:String = this.src;
+ var indent:int = 0;
+ var indentFound:Boolean = false;
+ var start:int,pos:int,len:int;
+ for (start = pos = indent = 0, len = s.length; pos < len; pos++) {
+ var ch:Number = s.charCodeAt(pos);
+
+ if (!indentFound) {
+ if (ch === 0x20/* space */) {
+ indent++;
+ continue;
+ } else {
+ indentFound = true;
+ }
+ }
+
+ if (ch === 0x0A || pos === len - 1) {
+ if (ch !== 0x0A) { pos++; }
+ this.bMarks.push(start);
+ this.eMarks.push(pos);
+ this.tShift.push(indent);
+
+ indentFound = false;
+ indent = 0;
+ start = pos + 1;
+ }
+ }
+
+ // Push fake entry to simplify cache bounds checks
+ this.bMarks.push(s.length);
+ this.eMarks.push(s.length);
+ this.tShift.push(0);
+
+ this.lineMax = this.bMarks.length - 1; // don't count last fake line
+
+ }
+
+ public var src:String;
+ public var parser:BlockParser;
+ private var _options:MarkdownOptions;
+
+ public function get options():MarkdownOptions
+ {
+ return _options;
+ }
+
+ public function set options(value:MarkdownOptions):void
+ {
+ _options = value;
+ }
+ public var env:Environment;
+
+ public var bMarks:Array;
+ public var eMarks:Array;
+ public var tShift:Array;
+ /**
+ * required block content indent (for example, if we are in list)
+ */
+ public var blkIndent:int = 0;
+
+ public var line:int = 0; // line index in src
+ public var lineMax:int = 0; // lines count
+ public var tight:Boolean = false; // loose/tight mode for lists
+ public var parentType:String = 'root'; // if `list`, block parser stops on two newlines
+ public var ddIndent:int = -1; // indent of the current dd block (-1 if there isn't any)
+ public var level:int = 0;
+ /**
+ * renderer var do we need?
+ */
+ private var result:String = '';
+ private var _tokens:Vector.<IToken>;
+
+ public function get tokens():Vector.<IToken>
+ {
+ return _tokens;
+ }
+
+ public function set tokens(value:Vector.<IToken>):void
+ {
+ _tokens = value;
+ }
+
+ public function isEmpty(line:int):Boolean {
+ return this.bMarks[line] + this.tShift[line] >= this.eMarks[line];
+ }
+
+ public function skipEmptyLines(from:int):int {
+ for (var max:int = lineMax; from < max; from++) {
+ if (bMarks[from] + tShift[from] < eMarks[from]) {
+ break;
+ }
+ }
+ return from;
+ }
+
+ // Skip spaces from given position.
+ public function skipSpaces(pos:int):int {
+ for (var max:int = this.src.length; pos < max; pos++) {
+ if (this.src.charCodeAt(pos) !== 0x20/* space */) { break; }
+ }
+ return pos;
+ }
+
+ // Skip char codes from given position
+ public function skipChars(pos:int, code:Number):int {
+ for (var max:int = src.length; pos < max; pos++) {
+ if (src.charCodeAt(pos) !== code) { break; }
+ }
+ return pos;
+ }
+
+ // Skip char codes reverse from given position - 1
+ public function skipCharsBack(pos:int, code:Number, min:int):int {
+ if (pos <= min) { return pos; }
+
+ while (pos > min) {
+ if (code !== src.charCodeAt(--pos)) { return pos + 1; }
+ }
+ return pos;
+ }
+
+ // cut lines range from source.
+ public function getLines(begin:int, end:int, indent:Number, keepLastLF:Boolean):String {
+ var i:int
+ var first:Number
+ var last:Number;
+ var queue:Array
+ var shift:Number;
+
+ line = begin;
+
+ if (begin >= end) {
+ return '';
+ }
+
+ // Opt: don't use push queue for single line;
+ if (line + 1 === end) {
+ first = this.bMarks[line] + Math.min(this.tShift[line], indent);
+ last = keepLastLF ? this.eMarks[line] + 1 : this.eMarks[line];
+ return this.src.slice(first, last);
+ }
+
+ queue = new Array(end - begin);
+
+ for (i = 0; line < end; line++, i++) {
+ shift = this.tShift[line];
+ if (shift > indent) { shift = indent; }
+ if (shift < 0) { shift = 0; }
+
+ first = this.bMarks[line] + shift;
+
+ if (line + 1 < end || keepLastLF) {
+ // No need for bounds check because we have fake entry on tail.
+ last = this.eMarks[line] + 1;
+ } else {
+ last = this.eMarks[line];
+ }
+
+ queue[i] = this.src.slice(first, last);
+ }
+
+ return queue.join('');
}
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockToken.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockToken.as
index e44e7da..46cc7c5 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockToken.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockToken.as
@@ -19,11 +19,14 @@
package org.apache.royale.markdown
{
- public class BlockToken implements IToken
+ public class BlockToken extends ContentToken
{
- public function BlockToken()
+ public function BlockToken(type:String,content:String)
{
+ super(type,content);
+
lineData = [-1,-1];
+ children = new Vector.<IToken>();
}
private var lineData:Array;
@@ -47,53 +50,7 @@ package org.apache.royale.markdown
lineData[1] = value;
}
- public var children:Array;
-
- private var _content:String;
- /**
- * The raw text content
- * @langversion 3.0
- * @productversion Royale 0.9.9
- */
- public function get content():String
- {
- return _content;
- }
-
- public function set content(value:String):void
- {
- _content = value;
- }
- private var _type:String = "";
- /**
- * The token type
- * @langversion 3.0
- * @productversion Royale 0.9.9
- */
- public function get type():String
- {
- return _type;
- }
+ public var children:Vector.<IToken>;
- public function set type(value:String):void
- {
- _type = value;
- }
-
- private var _level:int = 0;
- /**
- * The level of nesting of the token
- * @langversion 3.0
- * @productversion Royale 0.9.9
- */
- public function get level():int
- {
- return _level;
- }
-
- public function set level(value:int):void
- {
- _level = value;
- }
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/ContentToken.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/ContentToken.as
index 9ff76cf..880f475 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/ContentToken.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/ContentToken.as
@@ -28,11 +28,13 @@ package org.apache.royale.markdown
* @langversion 3.0
* @productversion Royale 0.9.9
*/
- public class ContentToken implements IToken
+ public class ContentToken extends Token
{
- public function ContentToken()
+ public function ContentToken(type:String,content:String,level:int=0)
{
-
+ super(type);
+ _content = content;
+ this.level = level;
}
private var _content:String = "";
@@ -50,36 +52,6 @@ package org.apache.royale.markdown
{
_content = value;
}
- private var _type:String = "";
- /**
- * The token type
- * @langversion 3.0
- * @productversion Royale 0.9.9
- */
- public function get type():String
- {
- return _type;
- }
-
- public function set type(value:String):void
- {
- _type = value;
- }
- private var _level:int = 0;
- /**
- * The level of nesting of the token
- * @langversion 3.0
- * @productversion Royale 0.9.9
- */
- public function get level():int
- {
- return _level;
- }
-
- public function set level(value:int):void
- {
- _level = value;
- }
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreParser.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreParser.as
index 5a91384..6592949 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreParser.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreParser.as
@@ -22,12 +22,15 @@ package org.apache.royale.markdown
{
public function CoreParser()
{
- // rulesManager = new RulesManager();
}
-
- // private var rulesManager:RulesManager;
- public function process(state:CoreState):void{
-
+ /**
+ * Delegates processing to the core rules
+ *
+ * The rules then call the block and inline parsers
+ */
+ public function process(state:CoreState):void
+ {
+ state.rules.runCoreRules(state);
}
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreState.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreState.as
index cbe86af..cd7e9df 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreState.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreState.as
@@ -22,7 +22,49 @@ package org.apache.royale.markdown
{
public function CoreState(parser:MarkdownParser,str:String,env:Environment)
{
+ this.src = str;
+ this.env = env;
+ this.options = parser.options;
+ tokens = new Vector.<IToken>();
+ this.inlineMode = false;
+
+ inlineParser = parser.inlineParser;
+ blockParser = parser.blockParser;
+ // this.renderer = parser.renderer;
+ // this.typographer = parser.typographer;
+ rules = parser.rulesManager;
}
+ private var _tokens:Vector.<IToken>;
+
+ public function get tokens():Vector.<IToken>
+ {
+ return _tokens;
+ }
+
+ public function set tokens(value:Vector.<IToken>):void
+ {
+ _tokens = value;
+ }
+ public var inlineParser:InlineParser;
+ public var blockParser:BlockParser;
+ public var rules:RulesManager;
+
+ private var _options:MarkdownOptions;
+
+ public function get options():MarkdownOptions
+ {
+ return _options;
+ }
+
+ public function set options(value:MarkdownOptions):void
+ {
+ _options = value;
+ }
+ public var inlineMode:Boolean;
+
+ public var src:String;
+ public var env:Environment;
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/Environment.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/Environment.as
index 3b86205..ded9ec1 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/Environment.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/Environment.as
@@ -24,5 +24,10 @@ package org.apache.royale.markdown
{
}
+ public var rules:RulesManager;
+ public var abbreviations:Object;
+ public var references:Object;
+ public var footnotes:Object;
+ public var abbrRegExp:RegExp;
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/IState.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/IState.as
index 34960bd..e5eaf6f 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/IState.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/IState.as
@@ -19,7 +19,11 @@
package org.apache.royale.markdown
{
public interface IState
- {
-
+ {
+ function get tokens():Vector.<IToken>;
+ function set tokens(value:Vector.<IToken>):void;
+ function get options():MarkdownOptions;
+ function set options(value:MarkdownOptions):void;
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/IToken.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/IToken.as
index b360004..38faba0 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/IToken.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/IToken.as
@@ -22,7 +22,19 @@ package org.apache.royale.markdown
{
function get type():String;
function set type(value:String):void;
+ function get data():String;
+ function set data(value:String):void;
+ function get title():String;
+ function set title(value:String):void;
function get level():int;
function set level(value:int):void;
+ function get id():int;
+ function set id(value:int):void;
+ function get subId():int;
+ function set subId(value:int):void;
+ function get tight():Boolean;
+ function set tight(value:Boolean):void;
+ function get numValue():Number;
+ function set numValue(value:Number):void;
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/InlineParser.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/InlineParser.as
index 80f59b4..0c37dc0 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/InlineParser.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/InlineParser.as
@@ -24,5 +24,64 @@ package org.apache.royale.markdown
{
}
+
+ public var rules:RulesManager;
+
+ /**
+ * Skip a single token by running all rules in validation mode.
+ *
+ */
+ public function skipToken (state:InlineState):void
+ {
+ var pos:int = state.position;
+ var cachedPos:int = state.cacheGet(pos);
+ if (cachedPos > 0) {
+ state.position = cachedPos;
+ return;
+ }
+ // when on silent, the cache is set if a rule is found
+ if(rules.runInlineRules(state,true,pos))
+ return;
+
+ state.position++;
+ state.cacheSet(pos, state.position);
+ }
+
+ /**
+ * Generate tokens for the given input range.
+ *
+ */
+
+ public function tokenize (state:InlineState):void{
+ var end:int = state.posMax;
+
+ while (state.position < end) {
+
+ // run all the rules.
+ var success:Boolean = rules.runInlineRules(state,true,0);
+ if (success) {
+ if (state.position >= end) { break; }
+ continue;
+ }
+
+ state.pending += state.src[state.position++];
+ }
+
+ if (state.pending) {
+ state.pushPending();
+ }
+ }
+
+ /**
+ * Parse the given input string.
+ *
+ */
+
+ public function parse (str:String, options:MarkdownOptions, env:Environment, tokens:Vector.<IToken>):void{
+ rules = env.rules;
+ var state:InlineState = new InlineState(str, this, options, env, tokens);
+ this.tokenize(state);
+ }
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/InlineState.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/InlineState.as
index 7600a18..f380640 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/InlineState.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/InlineState.as
@@ -20,9 +20,97 @@ package org.apache.royale.markdown
{
public class InlineState implements IState
{
- public function InlineState()
+ // str, this, options, env, outTokens
+ public function InlineState(src:String, parser:InlineParser, options:MarkdownOptions, env:Environment, tokens:Vector.<IToken>)
{
-
+
+ src = src;
+ env = env;
+ this.options = options;
+ this.parser = parser;
+ this.tokens = tokens;
+ posMax = src.length;
+ // Stores { start: end } pairs. Useful for backtrack
+ // optimization of pairs parse (emphasis, strikes).
+ cache = new Vector.<int>();
}
+
+ public var src:String;
+ public var env:Environment;
+ private var _options:MarkdownOptions;
+
+ public function get options():MarkdownOptions
+ {
+ return _options;
+ }
+
+ public function set options(value:MarkdownOptions):void
+ {
+ _options = value;
+ }
+ public var parser:InlineParser;
+ private var _tokens:Vector.<IToken>;
+
+ public function get tokens():Vector.<IToken>
+ {
+ return _tokens;
+ }
+
+ public function set tokens(value:Vector.<IToken>):void
+ {
+ _tokens = value;
+ }
+ public var position:int = 0;
+ public var posMax:int;
+ public var level:int = 0;
+ public var pending:String = "";
+ public var pendingLevel:int = 0;
+ public var cache:Vector.<int>;
+
+ /**
+ * Set true when seek link label - we should disable "paired" rules
+ * (emphasis, strikes) to not skip tailing `]`
+ */
+ public var isInLabel:Boolean = false;
+ public var linkLevel:int = 0;// Increment for each nesting link. Used to prevent nesting in definitions
+ public var linkContent:String = ""; // Temporary storage for link url
+ public var labelUnmatchedScopes:int = 0;// Track unpaired `[` for link labels (backtrack optimization)
+
+ // Flush pending text
+ //
+ public function pushPending():void{
+ var token:ContentToken = new ContentToken("text",pending);
+ token.level = pendingLevel;
+ tokens.push(token);
+ pending = '';
+ }
+
+ // Push new token to "stream".
+ // If pending text exists - flush it as text token
+ //
+ public function push(token:IToken):void{
+ if (this.pending) {
+ this.pushPending();
+ }
+
+ this.tokens.push(token);
+ this.pendingLevel = this.level;
+ }
+
+ // Store value to cache.
+ public function cacheSet(key:int, val:int):void{
+ for (var i:int = this.cache.length; i <= key; i++) {
+ this.cache.push(0);
+ }
+
+ this.cache[key] = val;
+ }
+
+ // Get cache value
+ //
+ public function cacheGet(key:int):int {
+ return key < this.cache.length ? this.cache[key] : 0;
+ }
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreParser.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/LinkToken.as
similarity index 75%
copy from frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreParser.as
copy to frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/LinkToken.as
index 5a91384..6af07af 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/CoreParser.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/LinkToken.as
@@ -18,16 +18,21 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
- public class CoreParser implements IParser
+ /**
+ * LinkTokens are for links and images
+ *
+ * A text token has a `content` property containing the text it represents.
+ * @langversion 3.0
+ * @productversion Royale 0.9.9
+ */
+ public class LinkToken extends ContentToken
{
- public function CoreParser()
+ public function LinkToken(type:String,level:int=0)
{
- // rulesManager = new RulesManager();
+ super(type,'',level);
}
- // private var rulesManager:RulesManager;
- public function process(state:CoreState):void{
-
- }
+ public var href:String;
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/BlockQuote.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/MarkdownOptions.as
similarity index 61%
copy from frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/BlockQuote.as
copy to frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/MarkdownOptions.as
index c497158..e0dfe2c 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/BlockQuote.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/MarkdownOptions.as
@@ -18,32 +18,23 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
- public class BlockQuote extends Rule
+ /**
+ * Holds optional customizations for rendering the markdown
+ */
+ public class MarkdownOptions
{
- private function BlockQuote()
+ public function MarkdownOptions()
{
}
-
- private static var _instance:BlockQuote;
- public static function get():BlockQuote
- {
- if(!_instance)
- _instance = new BlockQuote();
-
- return _instance;
- }
-
- /**
- * parses the rule
- * @langversion 3.0
- * @productversion Royale 0.9.9 *
- */
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
- {
- throw new Error("Method not implemented.");
- }
-
+ public var maxNesting:int = 20;
+ public var typographer:Boolean = false;
+ public var quotes:String = '“”‘’';
+ public var html:Boolean = false; // Enable HTML tags in source
+ public var xhtmlOut:Boolean = false; // Use '/' to close single tags (<br />)
+ public var breaks:Boolean = false; // Convert '\n' in paragraphs into <br>
+ public var langPrefix:String = 'language-'; // CSS language prefix for fenced blocks
+ public var linkTarget:String = ''; // set target to open link in
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/MarkdownParser.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/MarkdownParser.as
index ea3882e..bbd68c3 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/MarkdownParser.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/MarkdownParser.as
@@ -28,15 +28,25 @@ package org.apache.royale.markdown
{
inlineParser = new InlineParser();
blockParser = new BlockParser();
- coreParser = new CoreParser();
+ coreParser = new CoreParser();
+ rulesManager = new RulesManager();
+
}
- private var inlineParser:InlineParser;
- private var blockParser:BlockParser;
- private var coreParser:CoreParser;
+ public var inlineParser:InlineParser;
+ public var blockParser:BlockParser;
+ public var coreParser:CoreParser;
+ public var rulesManager:RulesManager;
+
+ public var options:MarkdownOptions;
+
+ public function parse (str:String, env:Environment=null):void {
+ if(!env)
+ env = new Environment();
- public function parse (str:String, env:Environment):void {
+ env.rules = rulesManager;
var state:CoreState = new CoreState(this, str, env);
+ state.options = rulesManager.options;
coreParser.process(state);
// return state.tokens;
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/TagToken.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/TagToken.as
index 175e788..75e21ac 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/TagToken.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/TagToken.as
@@ -28,7 +28,7 @@ package org.apache.royale.markdown
* Tag tokens have a variety of types and each is associated to a rendering rule.
*
*/
- public class TagToken implements IToken
+ public class TagToken extends Token
{
/**
@@ -70,44 +70,15 @@ package org.apache.royale.markdown
* dd (open/close)
*
*/
- public function TagToken()
+ public function TagToken(type:String,level:int=0)
{
-
+ super(type);
+ this.level = level;
}
public var openTag:Boolean;
public var closeTag:Boolean;
- private var _type:String = "";
- /**
- * The token type
- * @langversion 3.0
- * @productversion Royale 0.9.9
- */
- public function get type():String
- {
- return _type;
- }
-
- public function set type(value:String):void
- {
- _type = value;
- }
- private var _level:int = 0;
- /**
- * The level of nesting of the token
- * @langversion 3.0
- * @productversion Royale 0.9.9
- */
- public function get level():int
- {
- return _level;
- }
-
- public function set level(value:int):void
- {
- _level = value;
- }
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockToken.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/Token.as
similarity index 60%
copy from frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockToken.as
copy to frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/Token.as
index e44e7da..fed370b 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/BlockToken.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/Token.as
@@ -18,66 +18,51 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
-
- public class BlockToken implements IToken
+ public abstract class Token implements IToken
{
- public function BlockToken()
+ public function Token(type:String)
{
- lineData = [-1,-1];
+ this.type = type;
}
- private var lineData:Array;
- public function get firstLine():int
+ private var _type:String = "";
+ /**
+ * The token type
+ * @langversion 3.0
+ * @productversion Royale 0.9.9
+ */
+ public function get type():String
{
- return lineData[0] as int;
+ return _type;
}
- public function set firstLine(value:int):void
+ public function set type(value:String):void
{
- lineData[0] = value;
+ _type = value;
}
- public function get lastLine():int
+ private var _data:String;
+
+ public function get data():String
{
- return lineData[1];
+ return _data;
}
- public function set lastLine(value:int):void
+ public function set data(value:String):void
{
- lineData[1] = value;
+ _data = value;
}
- public var children:Array;
+ private var _title:String;
- private var _content:String;
- /**
- * The raw text content
- * @langversion 3.0
- * @productversion Royale 0.9.9
- */
- public function get content():String
+ public function get title():String
{
- return _content;
+ return _title;
}
- public function set content(value:String):void
- {
- _content = value;
- }
- private var _type:String = "";
- /**
- * The token type
- * @langversion 3.0
- * @productversion Royale 0.9.9
- */
- public function get type():String
+ public function set title(value:String):void
{
- return _type;
- }
-
- public function set type(value:String):void
- {
- _type = value;
+ _title = value;
}
private var _level:int = 0;
@@ -95,5 +80,52 @@ package org.apache.royale.markdown
{
_level = value;
}
+
+ private var _tight:Boolean = false;
+
+ public function get tight():Boolean
+ {
+ return _tight;
+ }
+
+ public function set tight(value:Boolean):void
+ {
+ _tight = value;
+ }
+
+ private var _id:int;
+
+ public function get id():int
+ {
+ return _id;
+ }
+
+ public function set id(value:int):void
+ {
+ _id = value;
+ }
+
+ private var _subId:int;
+
+ public function get subId():int
+ {
+ return _subId;
+ }
+
+ public function set subId(value:int):void
+ {
+ _subId = value;
+ }
+ private var _numValue:Number;
+
+ public function get numValue():Number
+ {
+ return _numValue;
+ }
+
+ public function set numValue(value:Number):void
+ {
+ _numValue = value;
+ }
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/HRef.as
similarity index 85%
copy from frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
copy to frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/HRef.as
index 7b3d16e..0abfcef 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/HRef.as
@@ -18,8 +18,15 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown.helpers
{
- public function normalizeReference(str:String):String
+ public class HRef
{
- return str.trim().replace(/\s+/g, ' ').toUpperCase();
+ public function HRef(href:String,title:String)
+ {
+ this.href = href;
+ this.title = title;
+ }
+ public var title:String;
+ public var href:String;
}
+
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/decodeEntity.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/decodeEntity.as
new file mode 100644
index 0000000..e9845a6
--- /dev/null
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/decodeEntity.as
@@ -0,0 +1,1769 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package
+{
+ /**
+ *
+ * @langversion 3.0
+ * @productversion Royale 0.9.9
+ * @royalesuppressexport
+ */
+ public function decodeEntity(name:String):String
+ {
+ var entity:String = entities[name];
+ return entity == null ? name : entity;
+ }
+
+}
+internal var entities:Object = {
+ "Aacute":"\u00C1","aacute":"\u00E1","Abreve":"\u0102","abreve":"\u0103","ac":"\u223E","acd":"\u223F",
+ "acE":"\u223E\u0333","Acirc":"\u00C2","acirc":"\u00E2","acute":"\u00B4","Acy":"\u0410","acy":"\u0430",
+ "AElig":"\u00C6","aelig":"\u00E6","af":"\u2061","Afr":"\uD835\uDD04","afr":"\uD835\uDD1E","Agrave":"\u00C0",
+ "agrave":"\u00E0","alefsym":"\u2135","aleph":"\u2135","Alpha":"\u0391","alpha":"\u03B1","Amacr":"\u0100","amacr":"\u0101",
+ "amalg":"\u2A3F","AMP":"\u0026","amp":"\u0026","And":"\u2A53","and":"\u2227","andand":"\u2A55","andd":"\u2A5C",
+ "andslope":"\u2A58","andv":"\u2A5A","ang":"\u2220","ange":"\u29A4","angle":"\u2220","angmsd":"\u2221","angmsdaa":"\u29A8",
+ "angmsdab":"\u29A9","angmsdac":"\u29AA","angmsdad":"\u29AB","angmsdae":"\u29AC","angmsdaf":"\u29AD","angmsdag":"\u29AE","angmsdah":"\u29AF",
+ "angrt":"\u221F","angrtvb":"\u22BE","angrtvbd":"\u299D","angsph":"\u2222","angst":"\u00C5","angzarr":"\u237C",
+ "Aogon":"\u0104","aogon":"\u0105","Aopf":"\uD835\uDD38","aopf":"\uD835\uDD52","ap":"\u2248","apacir":"\u2A6F",
+ "apE":"\u2A70","ape":"\u224A","apid":"\u224B","apos":"\u0027","ApplyFunction":"\u2061","approx":"\u2248",
+ "approxeq":"\u224A","Aring":"\u00C5","aring":"\u00E5","Ascr":"\uD835\uDC9C","ascr":"\uD835\uDCB6","Assign":"\u2254",
+ "ast":"\u002A","asymp":"\u2248","asympeq":"\u224D","Atilde":"\u00C3","atilde":"\u00E3","Auml":"\u00C4",
+ "auml":"\u00E4","awconint":"\u2233","awint":"\u2A11","backcong":"\u224C","backepsilon":"\u03F6","backprime":"\u2035",
+ "backsim":"\u223D","backsimeq":"\u22CD","Backslash":"\u2216","Barv":"\u2AE7","barvee":"\u22BD","Barwed":"\u2306",
+ "barwed":"\u2305","barwedge":"\u2305","bbrk":"\u23B5","bbrktbrk":"\u23B6","bcong":"\u224C","Bcy":"\u0411","bcy":"\u0431",
+ "bdquo":"\u201E","becaus":"\u2235","Because":"\u2235","because":"\u2235","bemptyv":"\u29B0","bepsi":"\u03F6","bernou":"\u212C",
+ "Bernoullis":"\u212C","Beta":"\u0392","beta":"\u03B2","beth":"\u2136","between":"\u226C","Bfr":"\uD835\uDD05","bfr":"\uD835\uDD1F",
+ "bigcap":"\u22C2","bigcirc":"\u25EF","bigcup":"\u22C3","bigodot":"\u2A00","bigoplus":"\u2A01","bigotimes":"\u2A02","bigsqcup":"\u2A06",
+ "bigstar":"\u2605","bigtriangledown":"\u25BD","bigtriangleup":"\u25B3","biguplus":"\u2A04","bigvee":"\u22C1","bigwedge":"\u22C0","bkarow":"\u290D",
+ "blacklozenge":"\u29EB","blacksquare":"\u25AA","blacktriangle":"\u25B4","blacktriangledown":"\u25BE","blacktriangleleft":"\u25C2",
+ "blacktriangleright":"\u25B8","blank":"\u2423","blk12":"\u2592","blk14":"\u2591","blk34":"\u2593","block":"\u2588","bne":"\u003D\u20E5",
+ "bnequiv":"\u2261\u20E5","bNot":"\u2AED","bnot":"\u2310","Bopf":"\uD835\uDD39","bopf":"\uD835\uDD53","bot":"\u22A5","bottom":"\u22A5","bowtie":"\u22C8",
+ "boxbox":"\u29C9","boxDL":"\u2557","boxDl":"\u2556","boxdL":"\u2555","boxdl":"\u2510","boxDR":"\u2554","boxDr":"\u2553",
+ "boxdR":"\u2552","boxdr":"\u250C","boxH":"\u2550","boxh":"\u2500","boxHD":"\u2566","boxHd":"\u2564","boxhD":"\u2565",
+ "boxhd":"\u252C","boxHU":"\u2569","boxHu":"\u2567","boxhU":"\u2568","boxhu":"\u2534","boxminus":"\u229F","boxplus":"\u229E",
+ "boxtimes":"\u22A0","boxUL":"\u255D","boxUl":"\u255C","boxuL":"\u255B","boxul":"\u2518","boxUR":"\u255A","boxUr":"\u2559","boxuR":"\u2558",
+ "boxur":"\u2514","boxV":"\u2551","boxv":"\u2502","boxVH":"\u256C","boxVh":"\u256B","boxvH":"\u256A","boxvh":"\u253C","boxVL":"\u2563",
+ "boxVl":"\u2562","boxvL":"\u2561","boxvl":"\u2524","boxVR":"\u2560","boxVr":"\u255F","boxvR":"\u255E","boxvr":"\u251C","bprime":"\u2035",
+ "Breve":"\u02D8","breve":"\u02D8","brvbar":"\u00A6","Bscr":"\u212C","bscr":"\uD835\uDCB7","bsemi":"\u204F","bsim":"\u223D","bsime":"\u22CD",
+ "bsol":"\u005C","bsolb":"\u29C5","bsolhsub":"\u27C8","bull":"\u2022","bullet":"\u2022","bump":"\u224E","bumpE":"\u2AAE","bumpe":"\u224F",
+ "Bumpeq":"\u224E","bumpeq":"\u224F","Cacute":"\u0106","cacute":"\u0107","Cap":"\u22D2","cap":"\u2229","capand":"\u2A44","capbrcup":"\u2A49",
+ "capcap":"\u2A4B","capcup":"\u2A47","capdot":"\u2A40","CapitalDifferentialD":"\u2145","caps":"\u2229\uFE00","caret":"\u2041","caron":"\u02C7",
+ "Cayleys":"\u212D","ccaps":"\u2A4D","Ccaron":"\u010C","ccaron":"\u010D","Ccedil":"\u00C7","ccedil":"\u00E7","Ccirc":"\u0108",
+ "ccirc":"\u0109","Cconint":"\u2230","ccups":"\u2A4C","ccupssm":"\u2A50","Cdot":"\u010A","cdot":"\u010B","cedil":"\u00B8",
+ "Cedilla":"\u00B8","cemptyv":"\u29B2","cent":"\u00A2","CenterDot":"\u00B7","centerdot":"\u00B7","Cfr":"\u212D","cfr":"\uD835\uDD20",
+ "CHcy":"\u0427","chcy":"\u0447","check":"\u2713","checkmark":"\u2713","Chi":"\u03A7","chi":"\u03C7","cir":"\u25CB",
+ "circ":"\u02C6","circeq":"\u2257","circlearrowleft":"\u21BA","circlearrowright":"\u21BB","circledast":"\u229B","circledcirc":"\u229A","circleddash":"\u229D",
+ "CircleDot":"\u2299","circledR":"\u00AE","circledS":"\u24C8","CircleMinus":"\u2296","CirclePlus":"\u2295","CircleTimes":"\u2297","cirE":"\u29C3",
+ "cire":"\u2257","cirfnint":"\u2A10","cirmid":"\u2AEF","cirscir":"\u29C2","ClockwiseContourIntegral":"\u2232","CloseCurlyDoubleQuote":"\u201D","CloseCurlyQuote":"\u2019",
+ "clubs":"\u2663","clubsuit":"\u2663","Colon":"\u2237","colon":"\u003A","Colone":"\u2A74","colone":"\u2254","coloneq":"\u2254",
+ "comma":"\u002C","commat":"\u0040","comp":"\u2201","compfn":"\u2218","complement":"\u2201","complexes":"\u2102","cong":"\u2245",
+ "congdot":"\u2A6D","Congruent":"\u2261","Conint":"\u222F","conint":"\u222E","ContourIntegral":"\u222E","Copf":"\u2102","copf":"\uD835\uDD54",
+ "coprod":"\u2210","Coproduct":"\u2210","COPY":"\u00A9","copy":"\u00A9","copysr":"\u2117","CounterClockwiseContourIntegral":"\u2233","crarr":"\u21B5",
+ "Cross":"\u2A2F","cross":"\u2717","Cscr":"\uD835\uDC9E","cscr":"\uD835\uDCB8","csub":"\u2ACF","csube":"\u2AD1","csup":"\u2AD0",
+ "csupe":"\u2AD2","ctdot":"\u22EF","cudarrl":"\u2938","cudarrr":"\u2935","cuepr":"\u22DE","cuesc":"\u22DF","cularr":"\u21B6",
+ "cularrp":"\u293D","Cup":"\u22D3","cup":"\u222A","cupbrcap":"\u2A48","CupCap":"\u224D","cupcap":"\u2A46","cupcup":"\u2A4A","cupdot":"\u228D",
+ "cupor":"\u2A45","cups":"\u222A\uFE00","curarr":"\u21B7","curarrm":"\u293C","curlyeqprec":"\u22DE","curlyeqsucc":"\u22DF","curlyvee":"\u22CE","curlywedge":"\u22CF",
+ "curren":"\u00A4","curvearrowleft":"\u21B6","curvearrowright":"\u21B7","cuvee":"\u22CE","cuwed":"\u22CF","cwconint":"\u2232",
+ "cwint":"\u2231","cylcty":"\u232D","Dagger":"\u2021","dagger":"\u2020","daleth":"\u2138","Darr":"\u21A1","dArr":"\u21D3",
+ "darr":"\u2193","dash":"\u2010","Dashv":"\u2AE4","dashv":"\u22A3","dbkarow":"\u290F","dblac":"\u02DD","Dcaron":"\u010E",
+ "dcaron":"\u010F","Dcy":"\u0414","dcy":"\u0434","DD":"\u2145","dd":"\u2146","ddagger":"\u2021",
+ "ddarr":"\u21CA","DDotrahd":"\u2911","ddotseq":"\u2A77","deg":"\u00B0","Del":"\u2207","Delta":"\u0394",
+ "delta":"\u03B4","demptyv":"\u29B1","dfisht":"\u297F","Dfr":"\uD835\uDD07","dfr":"\uD835\uDD21","dHar":"\u2965","dharl":"\u21C3",
+ "dharr":"\u21C2","DiacriticalAcute":"\u00B4","DiacriticalDot":"\u02D9","DiacriticalDoubleAcute":"\u02DD","DiacriticalGrave":"\u0060","DiacriticalTilde":"\u02DC","diam":"\u22C4",
+ "Diamond":"\u22C4","diamond":"\u22C4","diamondsuit":"\u2666","diams":"\u2666","die":"\u00A8","DifferentialD":"\u2146","digamma":"\u03DD",
+ "disin":"\u22F2","div":"\u00F7","divide":"\u00F7","divideontimes":"\u22C7","divonx":"\u22C7","DJcy":"\u0402","djcy":"\u0452",
+ "dlcorn":"\u231E","dlcrop":"\u230D","dollar":"\u0024","Dopf":"\uD835\uDD3B","dopf":"\uD835\uDD55","Dot":"\u00A8","dot":"\u02D9",
+ "DotDot":"\u20DC","doteq":"\u2250","doteqdot":"\u2251","DotEqual":"\u2250","dotminus":"\u2238","dotplus":"\u2214","dotsquare":"\u22A1",
+ "doublebarwedge":"\u2306","DoubleContourIntegral":"\u222F","DoubleDot":"\u00A8","DoubleDownArrow":"\u21D3","DoubleLeftArrow":"\u21D0","DoubleLeftRightArrow":"\u21D4",
+ "DoubleLeftTee":"\u2AE4","DoubleLongLeftArrow":"\u27F8","DoubleLongLeftRightArrow":"\u27FA","DoubleLongRightArrow":"\u27F9","DoubleRightArrow":"\u21D2",
+ "DoubleRightTee":"\u22A8","DoubleUpArrow":"\u21D1","DoubleUpDownArrow":"\u21D5","DoubleVerticalBar":"\u2225","DownArrow":"\u2193","Downarrow":"\u21D3",
+ "downarrow":"\u2193","DownArrowBar":"\u2913","DownArrowUpArrow":"\u21F5","DownBreve":"\u0311","downdownarrows":"\u21CA","downharpoonleft":"\u21C3",
+ "downharpoonright":"\u21C2","DownLeftRightVector":"\u2950","DownLeftTeeVector":"\u295E","DownLeftVector":"\u21BD","DownLeftVectorBar":"\u2956","DownRightTeeVector":"\u295F",
+ "DownRightVector":"\u21C1","DownRightVectorBar":"\u2957","DownTee":"\u22A4","DownTeeArrow":"\u21A7","drbkarow":"\u2910","drcorn":"\u231F",
+ "drcrop":"\u230C","Dscr":"\uD835\uDC9F","dscr":"\uD835\uDCB9","DScy":"\u0405","dscy":"\u0455","dsol":"\u29F6","Dstrok":"\u0110","dstrok":"\u0111","dtdot":"\u22F1",
+ "dtri":"\u25BF","dtrif":"\u25BE","duarr":"\u21F5","duhar":"\u296F","dwangle":"\u29A6","DZcy":"\u040F","dzcy":"\u045F",
+ "dzigrarr":"\u27FF","Eacute":"\u00C9","eacute":"\u00E9","easter":"\u2A6E","Ecaron":"\u011A","ecaron":"\u011B","ecir":"\u2256",
+ "Ecirc":"\u00CA",
+ "ecirc":"\u00EA",
+ "ecolon":"\u2255",
+ "Ecy":"\u042D",
+ "ecy":"\u044D",
+ "eDDot":"\u2A77",
+ "Edot":"\u0116",
+ "eDot":"\u2251",
+ "edot":"\u0117",
+ "ee":"\u2147",
+ "efDot":"\u2252",
+ "Efr":"\uD835\uDD08",
+ "efr":"\uD835\uDD22",
+ "eg":"\u2A9A",
+ "Egrave":"\u00C8",
+ "egrave":"\u00E8",
+ "egs":"\u2A96",
+ "egsdot":"\u2A98",
+ "el":"\u2A99",
+ "Element":"\u2208",
+ "elinters":"\u23E7",
+ "ell":"\u2113",
+ "els":"\u2A95",
+ "elsdot":"\u2A97",
+ "Emacr":"\u0112",
+ "emacr":"\u0113",
+ "empty":"\u2205",
+ "emptyset":"\u2205",
+ "EmptySmallSquare":"\u25FB",
+ "emptyv":"\u2205",
+ "EmptyVerySmallSquare":"\u25AB",
+ "emsp":"\u2003",
+ "emsp13":"\u2004",
+ "emsp14":"\u2005",
+ "ENG":"\u014A",
+ "eng":"\u014B",
+ "ensp":"\u2002",
+ "Eogon":"\u0118",
+ "eogon":"\u0119",
+ "Eopf":"\uD835\uDD3C",
+ "eopf":"\uD835\uDD56",
+ "epar":"\u22D5",
+ "eparsl":"\u29E3",
+ "eplus":"\u2A71",
+ "epsi":"\u03B5",
+ "Epsilon":"\u0395",
+ "epsilon":"\u03B5",
+ "epsiv":"\u03F5",
+ "eqcirc":"\u2256",
+ "eqcolon":"\u2255",
+ "eqsim":"\u2242",
+ "eqslantgtr":"\u2A96",
+ "eqslantless":"\u2A95",
+ "Equal":"\u2A75",
+ "equals":"\u003D",
+ "EqualTilde":"\u2242",
+ "equest":"\u225F",
+ "Equilibrium":"\u21CC",
+ "equiv":"\u2261",
+ "equivDD":"\u2A78",
+ "eqvparsl":"\u29E5",
+ "erarr":"\u2971",
+ "erDot":"\u2253",
+ "Escr":"\u2130",
+ "escr":"\u212F",
+ "esdot":"\u2250",
+ "Esim":"\u2A73",
+ "esim":"\u2242",
+ "Eta":"\u0397",
+ "eta":"\u03B7",
+ "ETH":"\u00D0",
+ "eth":"\u00F0",
+ "Euml":"\u00CB",
+ "euml":"\u00EB",
+ "euro":"\u20AC",
+ "excl":"\u0021",
+ "exist":"\u2203",
+ "Exists":"\u2203",
+ "expectation":"\u2130",
+ "ExponentialE":"\u2147",
+ "exponentiale":"\u2147",
+ "fallingdotseq":"\u2252",
+ "Fcy":"\u0424",
+ "fcy":"\u0444",
+ "female":"\u2640",
+ "ffilig":"\uFB03",
+ "fflig":"\uFB00",
+ "ffllig":"\uFB04",
+ "Ffr":"\uD835\uDD09",
+ "ffr":"\uD835\uDD23",
+ "filig":"\uFB01",
+ "FilledSmallSquare":"\u25FC",
+ "FilledVerySmallSquare":"\u25AA",
+ "fjlig":"\u0066\u006A",
+ "flat":"\u266D",
+ "fllig":"\uFB02",
+ "fltns":"\u25B1",
+ "fnof":"\u0192",
+ "Fopf":"\uD835\uDD3D",
+ "fopf":"\uD835\uDD57",
+ "ForAll":"\u2200",
+ "forall":"\u2200",
+ "fork":"\u22D4",
+ "forkv":"\u2AD9",
+ "Fouriertrf":"\u2131",
+ "fpartint":"\u2A0D",
+ "frac12":"\u00BD",
+ "frac13":"\u2153",
+ "frac14":"\u00BC",
+ "frac15":"\u2155",
+ "frac16":"\u2159",
+ "frac18":"\u215B",
+ "frac23":"\u2154",
+ "frac25":"\u2156",
+ "frac34":"\u00BE",
+ "frac35":"\u2157",
+ "frac38":"\u215C",
+ "frac45":"\u2158",
+ "frac56":"\u215A",
+ "frac58":"\u215D",
+ "frac78":"\u215E",
+ "frasl":"\u2044",
+ "frown":"\u2322",
+ "Fscr":"\u2131",
+ "fscr":"\uD835\uDCBB",
+ "gacute":"\u01F5",
+ "Gamma":"\u0393",
+ "gamma":"\u03B3",
+ "Gammad":"\u03DC",
+ "gammad":"\u03DD",
+ "gap":"\u2A86",
+ "Gbreve":"\u011E",
+ "gbreve":"\u011F",
+ "Gcedil":"\u0122",
+ "Gcirc":"\u011C",
+ "gcirc":"\u011D",
+ "Gcy":"\u0413",
+ "gcy":"\u0433",
+ "Gdot":"\u0120",
+ "gdot":"\u0121",
+ "gE":"\u2267",
+ "ge":"\u2265",
+ "gEl":"\u2A8C",
+ "gel":"\u22DB",
+ "geq":"\u2265",
+ "geqq":"\u2267",
+ "geqslant":"\u2A7E",
+ "ges":"\u2A7E",
+ "gescc":"\u2AA9",
+ "gesdot":"\u2A80",
+ "gesdoto":"\u2A82",
+ "gesdotol":"\u2A84",
+ "gesl":"\u22DB\uFE00",
+ "gesles":"\u2A94",
+ "Gfr":"\uD835\uDD0A",
+ "gfr":"\uD835\uDD24",
+ "Gg":"\u22D9",
+ "gg":"\u226B",
+ "ggg":"\u22D9",
+ "gimel":"\u2137",
+ "GJcy":"\u0403",
+ "gjcy":"\u0453",
+ "gl":"\u2277",
+ "gla":"\u2AA5",
+ "glE":"\u2A92",
+ "glj":"\u2AA4",
+ "gnap":"\u2A8A",
+ "gnapprox":"\u2A8A",
+ "gnE":"\u2269",
+ "gne":"\u2A88",
+ "gneq":"\u2A88",
+ "gneqq":"\u2269",
+ "gnsim":"\u22E7",
+ "Gopf":"\uD835\uDD3E",
+ "gopf":"\uD835\uDD58",
+ "grave":"\u0060",
+ "GreaterEqual":"\u2265",
+ "GreaterEqualLess":"\u22DB",
+ "GreaterFullEqual":"\u2267",
+ "GreaterGreater":"\u2AA2",
+ "GreaterLess":"\u2277",
+ "GreaterSlantEqual":"\u2A7E",
+ "GreaterTilde":"\u2273",
+ "Gscr":"\uD835\uDCA2",
+ "gscr":"\u210A",
+ "gsim":"\u2273",
+ "gsime":"\u2A8E",
+ "gsiml":"\u2A90",
+ "GT":"\u003E",
+ "Gt":"\u226B",
+ "gt":"\u003E",
+ "gtcc":"\u2AA7",
+ "gtcir":"\u2A7A",
+ "gtdot":"\u22D7",
+ "gtlPar":"\u2995",
+ "gtquest":"\u2A7C",
+ "gtrapprox":"\u2A86",
+ "gtrarr":"\u2978",
+ "gtrdot":"\u22D7",
+ "gtreqless":"\u22DB",
+ "gtreqqless":"\u2A8C",
+ "gtrless":"\u2277",
+ "gtrsim":"\u2273",
+ "gvertneqq":"\u2269\uFE00",
+ "gvnE":"\u2269\uFE00",
+ "Hacek":"\u02C7",
+ "hairsp":"\u200A",
+ "half":"\u00BD",
+ "hamilt":"\u210B",
+ "HARDcy":"\u042A",
+ "hardcy":"\u044A",
+ "hArr":"\u21D4",
+ "harr":"\u2194",
+ "harrcir":"\u2948",
+ "harrw":"\u21AD",
+ "Hat":"\u005E",
+ "hbar":"\u210F",
+ "Hcirc":"\u0124",
+ "hcirc":"\u0125",
+ "hearts":"\u2665",
+ "heartsuit":"\u2665",
+ "hellip":"\u2026",
+ "hercon":"\u22B9",
+ "Hfr":"\u210C",
+ "hfr":"\uD835\uDD25",
+ "HilbertSpace":"\u210B",
+ "hksearow":"\u2925",
+ "hkswarow":"\u2926",
+ "hoarr":"\u21FF",
+ "homtht":"\u223B",
+ "hookleftarrow":"\u21A9",
+ "hookrightarrow":"\u21AA",
+ "Hopf":"\u210D",
+ "hopf":"\uD835\uDD59",
+ "horbar":"\u2015",
+ "HorizontalLine":"\u2500",
+ "Hscr":"\u210B",
+ "hscr":"\uD835\uDCBD",
+ "hslash":"\u210F",
+ "Hstrok":"\u0126",
+ "hstrok":"\u0127",
+ "HumpDownHump":"\u224E",
+ "HumpEqual":"\u224F",
+ "hybull":"\u2043",
+ "hyphen":"\u2010",
+ "Iacute":"\u00CD",
+ "iacute":"\u00ED",
+ "ic":"\u2063",
+ "Icirc":"\u00CE",
+ "icirc":"\u00EE",
+ "Icy":"\u0418",
+ "icy":"\u0438",
+ "Idot":"\u0130",
+ "IEcy":"\u0415",
+ "iecy":"\u0435",
+ "iexcl":"\u00A1",
+ "iff":"\u21D4",
+ "Ifr":"\u2111",
+ "ifr":"\uD835\uDD26",
+ "Igrave":"\u00CC",
+ "igrave":"\u00EC",
+ "ii":"\u2148",
+ "iiiint":"\u2A0C",
+ "iiint":"\u222D",
+ "iinfin":"\u29DC",
+ "iiota":"\u2129",
+ "IJlig":"\u0132",
+ "ijlig":"\u0133",
+ "Im":"\u2111",
+ "Imacr":"\u012A",
+ "imacr":"\u012B",
+ "image":"\u2111",
+ "ImaginaryI":"\u2148",
+ "imagline":"\u2110",
+ "imagpart":"\u2111",
+ "imath":"\u0131",
+ "imof":"\u22B7",
+ "imped":"\u01B5",
+ "Implies":"\u21D2",
+ "in":"\u2208",
+ "incare":"\u2105",
+ "infin":"\u221E",
+ "infintie":"\u29DD",
+ "inodot":"\u0131",
+ "Int":"\u222C",
+ "int":"\u222B",
+ "intcal":"\u22BA",
+ "integers":"\u2124",
+ "Integral":"\u222B",
+ "intercal":"\u22BA",
+ "Intersection":"\u22C2",
+ "intlarhk":"\u2A17",
+ "intprod":"\u2A3C",
+ "InvisibleComma":"\u2063",
+ "InvisibleTimes":"\u2062",
+ "IOcy":"\u0401",
+ "iocy":"\u0451",
+ "Iogon":"\u012E",
+ "iogon":"\u012F",
+ "Iopf":"\uD835\uDD40",
+ "iopf":"\uD835\uDD5A",
+ "Iota":"\u0399",
+ "iota":"\u03B9",
+ "iprod":"\u2A3C",
+ "iquest":"\u00BF",
+ "Iscr":"\u2110",
+ "iscr":"\uD835\uDCBE",
+ "isin":"\u2208",
+ "isindot":"\u22F5",
+ "isinE":"\u22F9",
+ "isins":"\u22F4",
+ "isinsv":"\u22F3",
+ "isinv":"\u2208",
+ "it":"\u2062",
+ "Itilde":"\u0128",
+ "itilde":"\u0129",
+ "Iukcy":"\u0406",
+ "iukcy":"\u0456",
+ "Iuml":"\u00CF",
+ "iuml":"\u00EF",
+ "Jcirc":"\u0134",
+ "jcirc":"\u0135",
+ "Jcy":"\u0419",
+ "jcy":"\u0439",
+ "Jfr":"\uD835\uDD0D",
+ "jfr":"\uD835\uDD27",
+ "jmath":"\u0237",
+ "Jopf":"\uD835\uDD41",
+ "jopf":"\uD835\uDD5B",
+ "Jscr":"\uD835\uDCA5",
+ "jscr":"\uD835\uDCBF",
+ "Jsercy":"\u0408",
+ "jsercy":"\u0458",
+ "Jukcy":"\u0404",
+ "jukcy":"\u0454",
+ "Kappa":"\u039A",
+ "kappa":"\u03BA",
+ "kappav":"\u03F0",
+ "Kcedil":"\u0136",
+ "kcedil":"\u0137",
+ "Kcy":"\u041A",
+ "kcy":"\u043A",
+ "Kfr":"\uD835\uDD0E",
+ "kfr":"\uD835\uDD28",
+ "kgreen":"\u0138",
+ "KHcy":"\u0425",
+ "khcy":"\u0445",
+ "KJcy":"\u040C",
+ "kjcy":"\u045C",
+ "Kopf":"\uD835\uDD42",
+ "kopf":"\uD835\uDD5C",
+ "Kscr":"\uD835\uDCA6",
+ "kscr":"\uD835\uDCC0",
+ "lAarr":"\u21DA",
+ "Lacute":"\u0139",
+ "lacute":"\u013A",
+ "laemptyv":"\u29B4",
+ "lagran":"\u2112",
+ "Lambda":"\u039B",
+ "lambda":"\u03BB",
+ "Lang":"\u27EA",
+ "lang":"\u27E8",
+ "langd":"\u2991",
+ "langle":"\u27E8",
+ "lap":"\u2A85",
+ "Laplacetrf":"\u2112",
+ "laquo":"\u00AB",
+ "Larr":"\u219E",
+ "lArr":"\u21D0",
+ "larr":"\u2190",
+ "larrb":"\u21E4",
+ "larrbfs":"\u291F",
+ "larrfs":"\u291D",
+ "larrhk":"\u21A9",
+ "larrlp":"\u21AB",
+ "larrpl":"\u2939",
+ "larrsim":"\u2973",
+ "larrtl":"\u21A2",
+ "lat":"\u2AAB",
+ "lAtail":"\u291B",
+ "latail":"\u2919",
+ "late":"\u2AAD",
+ "lates":"\u2AAD\uFE00",
+ "lBarr":"\u290E",
+ "lbarr":"\u290C",
+ "lbbrk":"\u2772",
+ "lbrace":"\u007B",
+ "lbrack":"\u005B",
+ "lbrke":"\u298B",
+ "lbrksld":"\u298F",
+ "lbrkslu":"\u298D",
+ "Lcaron":"\u013D",
+ "lcaron":"\u013E",
+ "Lcedil":"\u013B",
+ "lcedil":"\u013C",
+ "lceil":"\u2308",
+ "lcub":"\u007B",
+ "Lcy":"\u041B",
+ "lcy":"\u043B",
+ "ldca":"\u2936",
+ "ldquo":"\u201C",
+ "ldquor":"\u201E",
+ "ldrdhar":"\u2967",
+ "ldrushar":"\u294B",
+ "ldsh":"\u21B2",
+ "lE":"\u2266",
+ "le":"\u2264",
+ "LeftAngleBracket":"\u27E8",
+ "LeftArrow":"\u2190",
+ "Leftarrow":"\u21D0",
+ "leftarrow":"\u2190",
+ "LeftArrowBar":"\u21E4",
+ "LeftArrowRightArrow":"\u21C6",
+ "leftarrowtail":"\u21A2",
+ "LeftCeiling":"\u2308",
+ "LeftDoubleBracket":"\u27E6",
+ "LeftDownTeeVector":"\u2961",
+ "LeftDownVector":"\u21C3",
+ "LeftDownVectorBar":"\u2959",
+ "LeftFloor":"\u230A",
+ "leftharpoondown":"\u21BD",
+ "leftharpoonup":"\u21BC",
+ "leftleftarrows":"\u21C7",
+ "LeftRightArrow":"\u2194",
+ "Leftrightarrow":"\u21D4",
+ "leftrightarrow":"\u2194",
+ "leftrightarrows":"\u21C6",
+ "leftrightharpoons":"\u21CB",
+ "leftrightsquigarrow":"\u21AD",
+ "LeftRightVector":"\u294E",
+ "LeftTee":"\u22A3",
+ "LeftTeeArrow":"\u21A4",
+ "LeftTeeVector":"\u295A",
+ "leftthreetimes":"\u22CB",
+ "LeftTriangle":"\u22B2",
+ "LeftTriangleBar":"\u29CF",
+ "LeftTriangleEqual":"\u22B4",
+ "LeftUpDownVector":"\u2951",
+ "LeftUpTeeVector":"\u2960",
+ "LeftUpVector":"\u21BF",
+ "LeftUpVectorBar":"\u2958",
+ "LeftVector":"\u21BC",
+ "LeftVectorBar":"\u2952",
+ "lEg":"\u2A8B",
+ "leg":"\u22DA",
+ "leq":"\u2264",
+ "leqq":"\u2266",
+ "leqslant":"\u2A7D",
+ "les":"\u2A7D",
+ "lescc":"\u2AA8",
+ "lesdot":"\u2A7F",
+ "lesdoto":"\u2A81",
+ "lesdotor":"\u2A83",
+ "lesg":"\u22DA\uFE00",
+ "lesges":"\u2A93",
+ "lessapprox":"\u2A85",
+ "lessdot":"\u22D6",
+ "lesseqgtr":"\u22DA",
+ "lesseqqgtr":"\u2A8B",
+ "LessEqualGreater":"\u22DA",
+ "LessFullEqual":"\u2266",
+ "LessGreater":"\u2276",
+ "lessgtr":"\u2276",
+ "LessLess":"\u2AA1",
+ "lesssim":"\u2272",
+ "LessSlantEqual":"\u2A7D",
+ "LessTilde":"\u2272",
+ "lfisht":"\u297C",
+ "lfloor":"\u230A",
+ "Lfr":"\uD835\uDD0F",
+ "lfr":"\uD835\uDD29",
+ "lg":"\u2276",
+ "lgE":"\u2A91",
+ "lHar":"\u2962",
+ "lhard":"\u21BD",
+ "lharu":"\u21BC",
+ "lharul":"\u296A",
+ "lhblk":"\u2584",
+ "LJcy":"\u0409",
+ "ljcy":"\u0459",
+ "Ll":"\u22D8",
+ "ll":"\u226A",
+ "llarr":"\u21C7",
+ "llcorner":"\u231E",
+ "Lleftarrow":"\u21DA",
+ "llhard":"\u296B",
+ "lltri":"\u25FA",
+ "Lmidot":"\u013F",
+ "lmidot":"\u0140",
+ "lmoust":"\u23B0",
+ "lmoustache":"\u23B0",
+ "lnap":"\u2A89",
+ "lnapprox":"\u2A89",
+ "lnE":"\u2268",
+ "lne":"\u2A87",
+ "lneq":"\u2A87",
+ "lneqq":"\u2268",
+ "lnsim":"\u22E6",
+ "loang":"\u27EC",
+ "loarr":"\u21FD",
+ "lobrk":"\u27E6",
+ "LongLeftArrow":"\u27F5",
+ "Longleftarrow":"\u27F8",
+ "longleftarrow":"\u27F5",
+ "LongLeftRightArrow":"\u27F7",
+ "Longleftrightarrow":"\u27FA",
+ "longleftrightarrow":"\u27F7",
+ "longmapsto":"\u27FC",
+ "LongRightArrow":"\u27F6",
+ "Longrightarrow":"\u27F9",
+ "longrightarrow":"\u27F6",
+ "looparrowleft":"\u21AB",
+ "looparrowright":"\u21AC",
+ "lopar":"\u2985",
+ "Lopf":"\uD835\uDD43",
+ "lopf":"\uD835\uDD5D",
+ "loplus":"\u2A2D",
+ "lotimes":"\u2A34",
+ "lowast":"\u2217",
+ "lowbar":"\u005F",
+ "LowerLeftArrow":"\u2199",
+ "LowerRightArrow":"\u2198",
+ "loz":"\u25CA",
+ "lozenge":"\u25CA",
+ "lozf":"\u29EB",
+ "lpar":"\u0028",
+ "lparlt":"\u2993",
+ "lrarr":"\u21C6",
+ "lrcorner":"\u231F",
+ "lrhar":"\u21CB",
+ "lrhard":"\u296D",
+ "lrm":"\u200E",
+ "lrtri":"\u22BF",
+ "lsaquo":"\u2039",
+ "Lscr":"\u2112",
+ "lscr":"\uD835\uDCC1",
+ "Lsh":"\u21B0",
+ "lsh":"\u21B0",
+ "lsim":"\u2272",
+ "lsime":"\u2A8D",
+ "lsimg":"\u2A8F",
+ "lsqb":"\u005B",
+ "lsquo":"\u2018",
+ "lsquor":"\u201A",
+ "Lstrok":"\u0141",
+ "lstrok":"\u0142",
+ "LT":"\u003C",
+ "Lt":"\u226A",
+ "lt":"\u003C",
+ "ltcc":"\u2AA6",
+ "ltcir":"\u2A79",
+ "ltdot":"\u22D6",
+ "lthree":"\u22CB",
+ "ltimes":"\u22C9",
+ "ltlarr":"\u2976",
+ "ltquest":"\u2A7B",
+ "ltri":"\u25C3",
+ "ltrie":"\u22B4",
+ "ltrif":"\u25C2",
+ "ltrPar":"\u2996",
+ "lurdshar":"\u294A",
+ "luruhar":"\u2966",
+ "lvertneqq":"\u2268\uFE00",
+ "lvnE":"\u2268\uFE00",
+ "macr":"\u00AF",
+ "male":"\u2642",
+ "malt":"\u2720",
+ "maltese":"\u2720",
+ "Map":"\u2905",
+ "map":"\u21A6",
+ "mapsto":"\u21A6",
+ "mapstodown":"\u21A7",
+ "mapstoleft":"\u21A4",
+ "mapstoup":"\u21A5",
+ "marker":"\u25AE",
+ "mcomma":"\u2A29",
+ "Mcy":"\u041C",
+ "mcy":"\u043C",
+ "mdash":"\u2014",
+ "mDDot":"\u223A",
+ "measuredangle":"\u2221",
+ "MediumSpace":"\u205F",
+ "Mellintrf":"\u2133",
+ "Mfr":"\uD835\uDD10",
+ "mfr":"\uD835\uDD2A",
+ "mho":"\u2127",
+ "micro":"\u00B5",
+ "mid":"\u2223",
+ "midast":"\u002A",
+ "midcir":"\u2AF0",
+ "middot":"\u00B7",
+ "minus":"\u2212",
+ "minusb":"\u229F",
+ "minusd":"\u2238",
+ "minusdu":"\u2A2A",
+ "MinusPlus":"\u2213",
+ "mlcp":"\u2ADB",
+ "mldr":"\u2026",
+ "mnplus":"\u2213",
+ "models":"\u22A7",
+ "Mopf":"\uD835\uDD44",
+ "mopf":"\uD835\uDD5E",
+ "mp":"\u2213",
+ "Mscr":"\u2133",
+ "mscr":"\uD835\uDCC2",
+ "mstpos":"\u223E",
+ "Mu":"\u039C",
+ "mu":"\u03BC",
+ "multimap":"\u22B8",
+ "mumap":"\u22B8",
+ "nabla":"\u2207",
+ "Nacute":"\u0143",
+ "nacute":"\u0144",
+ "nang":"\u2220\u20D2",
+ "nap":"\u2249",
+ "napE":"\u2A70\u0338",
+ "napid":"\u224B\u0338",
+ "napos":"\u0149",
+ "napprox":"\u2249",
+ "natur":"\u266E",
+ "natural":"\u266E",
+ "naturals":"\u2115",
+ "nbsp":"\u00A0",
+ "nbump":"\u224E\u0338",
+ "nbumpe":"\u224F\u0338",
+ "ncap":"\u2A43",
+ "Ncaron":"\u0147",
+ "ncaron":"\u0148",
+ "Ncedil":"\u0145",
+ "ncedil":"\u0146",
+ "ncong":"\u2247",
+ "ncongdot":"\u2A6D\u0338",
+ "ncup":"\u2A42",
+ "Ncy":"\u041D",
+ "ncy":"\u043D",
+ "ndash":"\u2013",
+ "ne":"\u2260",
+ "nearhk":"\u2924",
+ "neArr":"\u21D7",
+ "nearr":"\u2197",
+ "nearrow":"\u2197",
+ "nedot":"\u2250\u0338",
+ "NegativeMediumSpace":"\u200B",
+ "NegativeThickSpace":"\u200B",
+ "NegativeThinSpace":"\u200B",
+ "NegativeVeryThinSpace":"\u200B",
+ "nequiv":"\u2262",
+ "nesear":"\u2928",
+ "nesim":"\u2242\u0338",
+ "NestedGreaterGreater":"\u226B",
+ "NestedLessLess":"\u226A",
+ "NewLine":"\u000A",
+ "nexist":"\u2204",
+ "nexists":"\u2204",
+ "Nfr":"\uD835\uDD11",
+ "nfr":"\uD835\uDD2B",
+ "ngE":"\u2267\u0338",
+ "nge":"\u2271",
+ "ngeq":"\u2271",
+ "ngeqq":"\u2267\u0338",
+ "ngeqslant":"\u2A7E\u0338",
+ "nges":"\u2A7E\u0338",
+ "nGg":"\u22D9\u0338",
+ "ngsim":"\u2275",
+ "nGt":"\u226B\u20D2",
+ "ngt":"\u226F",
+ "ngtr":"\u226F",
+ "nGtv":"\u226B\u0338",
+ "nhArr":"\u21CE",
+ "nharr":"\u21AE",
+ "nhpar":"\u2AF2",
+ "ni":"\u220B",
+ "nis":"\u22FC",
+ "nisd":"\u22FA",
+ "niv":"\u220B",
+ "NJcy":"\u040A",
+ "njcy":"\u045A",
+ "nlArr":"\u21CD",
+ "nlarr":"\u219A",
+ "nldr":"\u2025",
+ "nlE":"\u2266\u0338",
+ "nle":"\u2270",
+ "nLeftarrow":"\u21CD",
+ "nleftarrow":"\u219A",
+ "nLeftrightarrow":"\u21CE",
+ "nleftrightarrow":"\u21AE",
+ "nleq":"\u2270",
+ "nleqq":"\u2266\u0338",
+ "nleqslant":"\u2A7D\u0338",
+ "nles":"\u2A7D\u0338",
+ "nless":"\u226E",
+ "nLl":"\u22D8\u0338",
+ "nlsim":"\u2274",
+ "nLt":"\u226A\u20D2",
+ "nlt":"\u226E",
+ "nltri":"\u22EA",
+ "nltrie":"\u22EC",
+ "nLtv":"\u226A\u0338",
+ "nmid":"\u2224",
+ "NoBreak":"\u2060",
+ "NonBreakingSpace":"\u00A0",
+ "Nopf":"\u2115",
+ "nopf":"\uD835\uDD5F",
+ "Not":"\u2AEC",
+ "not":"\u00AC",
+ "NotCongruent":"\u2262",
+ "NotCupCap":"\u226D",
+ "NotDoubleVerticalBar":"\u2226",
+ "NotElement":"\u2209",
+ "NotEqual":"\u2260",
+ "NotEqualTilde":"\u2242\u0338",
+ "NotExists":"\u2204",
+ "NotGreater":"\u226F",
+ "NotGreaterEqual":"\u2271",
+ "NotGreaterFullEqual":"\u2267\u0338",
+ "NotGreaterGreater":"\u226B\u0338",
+ "NotGreaterLess":"\u2279",
+ "NotGreaterSlantEqual":"\u2A7E\u0338",
+ "NotGreaterTilde":"\u2275",
+ "NotHumpDownHump":"\u224E\u0338",
+ "NotHumpEqual":"\u224F\u0338",
+ "notin":"\u2209",
+ "notindot":"\u22F5\u0338",
+ "notinE":"\u22F9\u0338",
+ "notinva":"\u2209",
+ "notinvb":"\u22F7",
+ "notinvc":"\u22F6",
+ "NotLeftTriangle":"\u22EA",
+ "NotLeftTriangleBar":"\u29CF\u0338",
+ "NotLeftTriangleEqual":"\u22EC",
+ "NotLess":"\u226E",
+ "NotLessEqual":"\u2270",
+ "NotLessGreater":"\u2278",
+ "NotLessLess":"\u226A\u0338",
+ "NotLessSlantEqual":"\u2A7D\u0338",
+ "NotLessTilde":"\u2274",
+ "NotNestedGreaterGreater":"\u2AA2\u0338",
+ "NotNestedLessLess":"\u2AA1\u0338",
+ "notni":"\u220C",
+ "notniva":"\u220C",
+ "notnivb":"\u22FE",
+ "notnivc":"\u22FD",
+ "NotPrecedes":"\u2280",
+ "NotPrecedesEqual":"\u2AAF\u0338",
+ "NotPrecedesSlantEqual":"\u22E0",
+ "NotReverseElement":"\u220C",
+ "NotRightTriangle":"\u22EB",
+ "NotRightTriangleBar":"\u29D0\u0338",
+ "NotRightTriangleEqual":"\u22ED",
+ "NotSquareSubset":"\u228F\u0338",
+ "NotSquareSubsetEqual":"\u22E2",
+ "NotSquareSuperset":"\u2290\u0338",
+ "NotSquareSupersetEqual":"\u22E3",
+ "NotSubset":"\u2282\u20D2",
+ "NotSubsetEqual":"\u2288",
+ "NotSucceeds":"\u2281",
+ "NotSucceedsEqual":"\u2AB0\u0338",
+ "NotSucceedsSlantEqual":"\u22E1",
+ "NotSucceedsTilde":"\u227F\u0338",
+ "NotSuperset":"\u2283\u20D2",
+ "NotSupersetEqual":"\u2289",
+ "NotTilde":"\u2241",
+ "NotTildeEqual":"\u2244",
+ "NotTildeFullEqual":"\u2247",
+ "NotTildeTilde":"\u2249",
+ "NotVerticalBar":"\u2224",
+ "npar":"\u2226",
+ "nparallel":"\u2226",
+ "nparsl":"\u2AFD\u20E5",
+ "npart":"\u2202\u0338",
+ "npolint":"\u2A14",
+ "npr":"\u2280",
+ "nprcue":"\u22E0",
+ "npre":"\u2AAF\u0338",
+ "nprec":"\u2280",
+ "npreceq":"\u2AAF\u0338",
+ "nrArr":"\u21CF",
+ "nrarr":"\u219B",
+ "nrarrc":"\u2933\u0338",
+ "nrarrw":"\u219D\u0338",
+ "nRightarrow":"\u21CF",
+ "nrightarrow":"\u219B",
+ "nrtri":"\u22EB",
+ "nrtrie":"\u22ED",
+ "nsc":"\u2281",
+ "nsccue":"\u22E1",
+ "nsce":"\u2AB0\u0338",
+ "Nscr":"\uD835\uDCA9",
+ "nscr":"\uD835\uDCC3",
+ "nshortmid":"\u2224",
+ "nshortparallel":"\u2226",
+ "nsim":"\u2241",
+ "nsime":"\u2244",
+ "nsimeq":"\u2244",
+ "nsmid":"\u2224",
+ "nspar":"\u2226",
+ "nsqsube":"\u22E2",
+ "nsqsupe":"\u22E3",
+ "nsub":"\u2284",
+ "nsubE":"\u2AC5\u0338",
+ "nsube":"\u2288",
+ "nsubset":"\u2282\u20D2",
+ "nsubseteq":"\u2288",
+ "nsubseteqq":"\u2AC5\u0338",
+ "nsucc":"\u2281",
+ "nsucceq":"\u2AB0\u0338",
+ "nsup":"\u2285",
+ "nsupE":"\u2AC6\u0338",
+ "nsupe":"\u2289",
+ "nsupset":"\u2283\u20D2",
+ "nsupseteq":"\u2289",
+ "nsupseteqq":"\u2AC6\u0338",
+ "ntgl":"\u2279",
+ "Ntilde":"\u00D1",
+ "ntilde":"\u00F1",
+ "ntlg":"\u2278",
+ "ntriangleleft":"\u22EA",
+ "ntrianglelefteq":"\u22EC",
+ "ntriangleright":"\u22EB",
+ "ntrianglerighteq":"\u22ED",
+ "Nu":"\u039D",
+ "nu":"\u03BD",
+ "num":"\u0023",
+ "numero":"\u2116",
+ "numsp":"\u2007",
+ "nvap":"\u224D\u20D2",
+ "nVDash":"\u22AF",
+ "nVdash":"\u22AE",
+ "nvDash":"\u22AD",
+ "nvdash":"\u22AC",
+ "nvge":"\u2265\u20D2",
+ "nvgt":"\u003E\u20D2",
+ "nvHarr":"\u2904",
+ "nvinfin":"\u29DE",
+ "nvlArr":"\u2902",
+ "nvle":"\u2264\u20D2",
+ "nvlt":"\u003C\u20D2",
+ "nvltrie":"\u22B4\u20D2",
+ "nvrArr":"\u2903",
+ "nvrtrie":"\u22B5\u20D2",
+ "nvsim":"\u223C\u20D2",
+ "nwarhk":"\u2923",
+ "nwArr":"\u21D6",
+ "nwarr":"\u2196",
+ "nwarrow":"\u2196",
+ "nwnear":"\u2927",
+ "Oacute":"\u00D3",
+ "oacute":"\u00F3",
+ "oast":"\u229B",
+ "ocir":"\u229A",
+ "Ocirc":"\u00D4",
+ "ocirc":"\u00F4",
+ "Ocy":"\u041E",
+ "ocy":"\u043E",
+ "odash":"\u229D",
+ "Odblac":"\u0150",
+ "odblac":"\u0151",
+ "odiv":"\u2A38",
+ "odot":"\u2299",
+ "odsold":"\u29BC",
+ "OElig":"\u0152",
+ "oelig":"\u0153",
+ "ofcir":"\u29BF",
+ "Ofr":"\uD835\uDD12",
+ "ofr":"\uD835\uDD2C",
+ "ogon":"\u02DB",
+ "Ograve":"\u00D2",
+ "ograve":"\u00F2",
+ "ogt":"\u29C1",
+ "ohbar":"\u29B5",
+ "ohm":"\u03A9",
+ "oint":"\u222E",
+ "olarr":"\u21BA",
+ "olcir":"\u29BE",
+ "olcross":"\u29BB",
+ "oline":"\u203E",
+ "olt":"\u29C0",
+ "Omacr":"\u014C",
+ "omacr":"\u014D",
+ "Omega":"\u03A9",
+ "omega":"\u03C9",
+ "Omicron":"\u039F",
+ "omicron":"\u03BF",
+ "omid":"\u29B6",
+ "ominus":"\u2296",
+ "Oopf":"\uD835\uDD46",
+ "oopf":"\uD835\uDD60",
+ "opar":"\u29B7",
+ "OpenCurlyDoubleQuote":"\u201C",
+ "OpenCurlyQuote":"\u2018",
+ "operp":"\u29B9",
+ "oplus":"\u2295",
+ "Or":"\u2A54",
+ "or":"\u2228",
+ "orarr":"\u21BB",
+ "ord":"\u2A5D",
+ "order":"\u2134",
+ "orderof":"\u2134",
+ "ordf":"\u00AA",
+ "ordm":"\u00BA",
+ "origof":"\u22B6",
+ "oror":"\u2A56",
+ "orslope":"\u2A57",
+ "orv":"\u2A5B",
+ "oS":"\u24C8",
+ "Oscr":"\uD835\uDCAA",
+ "oscr":"\u2134",
+ "Oslash":"\u00D8",
+ "oslash":"\u00F8",
+ "osol":"\u2298",
+ "Otilde":"\u00D5",
+ "otilde":"\u00F5",
+ "Otimes":"\u2A37",
+ "otimes":"\u2297",
+ "otimesas":"\u2A36",
+ "Ouml":"\u00D6",
+ "ouml":"\u00F6",
+ "ovbar":"\u233D",
+ "OverBar":"\u203E",
+ "OverBrace":"\u23DE",
+ "OverBracket":"\u23B4",
+ "OverParenthesis":"\u23DC",
+ "par":"\u2225",
+ "para":"\u00B6",
+ "parallel":"\u2225",
+ "parsim":"\u2AF3",
+ "parsl":"\u2AFD",
+ "part":"\u2202",
+ "PartialD":"\u2202",
+ "Pcy":"\u041F",
+ "pcy":"\u043F",
+ "percnt":"\u0025",
+ "period":"\u002E",
+ "permil":"\u2030",
+ "perp":"\u22A5",
+ "pertenk":"\u2031",
+ "Pfr":"\uD835\uDD13",
+ "pfr":"\uD835\uDD2D",
+ "Phi":"\u03A6",
+ "phi":"\u03C6",
+ "phiv":"\u03D5",
+ "phmmat":"\u2133",
+ "phone":"\u260E",
+ "Pi":"\u03A0",
+ "pi":"\u03C0",
+ "pitchfork":"\u22D4",
+ "piv":"\u03D6",
+ "planck":"\u210F",
+ "planckh":"\u210E",
+ "plankv":"\u210F",
+ "plus":"\u002B",
+ "plusacir":"\u2A23",
+ "plusb":"\u229E",
+ "pluscir":"\u2A22",
+ "plusdo":"\u2214",
+ "plusdu":"\u2A25",
+ "pluse":"\u2A72",
+ "PlusMinus":"\u00B1",
+ "plusmn":"\u00B1",
+ "plussim":"\u2A26",
+ "plustwo":"\u2A27",
+ "pm":"\u00B1",
+ "Poincareplane":"\u210C",
+ "pointint":"\u2A15",
+ "Popf":"\u2119",
+ "popf":"\uD835\uDD61",
+ "pound":"\u00A3",
+ "Pr":"\u2ABB",
+ "pr":"\u227A",
+ "prap":"\u2AB7",
+ "prcue":"\u227C",
+ "prE":"\u2AB3",
+ "pre":"\u2AAF",
+ "prec":"\u227A",
+ "precapprox":"\u2AB7",
+ "preccurlyeq":"\u227C",
+ "Precedes":"\u227A",
+ "PrecedesEqual":"\u2AAF",
+ "PrecedesSlantEqual":"\u227C",
+ "PrecedesTilde":"\u227E",
+ "preceq":"\u2AAF",
+ "precnapprox":"\u2AB9",
+ "precneqq":"\u2AB5",
+ "precnsim":"\u22E8",
+ "precsim":"\u227E",
+ "Prime":"\u2033",
+ "prime":"\u2032",
+ "primes":"\u2119",
+ "prnap":"\u2AB9",
+ "prnE":"\u2AB5",
+ "prnsim":"\u22E8",
+ "prod":"\u220F",
+ "Product":"\u220F",
+ "profalar":"\u232E",
+ "profline":"\u2312",
+ "profsurf":"\u2313",
+ "prop":"\u221D",
+ "Proportion":"\u2237",
+ "Proportional":"\u221D",
+ "propto":"\u221D",
+ "prsim":"\u227E",
+ "prurel":"\u22B0",
+ "Pscr":"\uD835\uDCAB",
+ "pscr":"\uD835\uDCC5",
+ "Psi":"\u03A8",
+ "psi":"\u03C8",
+ "puncsp":"\u2008",
+ "Qfr":"\uD835\uDD14",
+ "qfr":"\uD835\uDD2E",
+ "qint":"\u2A0C",
+ "Qopf":"\u211A",
+ "qopf":"\uD835\uDD62",
+ "qprime":"\u2057",
+ "Qscr":"\uD835\uDCAC",
+ "qscr":"\uD835\uDCC6",
+ "quaternions":"\u210D",
+ "quatint":"\u2A16",
+ "quest":"\u003F",
+ "questeq":"\u225F",
+ "QUOT":"\u0022",
+ "quot":"\u0022",
+ "rAarr":"\u21DB",
+ "race":"\u223D\u0331",
+ "Racute":"\u0154",
+ "racute":"\u0155",
+ "radic":"\u221A",
+ "raemptyv":"\u29B3",
+ "Rang":"\u27EB",
+ "rang":"\u27E9",
+ "rangd":"\u2992",
+ "range":"\u29A5",
+ "rangle":"\u27E9",
+ "raquo":"\u00BB",
+ "Rarr":"\u21A0",
+ "rArr":"\u21D2",
+ "rarr":"\u2192",
+ "rarrap":"\u2975",
+ "rarrb":"\u21E5",
+ "rarrbfs":"\u2920",
+ "rarrc":"\u2933",
+ "rarrfs":"\u291E",
+ "rarrhk":"\u21AA",
+ "rarrlp":"\u21AC",
+ "rarrpl":"\u2945",
+ "rarrsim":"\u2974",
+ "Rarrtl":"\u2916",
+ "rarrtl":"\u21A3",
+ "rarrw":"\u219D",
+ "rAtail":"\u291C",
+ "ratail":"\u291A",
+ "ratio":"\u2236",
+ "rationals":"\u211A",
+ "RBarr":"\u2910",
+ "rBarr":"\u290F",
+ "rbarr":"\u290D",
+ "rbbrk":"\u2773",
+ "rbrace":"\u007D",
+ "rbrack":"\u005D",
+ "rbrke":"\u298C",
+ "rbrksld":"\u298E",
+ "rbrkslu":"\u2990",
+ "Rcaron":"\u0158",
+ "rcaron":"\u0159",
+ "Rcedil":"\u0156",
+ "rcedil":"\u0157",
+ "rceil":"\u2309",
+ "rcub":"\u007D",
+ "Rcy":"\u0420",
+ "rcy":"\u0440",
+ "rdca":"\u2937",
+ "rdldhar":"\u2969",
+ "rdquo":"\u201D",
+ "rdquor":"\u201D",
+ "rdsh":"\u21B3",
+ "Re":"\u211C",
+ "real":"\u211C",
+ "realine":"\u211B",
+ "realpart":"\u211C",
+ "reals":"\u211D",
+ "rect":"\u25AD",
+ "REG":"\u00AE",
+ "reg":"\u00AE",
+ "ReverseElement":"\u220B",
+ "ReverseEquilibrium":"\u21CB",
+ "ReverseUpEquilibrium":"\u296F",
+ "rfisht":"\u297D",
+ "rfloor":"\u230B",
+ "Rfr":"\u211C",
+ "rfr":"\uD835\uDD2F",
+ "rHar":"\u2964",
+ "rhard":"\u21C1",
+ "rharu":"\u21C0",
+ "rharul":"\u296C",
+ "Rho":"\u03A1",
+ "rho":"\u03C1",
+ "rhov":"\u03F1",
+ "RightAngleBracket":"\u27E9",
+ "RightArrow":"\u2192",
+ "Rightarrow":"\u21D2",
+ "rightarrow":"\u2192",
+ "RightArrowBar":"\u21E5",
+ "RightArrowLeftArrow":"\u21C4",
+ "rightarrowtail":"\u21A3",
+ "RightCeiling":"\u2309",
+ "RightDoubleBracket":"\u27E7",
+ "RightDownTeeVector":"\u295D",
+ "RightDownVector":"\u21C2",
+ "RightDownVectorBar":"\u2955",
+ "RightFloor":"\u230B",
+ "rightharpoondown":"\u21C1",
+ "rightharpoonup":"\u21C0",
+ "rightleftarrows":"\u21C4",
+ "rightleftharpoons":"\u21CC",
+ "rightrightarrows":"\u21C9",
+ "rightsquigarrow":"\u219D",
+ "RightTee":"\u22A2",
+ "RightTeeArrow":"\u21A6",
+ "RightTeeVector":"\u295B",
+ "rightthreetimes":"\u22CC",
+ "RightTriangle":"\u22B3",
+ "RightTriangleBar":"\u29D0",
+ "RightTriangleEqual":"\u22B5",
+ "RightUpDownVector":"\u294F",
+ "RightUpTeeVector":"\u295C",
+ "RightUpVector":"\u21BE",
+ "RightUpVectorBar":"\u2954",
+ "RightVector":"\u21C0",
+ "RightVectorBar":"\u2953",
+ "ring":"\u02DA",
+ "risingdotseq":"\u2253",
+ "rlarr":"\u21C4",
+ "rlhar":"\u21CC",
+ "rlm":"\u200F",
+ "rmoust":"\u23B1",
+ "rmoustache":"\u23B1",
+ "rnmid":"\u2AEE",
+ "roang":"\u27ED",
+ "roarr":"\u21FE",
+ "robrk":"\u27E7",
+ "ropar":"\u2986",
+ "Ropf":"\u211D",
+ "ropf":"\uD835\uDD63",
+ "roplus":"\u2A2E",
+ "rotimes":"\u2A35",
+ "RoundImplies":"\u2970",
+ "rpar":"\u0029",
+ "rpargt":"\u2994",
+ "rppolint":"\u2A12",
+ "rrarr":"\u21C9",
+ "Rrightarrow":"\u21DB",
+ "rsaquo":"\u203A",
+ "Rscr":"\u211B",
+ "rscr":"\uD835\uDCC7",
+ "Rsh":"\u21B1",
+ "rsh":"\u21B1",
+ "rsqb":"\u005D",
+ "rsquo":"\u2019",
+ "rsquor":"\u2019",
+ "rthree":"\u22CC",
+ "rtimes":"\u22CA",
+ "rtri":"\u25B9",
+ "rtrie":"\u22B5",
+ "rtrif":"\u25B8",
+ "rtriltri":"\u29CE",
+ "RuleDelayed":"\u29F4",
+ "ruluhar":"\u2968",
+ "rx":"\u211E",
+ "Sacute":"\u015A",
+ "sacute":"\u015B",
+ "sbquo":"\u201A",
+ "Sc":"\u2ABC",
+ "sc":"\u227B",
+ "scap":"\u2AB8",
+ "Scaron":"\u0160",
+ "scaron":"\u0161",
+ "sccue":"\u227D",
+ "scE":"\u2AB4",
+ "sce":"\u2AB0",
+ "Scedil":"\u015E",
+ "scedil":"\u015F",
+ "Scirc":"\u015C",
+ "scirc":"\u015D",
+ "scnap":"\u2ABA",
+ "scnE":"\u2AB6",
+ "scnsim":"\u22E9",
+ "scpolint":"\u2A13",
+ "scsim":"\u227F",
+ "Scy":"\u0421",
+ "scy":"\u0441",
+ "sdot":"\u22C5",
+ "sdotb":"\u22A1",
+ "sdote":"\u2A66",
+ "searhk":"\u2925",
+ "seArr":"\u21D8",
+ "searr":"\u2198",
+ "searrow":"\u2198",
+ "sect":"\u00A7",
+ "semi":"\u003B",
+ "seswar":"\u2929",
+ "setminus":"\u2216",
+ "setmn":"\u2216",
+ "sext":"\u2736",
+ "Sfr":"\uD835\uDD16",
+ "sfr":"\uD835\uDD30",
+ "sfrown":"\u2322",
+ "sharp":"\u266F",
+ "SHCHcy":"\u0429",
+ "shchcy":"\u0449",
+ "SHcy":"\u0428",
+ "shcy":"\u0448",
+ "ShortDownArrow":"\u2193",
+ "ShortLeftArrow":"\u2190",
+ "shortmid":"\u2223",
+ "shortparallel":"\u2225",
+ "ShortRightArrow":"\u2192",
+ "ShortUpArrow":"\u2191",
+ "shy":"\u00AD",
+ "Sigma":"\u03A3",
+ "sigma":"\u03C3",
+ "sigmaf":"\u03C2",
+ "sigmav":"\u03C2",
+ "sim":"\u223C",
+ "simdot":"\u2A6A",
+ "sime":"\u2243",
+ "simeq":"\u2243",
+ "simg":"\u2A9E",
+ "simgE":"\u2AA0",
+ "siml":"\u2A9D",
+ "simlE":"\u2A9F",
+ "simne":"\u2246",
+ "simplus":"\u2A24",
+ "simrarr":"\u2972",
+ "slarr":"\u2190",
+ "SmallCircle":"\u2218",
+ "smallsetminus":"\u2216",
+ "smashp":"\u2A33",
+ "smeparsl":"\u29E4",
+ "smid":"\u2223",
+ "smile":"\u2323",
+ "smt":"\u2AAA",
+ "smte":"\u2AAC",
+ "smtes":"\u2AAC\uFE00",
+ "SOFTcy":"\u042C",
+ "softcy":"\u044C",
+ "sol":"\u002F",
+ "solb":"\u29C4",
+ "solbar":"\u233F",
+ "Sopf":"\uD835\uDD4A",
+ "sopf":"\uD835\uDD64",
+ "spades":"\u2660",
+ "spadesuit":"\u2660",
+ "spar":"\u2225",
+ "sqcap":"\u2293",
+ "sqcaps":"\u2293\uFE00",
+ "sqcup":"\u2294",
+ "sqcups":"\u2294\uFE00",
+ "Sqrt":"\u221A",
+ "sqsub":"\u228F",
+ "sqsube":"\u2291",
+ "sqsubset":"\u228F",
+ "sqsubseteq":"\u2291",
+ "sqsup":"\u2290",
+ "sqsupe":"\u2292",
+ "sqsupset":"\u2290",
+ "sqsupseteq":"\u2292",
+ "squ":"\u25A1",
+ "Square":"\u25A1",
+ "square":"\u25A1",
+ "SquareIntersection":"\u2293",
+ "SquareSubset":"\u228F",
+ "SquareSubsetEqual":"\u2291",
+ "SquareSuperset":"\u2290",
+ "SquareSupersetEqual":"\u2292",
+ "SquareUnion":"\u2294",
+ "squarf":"\u25AA",
+ "squf":"\u25AA",
+ "srarr":"\u2192",
+ "Sscr":"\uD835\uDCAE",
+ "sscr":"\uD835\uDCC8",
+ "ssetmn":"\u2216",
+ "ssmile":"\u2323",
+ "sstarf":"\u22C6",
+ "Star":"\u22C6",
+ "star":"\u2606",
+ "starf":"\u2605",
+ "straightepsilon":"\u03F5",
+ "straightphi":"\u03D5",
+ "strns":"\u00AF",
+ "Sub":"\u22D0",
+ "sub":"\u2282",
+ "subdot":"\u2ABD",
+ "subE":"\u2AC5",
+ "sube":"\u2286",
+ "subedot":"\u2AC3",
+ "submult":"\u2AC1",
+ "subnE":"\u2ACB",
+ "subne":"\u228A",
+ "subplus":"\u2ABF",
+ "subrarr":"\u2979",
+ "Subset":"\u22D0",
+ "subset":"\u2282",
+ "subseteq":"\u2286",
+ "subseteqq":"\u2AC5",
+ "SubsetEqual":"\u2286",
+ "subsetneq":"\u228A",
+ "subsetneqq":"\u2ACB",
+ "subsim":"\u2AC7",
+ "subsub":"\u2AD5",
+ "subsup":"\u2AD3",
+ "succ":"\u227B",
+ "succapprox":"\u2AB8",
+ "succcurlyeq":"\u227D",
+ "Succeeds":"\u227B",
+ "SucceedsEqual":"\u2AB0",
+ "SucceedsSlantEqual":"\u227D",
+ "SucceedsTilde":"\u227F",
+ "succeq":"\u2AB0",
+ "succnapprox":"\u2ABA",
+ "succneqq":"\u2AB6",
+ "succnsim":"\u22E9",
+ "succsim":"\u227F",
+ "SuchThat":"\u220B",
+ "Sum":"\u2211",
+ "sum":"\u2211",
+ "sung":"\u266A",
+ "Sup":"\u22D1",
+ "sup":"\u2283",
+ "sup1":"\u00B9",
+ "sup2":"\u00B2",
+ "sup3":"\u00B3",
+ "supdot":"\u2ABE",
+ "supdsub":"\u2AD8",
+ "supE":"\u2AC6",
+ "supe":"\u2287",
+ "supedot":"\u2AC4",
+ "Superset":"\u2283",
+ "SupersetEqual":"\u2287",
+ "suphsol":"\u27C9",
+ "suphsub":"\u2AD7",
+ "suplarr":"\u297B",
+ "supmult":"\u2AC2",
+ "supnE":"\u2ACC",
+ "supne":"\u228B",
+ "supplus":"\u2AC0",
+ "Supset":"\u22D1",
+ "supset":"\u2283",
+ "supseteq":"\u2287",
+ "supseteqq":"\u2AC6",
+ "supsetneq":"\u228B",
+ "supsetneqq":"\u2ACC",
+ "supsim":"\u2AC8",
+ "supsub":"\u2AD4",
+ "supsup":"\u2AD6",
+ "swarhk":"\u2926",
+ "swArr":"\u21D9",
+ "swarr":"\u2199",
+ "swarrow":"\u2199",
+ "swnwar":"\u292A",
+ "szlig":"\u00DF",
+ "Tab":"\u0009",
+ "target":"\u2316",
+ "Tau":"\u03A4",
+ "tau":"\u03C4",
+ "tbrk":"\u23B4",
+ "Tcaron":"\u0164",
+ "tcaron":"\u0165",
+ "Tcedil":"\u0162",
+ "tcedil":"\u0163",
+ "Tcy":"\u0422",
+ "tcy":"\u0442",
+ "tdot":"\u20DB",
+ "telrec":"\u2315",
+ "Tfr":"\uD835\uDD17",
+ "tfr":"\uD835\uDD31",
+ "there4":"\u2234",
+ "Therefore":"\u2234",
+ "therefore":"\u2234",
+ "Theta":"\u0398",
+ "theta":"\u03B8",
+ "thetasym":"\u03D1",
+ "thetav":"\u03D1",
+ "thickapprox":"\u2248",
+ "thicksim":"\u223C",
+ "ThickSpace":"\u205F\u200A",
+ "thinsp":"\u2009",
+ "ThinSpace":"\u2009",
+ "thkap":"\u2248",
+ "thksim":"\u223C",
+ "THORN":"\u00DE",
+ "thorn":"\u00FE",
+ "Tilde":"\u223C",
+ "tilde":"\u02DC",
+ "TildeEqual":"\u2243",
+ "TildeFullEqual":"\u2245",
+ "TildeTilde":"\u2248",
+ "times":"\u00D7",
+ "timesb":"\u22A0",
+ "timesbar":"\u2A31",
+ "timesd":"\u2A30",
+ "tint":"\u222D",
+ "toea":"\u2928",
+ "top":"\u22A4",
+ "topbot":"\u2336",
+ "topcir":"\u2AF1",
+ "Topf":"\uD835\uDD4B",
+ "topf":"\uD835\uDD65",
+ "topfork":"\u2ADA",
+ "tosa":"\u2929",
+ "tprime":"\u2034",
+ "TRADE":"\u2122",
+ "trade":"\u2122",
+ "triangle":"\u25B5",
+ "triangledown":"\u25BF",
+ "triangleleft":"\u25C3",
+ "trianglelefteq":"\u22B4",
+ "triangleq":"\u225C",
+ "triangleright":"\u25B9",
+ "trianglerighteq":"\u22B5",
+ "tridot":"\u25EC",
+ "trie":"\u225C",
+ "triminus":"\u2A3A",
+ "TripleDot":"\u20DB",
+ "triplus":"\u2A39",
+ "trisb":"\u29CD",
+ "tritime":"\u2A3B",
+ "trpezium":"\u23E2",
+ "Tscr":"\uD835\uDCAF",
+ "tscr":"\uD835\uDCC9",
+ "TScy":"\u0426",
+ "tscy":"\u0446",
+ "TSHcy":"\u040B",
+ "tshcy":"\u045B",
+ "Tstrok":"\u0166",
+ "tstrok":"\u0167",
+ "twixt":"\u226C",
+ "twoheadleftarrow":"\u219E",
+ "twoheadrightarrow":"\u21A0",
+ "Uacute":"\u00DA",
+ "uacute":"\u00FA",
+ "Uarr":"\u219F",
+ "uArr":"\u21D1",
+ "uarr":"\u2191",
+ "Uarrocir":"\u2949",
+ "Ubrcy":"\u040E",
+ "ubrcy":"\u045E",
+ "Ubreve":"\u016C",
+ "ubreve":"\u016D",
+ "Ucirc":"\u00DB",
+ "ucirc":"\u00FB",
+ "Ucy":"\u0423",
+ "ucy":"\u0443",
+ "udarr":"\u21C5",
+ "Udblac":"\u0170",
+ "udblac":"\u0171",
+ "udhar":"\u296E",
+ "ufisht":"\u297E",
+ "Ufr":"\uD835\uDD18",
+ "ufr":"\uD835\uDD32",
+ "Ugrave":"\u00D9",
+ "ugrave":"\u00F9",
+ "uHar":"\u2963",
+ "uharl":"\u21BF",
+ "uharr":"\u21BE",
+ "uhblk":"\u2580",
+ "ulcorn":"\u231C",
+ "ulcorner":"\u231C",
+ "ulcrop":"\u230F",
+ "ultri":"\u25F8",
+ "Umacr":"\u016A",
+ "umacr":"\u016B",
+ "uml":"\u00A8",
+ "UnderBar":"\u005F",
+ "UnderBrace":"\u23DF",
+ "UnderBracket":"\u23B5",
+ "UnderParenthesis":"\u23DD",
+ "Union":"\u22C3",
+ "UnionPlus":"\u228E",
+ "Uogon":"\u0172",
+ "uogon":"\u0173",
+ "Uopf":"\uD835\uDD4C",
+ "uopf":"\uD835\uDD66",
+ "UpArrow":"\u2191",
+ "Uparrow":"\u21D1",
+ "uparrow":"\u2191",
+ "UpArrowBar":"\u2912",
+ "UpArrowDownArrow":"\u21C5",
+ "UpDownArrow":"\u2195",
+ "Updownarrow":"\u21D5",
+ "updownarrow":"\u2195",
+ "UpEquilibrium":"\u296E",
+ "upharpoonleft":"\u21BF",
+ "upharpoonright":"\u21BE",
+ "uplus":"\u228E",
+ "UpperLeftArrow":"\u2196",
+ "UpperRightArrow":"\u2197",
+ "Upsi":"\u03D2",
+ "upsi":"\u03C5",
+ "upsih":"\u03D2",
+ "Upsilon":"\u03A5",
+ "upsilon":"\u03C5",
+ "UpTee":"\u22A5",
+ "UpTeeArrow":"\u21A5",
+ "upuparrows":"\u21C8",
+ "urcorn":"\u231D",
+ "urcorner":"\u231D",
+ "urcrop":"\u230E",
+ "Uring":"\u016E",
+ "uring":"\u016F",
+ "urtri":"\u25F9",
+ "Uscr":"\uD835\uDCB0",
+ "uscr":"\uD835\uDCCA",
+ "utdot":"\u22F0",
+ "Utilde":"\u0168",
+ "utilde":"\u0169",
+ "utri":"\u25B5",
+ "utrif":"\u25B4",
+ "uuarr":"\u21C8",
+ "Uuml":"\u00DC",
+ "uuml":"\u00FC",
+ "uwangle":"\u29A7",
+ "vangrt":"\u299C",
+ "varepsilon":"\u03F5",
+ "varkappa":"\u03F0",
+ "varnothing":"\u2205",
+ "varphi":"\u03D5",
+ "varpi":"\u03D6",
+ "varpropto":"\u221D",
+ "vArr":"\u21D5",
+ "varr":"\u2195",
+ "varrho":"\u03F1",
+ "varsigma":"\u03C2",
+ "varsubsetneq":"\u228A\uFE00",
+ "varsubsetneqq":"\u2ACB\uFE00",
+ "varsupsetneq":"\u228B\uFE00",
+ "varsupsetneqq":"\u2ACC\uFE00",
+ "vartheta":"\u03D1",
+ "vartriangleleft":"\u22B2",
+ "vartriangleright":"\u22B3",
+ "Vbar":"\u2AEB",
+ "vBar":"\u2AE8",
+ "vBarv":"\u2AE9",
+ "Vcy":"\u0412",
+ "vcy":"\u0432",
+ "VDash":"\u22AB",
+ "Vdash":"\u22A9",
+ "vDash":"\u22A8",
+ "vdash":"\u22A2",
+ "Vdashl":"\u2AE6",
+ "Vee":"\u22C1",
+ "vee":"\u2228",
+ "veebar":"\u22BB",
+ "veeeq":"\u225A",
+ "vellip":"\u22EE",
+ "Verbar":"\u2016",
+ "verbar":"\u007C",
+ "Vert":"\u2016",
+ "vert":"\u007C",
+ "VerticalBar":"\u2223",
+ "VerticalLine":"\u007C",
+ "VerticalSeparator":"\u2758",
+ "VerticalTilde":"\u2240",
+ "VeryThinSpace":"\u200A",
+ "Vfr":"\uD835\uDD19",
+ "vfr":"\uD835\uDD33",
+ "vltri":"\u22B2",
+ "vnsub":"\u2282\u20D2",
+ "vnsup":"\u2283\u20D2",
+ "Vopf":"\uD835\uDD4D",
+ "vopf":"\uD835\uDD67",
+ "vprop":"\u221D",
+ "vrtri":"\u22B3",
+ "Vscr":"\uD835\uDCB1",
+ "vscr":"\uD835\uDCCB",
+ "vsubnE":"\u2ACB\uFE00",
+ "vsubne":"\u228A\uFE00",
+ "vsupnE":"\u2ACC\uFE00",
+ "vsupne":"\u228B\uFE00",
+ "Vvdash":"\u22AA",
+ "vzigzag":"\u299A",
+ "Wcirc":"\u0174",
+ "wcirc":"\u0175",
+ "wedbar":"\u2A5F",
+ "Wedge":"\u22C0",
+ "wedge":"\u2227",
+ "wedgeq":"\u2259",
+ "weierp":"\u2118",
+ "Wfr":"\uD835\uDD1A",
+ "wfr":"\uD835\uDD34",
+ "Wopf":"\uD835\uDD4E",
+ "wopf":"\uD835\uDD68",
+ "wp":"\u2118",
+ "wr":"\u2240",
+ "wreath":"\u2240",
+ "Wscr":"\uD835\uDCB2",
+ "wscr":"\uD835\uDCCC",
+ "xcap":"\u22C2",
+ "xcirc":"\u25EF",
+ "xcup":"\u22C3",
+ "xdtri":"\u25BD",
+ "Xfr":"\uD835\uDD1B",
+ "xfr":"\uD835\uDD35",
+ "xhArr":"\u27FA",
+ "xharr":"\u27F7",
+ "Xi":"\u039E",
+ "xi":"\u03BE",
+ "xlArr":"\u27F8",
+ "xlarr":"\u27F5",
+ "xmap":"\u27FC",
+ "xnis":"\u22FB",
+ "xodot":"\u2A00",
+ "Xopf":"\uD835\uDD4F",
+ "xopf":"\uD835\uDD69",
+ "xoplus":"\u2A01",
+ "xotime":"\u2A02",
+ "xrArr":"\u27F9",
+ "xrarr":"\u27F6",
+ "Xscr":"\uD835\uDCB3",
+ "xscr":"\uD835\uDCCD",
+ "xsqcup":"\u2A06",
+ "xuplus":"\u2A04",
+ "xutri":"\u25B3",
+ "xvee":"\u22C1",
+ "xwedge":"\u22C0",
+ "Yacute":"\u00DD",
+ "yacute":"\u00FD",
+ "YAcy":"\u042F",
+ "yacy":"\u044F",
+ "Ycirc":"\u0176",
+ "ycirc":"\u0177",
+ "Ycy":"\u042B",
+ "ycy":"\u044B",
+ "yen":"\u00A5",
+ "Yfr":"\uD835\uDD1C",
+ "yfr":"\uD835\uDD36",
+ "YIcy":"\u0407",
+ "yicy":"\u0457",
+ "Yopf":"\uD835\uDD50",
+ "yopf":"\uD835\uDD6A",
+ "Yscr":"\uD835\uDCB4",
+ "yscr":"\uD835\uDCCE",
+ "YUcy":"\u042E",
+ "yucy":"\u044E",
+ "Yuml":"\u0178",
+ "yuml":"\u00FF",
+ "Zacute":"\u0179",
+ "zacute":"\u017A",
+ "Zcaron":"\u017D",
+ "zcaron":"\u017E",
+ "Zcy":"\u0417",
+ "zcy":"\u0437",
+ "Zdot":"\u017B",
+ "zdot":"\u017C",
+ "zeetrf":"\u2128",
+ "ZeroWidthSpace":"\u200B",
+ "Zeta":"\u0396",
+ "zeta":"\u03B6",
+ "Zfr":"\u2128",
+ "zfr":"\uD835\uDD37",
+ "ZHcy":"\u0416",
+ "zhcy":"\u0436",
+ "zigrarr":"\u21DD",
+ "Zopf":"\u2124",
+ "zopf":"\uD835\uDD6B",
+ "Zscr":"\uD835\uDCB5",
+ "zscr":"\uD835\uDCCF",
+ "zwj":"\u200D",
+ "zwnj":"\u200C"
+};
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
index 7b3d16e..5e38c2d 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
@@ -18,6 +18,12 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown.helpers
{
+ /**
+ *
+ * @langversion 3.0
+ * @productversion Royale 0.9.9
+ * @royalesuppressexport
+ */
public function normalizeReference(str:String):String
{
return str.trim().replace(/\s+/g, ' ').toUpperCase();
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/parseLinkDestination.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/parseLinkDestination.as
new file mode 100644
index 0000000..03bc52b
--- /dev/null
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/parseLinkDestination.as
@@ -0,0 +1,102 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.royale.markdown.helpers
+{
+ import org.apache.royale.markdown.InlineState;
+ import org.apache.royale.utils.string.sanitizeUrl;
+
+ /**
+ *
+ * @langversion 3.0
+ * @productversion Royale 0.9.9
+ * @royalesuppressexport
+ */
+ public function parseLinkDestination(state:InlineState, pos:int):Boolean
+ {
+ // var code, level, link,
+ var start:int = pos;
+ var max:int = state.posMax;
+
+ if (state.src.charCodeAt(pos) === 0x3C /* < */) {
+ pos++;
+ while (pos < max) {
+ var code:Number = state.src.charCodeAt(pos);
+ if (code === 0x0A /* \n */) { return false; }
+ if (code === 0x3E /* > */) {
+ var link:String = normalizeLink(unescapeMd(state.src.slice(start + 1, pos)));
+ if(sanitizeUrl(link) != link)
+ return false;
+ // if (!state.parser.validateLink(link)) { return false; }
+ state.position = pos + 1;
+ state.linkContent = link;
+ return true;
+ }
+ if (code === 0x5C /* \ */ && pos + 1 < max) {
+ pos += 2;
+ continue;
+ }
+
+ pos++;
+ }
+
+ // no closing '>'
+ return false;
+ }
+
+ // this should be ... } else { ... branch
+
+ var level:int = 0;
+ while (pos < max) {
+ code = state.src.charCodeAt(pos);
+
+ if (code === 0x20) { break; }
+
+ // ascii control chars
+ if (code < 0x20 || code === 0x7F) { break; }
+
+ if (code === 0x5C /* \ */ && pos + 1 < max) {
+ pos += 2;
+ continue;
+ }
+
+ if (code === 0x28 /* ( */) {
+ level++;
+ if (level > 1) { break; }
+ }
+
+ if (code === 0x29 /* ) */) {
+ level--;
+ if (level < 0) { break; }
+ }
+
+ pos++;
+ }
+
+ if (start === pos) { return false; }
+
+ link = unescapeMd(state.src.slice(start, pos));
+ if(!link != sanitizeUrl(link))
+ return false;
+ // if (!state.parser.validateLink(link)) { return false; }
+
+ state.linkContent = link;
+ state.position = pos;
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/parseLinkLabel.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/parseLinkLabel.as
new file mode 100644
index 0000000..407059c
--- /dev/null
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/parseLinkLabel.as
@@ -0,0 +1,76 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.royale.markdown.helpers
+{
+ import org.apache.royale.markdown.InlineState;
+
+ /**
+ *
+ * @langversion 3.0
+ * @productversion Royale 0.9.9
+ * @royalesuppressexport
+ */
+ public function parseLinkLabel(state:InlineState, start:int):int
+ {
+ var found:Boolean;
+ var labelEnd:int = -1;
+ var max:int = state.posMax;
+ var oldPos:int = state.position;
+ var oldFlag:Boolean = state.isInLabel;
+
+ if (state.isInLabel) { return -1; }
+
+ if (state.labelUnmatchedScopes) {
+ state.labelUnmatchedScopes--;
+ return -1;
+ }
+
+ state.position = start + 1;
+ state.isInLabel = true;
+ var level:int = 1;
+
+ while (state.position < max) {
+ var marker:Number = state.src.charCodeAt(state.position);
+ if (marker === 0x5B /* [ */) {
+ level++;
+ } else if (marker === 0x5D /* ] */) {
+ level--;
+ if (level === 0) {
+ found = true;
+ break;
+ }
+ }
+
+ state.parser.skipToken(state);
+ }
+
+ if (found) {
+ labelEnd = state.position;
+ state.labelUnmatchedScopes = 0;
+ } else {
+ state.labelUnmatchedScopes = level - 1;
+ }
+
+ // restore old state
+ state.position = oldPos;
+ state.isInLabel = oldFlag;
+
+ return labelEnd;
+ }
+}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/parseLinkTitle.as
similarity index 53%
copy from frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
copy to frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/parseLinkTitle.as
index 7b3d16e..ee82a5e 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/parseLinkTitle.as
@@ -18,8 +18,43 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown.helpers
{
- public function normalizeReference(str:String):String
+ import org.apache.royale.markdown.InlineState;
+
+ /**
+ *
+ * @langversion 3.0
+ * @productversion Royale 0.9.9
+ * @royalesuppressexport
+ */
+ public function parseLinkTitle(state:InlineState, pos:int):Boolean
{
- return str.trim().replace(/\s+/g, ' ').toUpperCase();
+ // var code,
+ var start:int = pos;
+ var max:int = state.posMax;
+ var marker:Number = state.src.charCodeAt(pos);
+
+ if (marker !== 0x22 /* " */ && marker !== 0x27 /* ' */ && marker !== 0x28 /* ( */) { return false; }
+
+ pos++;
+
+ // if opening marker is "(", switch it to closing marker ")"
+ if (marker === 0x28) { marker = 0x29; }
+
+ while (pos < max) {
+ var code:Number = state.src.charCodeAt(pos);
+ if (code === marker) {
+ state.position = pos + 1;
+ state.linkContent = unescapeMd(state.src.slice(start + 1, pos));
+ return true;
+ }
+ if (code === 0x5C /* \ */ && pos + 1 < max) {
+ pos += 2;
+ continue;
+ }
+
+ pos++;
+ }
+
+ return false;
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/unescapeMd.as
similarity index 73%
copy from frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
copy to frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/unescapeMd.as
index 7b3d16e..476f1c6 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/unescapeMd.as
@@ -18,8 +18,17 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown.helpers
{
- public function normalizeReference(str:String):String
- {
- return str.trim().replace(/\s+/g, ' ').toUpperCase();
+ import org.apache.royale.markdown.InlineState;
+
+ /**
+ *
+ * @langversion 3.0
+ * @productversion Royale 0.9.9
+ * @royalesuppressexport
+ */
+ public function unescapeMd(str:String):String {
+ if (str.indexOf('\\') < 0) { return str; }
+ return str.replace(UNESCAPE_MD_RE, '$1');
}
-}
\ No newline at end of file
+}
+internal const UNESCAPE_MD_RE:RegExp = /\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g;
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/wrappedInParagraph.as
similarity index 69%
copy from frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
copy to frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/wrappedInParagraph.as
index 7b3d16e..623e576 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/normalizeReference.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/helpers/wrappedInParagraph.as
@@ -18,8 +18,21 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown.helpers
{
- public function normalizeReference(str:String):String
- {
- return str.trim().replace(/\s+/g, ' ').toUpperCase();
- }
+ import org.apache.royale.markdown.IToken;
+ import org.apache.royale.markdown.TagToken;
+ import org.apache.royale.markdown.ContentToken;
+
+ /**
+ *
+ * @langversion 3.0
+ * @productversion Royale 0.9.9
+ * @royalesuppressexport
+ */
+ public function wrappedInParagraph(first:IToken,second:IToken,third:IToken):Boolean
+ {
+ return first.type == 'paragraph_open' &&
+ second.type == 'inline' &&
+ third.type == 'paragraph_close';
+
+ }
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/RulesManager.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/RulesManager.as
index 55641ea..a57200d 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/RulesManager.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/RulesManager.as
@@ -27,7 +27,7 @@ package org.apache.royale.markdown
* @langversion 3.0
* @productversion Royale 0.9.9
*/
- public static function enableAll():void
+ public function enableAll():void
{
var coreRules:Array = ['block','abbr','references','inline','footnote_tail',
'abbr2','replacements','smartquotes'];
@@ -51,7 +51,7 @@ package org.apache.royale.markdown
* @langversion 3.0
* @productversion Royale 0.9.9
*/
- public static function enableStandard():void
+ public function enableStandard():void
{
var coreRules:Array = ['block','references','inline','footnote_tail','abbr2','replacements','smartquotes'];
var blockRules:Array = ['code','fences','blockquote','hr','list','footnote',
@@ -74,7 +74,7 @@ package org.apache.royale.markdown
* @langversion 3.0
* @productversion Royale 0.9.9
*/
- public static function enableCommonMark():void
+ public function enableCommonMark():void
{
var coreRules:Array = ['block','references','inline','abbr2'];
var blockRules:Array = ['code','fences','blockquote','hr','list','heading','htmlblock','paragraph'];
@@ -90,20 +90,20 @@ package org.apache.royale.markdown
}
- private static function checkCore(toCheck:Array):Boolean
+ private function checkCore(toCheck:Array):Boolean
{
return arraysMatch(toCheck,enabledCoreRules);
}
- private static function checkBlock(toCheck:Array):Boolean
+ private function checkBlock(toCheck:Array):Boolean
{
return arraysMatch(toCheck,enabledBlockRules);
}
- private static function checkInline(toCheck:Array):Boolean
+ private function checkInline(toCheck:Array):Boolean
{
return arraysMatch(toCheck,enabledInlineRules);
}
- public static function disableRule(name:String):void
+ public function disableRule(name:String):void
{
if(enabledCoreRules.indexOf(name) != -1)
{
@@ -122,17 +122,17 @@ package org.apache.royale.markdown
}
}
- private static var enabledCoreRules:Array;
- private static var enabledBlockRules:Array;
- private static var enabledInlineRules:Array;
+ private var enabledCoreRules:Array;
+ private var enabledBlockRules:Array;
+ private var enabledInlineRules:Array;
- private static var coreRules:Vector.<IRule>;
- private static var blockRules:Vector.<IRule>;
- private static var inlineRules:Vector.<IRule>;
+ private var coreRules:Vector.<IRule>;
+ private var blockRules:Vector.<IRule>;
+ private var inlineRules:Vector.<IRule>;
- private static var paragraphRules:Vector.<IRule>;
- private static var blockquoteRules:Vector.<IRule>;
- private static var listRules:Vector.<IRule>;
+ private var paragraphRules:Vector.<IRule>;
+ private var blockquoteRules:Vector.<IRule>;
+ private var listRules:Vector.<IRule>;
/**
*
@@ -181,8 +181,8 @@ Inline
*/
- private static var initialized:Boolean = false;
- private static function initialize():void
+ private var initialized:Boolean = false;
+ private function initialize():void
{
initialized = true;
coreRules = new Vector.<IRule>();
@@ -349,14 +349,14 @@ Inline
}
}
}
- private static function getCoreRules():Vector.<IRule>
+ private function getCoreRules():Vector.<IRule>
{
if(!coreRules)
initialize();
return coreRules;
}
- public static function runCoreRules(state:CoreState):void
+ public function runCoreRules(state:CoreState):void
{
if(!initialized)
initialize();
@@ -368,10 +368,87 @@ Inline
}
}
+ private function getBlockRules():Vector.<IRule>
+ {
+ if(!blockRules)
+ initialize();
+
+ return blockRules;
+ }
+ public function runBlockRules(state:BlockState,silent:Boolean,firstLine:int,lastLine:int):Boolean
+ {
+ var rules:Vector.<IRule> = getBlockRules();
+ for each(var rule:IRule in rules)
+ {
+ if(rule.parse(state,silent,firstLine,lastLine))
+ return true;
+ }
+ return false;
+ }
+
+ public function getInlineRules():Vector.<IRule>
+ {
+ if(!inlineRules)
+ initialize();
+
+ return inlineRules;
+ }
+ public function runInlineRules(state:InlineState,silent:Boolean,position:int):Boolean
+ {
+ var rules:Vector.<IRule> = getInlineRules();
+ for each(var rule:IRule in rules)
+ {
+ if(rule.parse(state,silent))
+ {
+ if(silent)
+ state.cacheSet(position, state.position);
+
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public function runBlockquotes(state:BlockState,firstLine:int,lastLine:int):Boolean
+ {
+ var rules:Vector.<IRule> = blockquoteRules;
+ for each(var rule:IRule in rules)
+ {
+ if (rule.parse(state,true, firstLine, lastLine))
+ return true;
+ }
+ return false;
+ }
+
+ public function runLists(state:BlockState,firstLine:int,lastLine:int):Boolean
+ {
+ var rules:Vector.<IRule> = listRules;
+ for each(var rule:IRule in rules)
+ {
+ if (rule.parse(state,true, firstLine, lastLine))
+ return true;
+ }
+ return false;
+ }
+
+ public function runParagraphs(state:BlockState,firstLine:int,lastLine:int):Boolean
+ {
+ var rules:Vector.<IRule> = paragraphRules;
+ for each(var rule:IRule in rules)
+ {
+ if (rule.parse(state,true, firstLine, lastLine))
+ return true;
+ }
+ return false;
+ }
+
+ public var options:MarkdownOptions;
/**
- * RulesManager is a static-only class
+ * Each Parser needs a RulesManager which holds the current set of rules
*/
- private function RulesManager(){}
+ public function RulesManager(){
+ options = new MarkdownOptions();
+ }
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/BlockQuote.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/BlockQuote.as
index c497158..093d57e 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/BlockQuote.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/BlockQuote.as
@@ -37,13 +37,153 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ *
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(iState:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
- }
+ var state:BlockState = iState as BlockState;
+ // var nextLine, lastLineEmpty, oldTShift, oldBMarks, oldIndent, oldParentType, lines,
+ // terminatorRules,
+ // i, l, terminate;
+ var pos:int = state.bMarks[startLine] + state.tShift[startLine];
+ var max:int = state.eMarks[startLine];
+
+ if (pos > max) { return false; }
+
+ // check the block quote marker
+ if (state.src.charCodeAt(pos++) !== 0x3E/* > */) { return false; }
+
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ // we know that it's going to be a valid blockquote,
+ // so no point trying to find the end of it in silent mode
+ if (silent) { return true; }
+
+ // skip one optional space after '>'
+ if (state.src.charCodeAt(pos) === 0x20) { pos++; }
+
+ var oldIndent:int = state.blkIndent;
+ state.blkIndent = 0;
+
+ var oldBMarks:Array = [ state.bMarks[startLine] ];
+ state.bMarks[startLine] = pos;
+
+ // check if we have an empty blockquote
+ pos = pos < max ? state.skipSpaces(pos) : pos;
+ var lastLineEmpty:Boolean = pos >= max;
+
+ var oldTShift:Array = [ state.tShift[startLine] ];
+ state.tShift[startLine] = pos - state.bMarks[startLine];
+
+ // terminatorRules = state.parser.ruler.getRules('blockquote');
+
+ // Search the end of the block
+ //
+ // Block ends with either:
+ // 1. an empty line outside:
+ // ```
+ // > test
+ //
+ // ```
+ // 2. an empty line inside:
+ // ```
+ // >
+ // test
+ // ```
+ // 3. another tag
+ // ```
+ // > test
+ // - - -
+ // ```
+ for (var nextLine:int = startLine + 1; nextLine < endLine; nextLine++) {
+ pos = state.bMarks[nextLine] + state.tShift[nextLine];
+ max = state.eMarks[nextLine];
+
+ if (pos >= max) {
+ // Case 1: line is not inside the blockquote, and this line is empty.
+ break;
+ }
+ if (state.src.charCodeAt(pos++) === 0x3E/* > */) {
+ // This line is inside the blockquote.
+
+ // skip one optional space after '>'
+ if (state.src.charCodeAt(pos) === 0x20) { pos++; }
+
+ oldBMarks.push(state.bMarks[nextLine]);
+ state.bMarks[nextLine] = pos;
+
+ pos = pos < max ? state.skipSpaces(pos) : pos;
+ lastLineEmpty = pos >= max;
+
+ oldTShift.push(state.tShift[nextLine]);
+ state.tShift[nextLine] = pos - state.bMarks[nextLine];
+ continue;
+ }
+
+ // Case 2: line is not inside the blockquote, and the last line was empty.
+ if (lastLineEmpty) { break; }
+
+ // Case 3: another tag found.
+ if(state.parser.rules.runBlockquotes(state,nextLine,endLine))
+ break;
+
+ // terminate = false;
+ // for (i = 0, l = terminatorRules.length; i < l; i++) {
+ // if (terminatorRules[i](state, nextLine, endLine, true)) {
+ // terminate = true;
+ // break;
+ // }
+ // }
+ // if (terminate) { break; }
+
+ oldBMarks.push(state.bMarks[nextLine]);
+ oldTShift.push(state.tShift[nextLine]);
+
+ // A negative number means that this is a paragraph continuation;
+ //
+ // Any negative number will do the job here, but it's better for it
+ // to be large enough to make any bugs obvious.
+ state.tShift[nextLine] = -1337;
+ }
+
+ var oldParentType:String = state.parentType;
+ state.parentType = 'blockquote';
+ //TODO why does blockquote_open have lines?
+ var token:BlockToken = new BlockToken('blockquote_open','');
+ token.firstLine = startLine;
+ //set further down when the tag is closed
+ // token.lastLine = 0;
+ token.level = state.level++;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'blockquote_open',
+ // lines: lines = [ startLine, 0 ],
+ // level: state.level++
+ // });
+ state.parser.tokenize(state, startLine, nextLine);
+ var closeToken:TagToken = new TagToken('blockquote_close');
+ closeToken.level = --state.level;
+ state.tokens.push(closeToken);
+ // state.tokens.push({
+ // type: 'blockquote_close',
+ // level: --state.level
+ // });
+ state.parentType = oldParentType;
+ token.lastLine = state.line;
+ // lines[1] = state.line;
+
+ // Restore original tShift; this might not be necessary since the parser
+ // has already been here, but just to make sure we can do that.
+ for (var i:int = 0; i < oldTShift.length; i++) {
+ state.bMarks[i + startLine] = oldBMarks[i];
+ state.tShift[i + startLine] = oldTShift[i];
+ }
+ state.blkIndent = oldIndent;
+
+ return true;
+ }
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Code.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Code.as
index eed649b..204ad72 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Code.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Code.as
@@ -36,11 +36,47 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:BlockState = istate as BlockState;
+
+ // var nextLine, last;
+
+ if (state.tShift[startLine] - state.blkIndent < 4) { return false; }
+ var nextLine:int;
+ var last:int = nextLine = startLine + 1;
+
+ while (nextLine < endLine) {
+ if (state.isEmpty(nextLine)) {
+ nextLine++;
+ continue;
+ }
+ if (state.tShift[nextLine] - state.blkIndent >= 4) {
+ nextLine++;
+ last = nextLine;
+ continue;
+ }
+ break;
+ }
+
+ state.line = nextLine;
+ var token:BlockToken = new BlockToken("code",state.getLines(startLine, last, 4 + state.blkIndent, true));
+ token.firstLine = startLine;
+ token.lastLine = state.line;
+ token.level = state.level;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'code',
+ // content: state.getLines(startLine, last, 4 + state.blkIndent, true),
+ // block: true,
+ // lines: [ startLine, state.line ],
+ // level: state.level
+ // });
+
+ return true;
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Deflist.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Deflist.as
index 8482377..dbbc91e 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Deflist.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Deflist.as
@@ -34,14 +34,262 @@ package org.apache.royale.markdown
return _instance;
}
+ // Search `[:~][\n ]`, returns next pos after marker on success
+ // or -1 on fail.
+ private function skipMarker(state:BlockState, line:int):int
+ {
+ var start:int = state.bMarks[line] + state.tShift[line];
+ var max:int = state.eMarks[line];
+
+ if (start >= max) { return -1; }
+
+ // Check bullet
+ var marker:Number = state.src.charCodeAt(start++);
+ if (marker !== 0x7E/* ~ */ && marker !== 0x3A/* : */) { return -1; }
+
+ var pos:int = state.skipSpaces(start);
+
+ // require space after ":"
+ if (start === pos) { return -1; }
+
+ // no empty definitions, e.g. " : "
+ if (pos >= max) { return -1; }
+
+ return pos;
+ }
+
+ private function markTightParagraphs(state:BlockState, idx:int):void
+ {
+ // var i, l,
+ var level:int = state.level + 2;
+ var len:int = state.tokens.length - 2;
+ for (var i:int = idx + 2; i < len; i++) {
+ if (state.tokens[i].level === level && state.tokens[i].type === 'paragraph_open') {
+ state.tokens[i + 2].tight = true;
+ state.tokens[i].tight = true;
+ i += 2;
+ }
+ }
+ }
+
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var contentStart,
+ // ddLine,
+ // dtLine,
+ // itemLines,
+ // listLines,
+ // listTokIdx,
+ // nextLine,
+ // oldIndent,
+ // oldDDIndent,
+ // oldParentType,
+ // oldTShift,
+ // oldTight,
+ // prevEmptyEnd,
+ // tight;
+
+ var state:BlockState = istate as BlockState;
+ if (silent) {
+ // quirk: validation mode validates a dd block only, not a whole deflist
+ if (state.ddIndent < 0) { return false; }
+ return skipMarker(state, startLine) >= 0;
+ }
+
+ nextLine = startLine + 1;
+ if (state.isEmpty(nextLine)) {
+ if (++nextLine > endLine) { return false; }
+ }
+
+ if (state.tShift[nextLine] < state.blkIndent) { return false; }
+ var contentStart:int = skipMarker(state, nextLine);
+ if (contentStart < 0) { return false; }
+
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ // Start list
+ var listTokIdx:int = state.tokens.length;
+
+ var token:BlockToken = new BlockToken('dl_open','');
+ token.firstLine = startLine;
+ token.level = state.level++;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'dl_open',
+ // lines: listLines = [ startLine, 0 ],
+ // level: state.level++
+ // });
+
+ //
+ // Iterate list items
+ //
+
+ this.startLine = startLine;
+ this.endLine = endLine;
+
+ loopDT(state,contentStart);
+
+ // Finalize list
+ token.lastLine = nextLine;
+ // listLines[1] = nextLine;
+ var tToken:TagToken = new TagToken('dl_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({
+ // type: 'dl_close',
+ // level: --state.level
+ // });
+
+ state.line = nextLine;
+
+ // mark paragraphs tight if needed
+ if (tight) {
+ markTightParagraphs(state, listTokIdx);
+ }
+
+ return true;
+
+ }
+ private var nextLine:int;
+ private var startLine:int;
+ private var endLine:int;
+ private var tight:Boolean;
+ private function loopDT(state:BlockState,contentStart:int):void
+ {
+ var dtLine:int = startLine;
+ var ddLine:int = nextLine;
+
+ // One definition list can contain multiple DTs,
+ // and one DT can be followed by multiple DDs.
+ //
+ // Thus, there is two loops here.
+ //
+ for (;;) {
+ tight = true;
+ var prevEmptyEnd:Boolean = false;
+ var token:BlockToken = new BlockToken('dt_open','');
+ token.firstLine = dtLine;
+ token.lastLine = dtLine;
+ token.level = state.level++;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'dt_open',
+ // lines: [ dtLine, dtLine ],
+ // level: state.level++
+ // });
+
+ token = new BlockToken('inline',state.getLines(dtLine, dtLine + 1, state.blkIndent, false).trim());
+ token.firstLine = dtLine;
+ token.lastLine = dtLine;
+ token.level = state.level + 1;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'inline',
+ // content: state.getLines(dtLine, dtLine + 1, state.blkIndent, false).trim(),
+ // level: state.level + 1,
+ // lines: [ dtLine, dtLine ],
+ // children: []
+ // });
+ var tToken:TagToken = new TagToken('dt_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({
+ // type: 'dt_close',
+ // level: --state.level
+ // });
+
+ for (;;) {
+ var lineToken:BlockToken = new BlockToken('dd_open','');
+ lineToken.firstLine = nextLine;
+ lineToken.level = state.level++;
+ state.tokens.push(lineToken);
+ // state.tokens.push({
+ // type: 'dd_open',
+ // lines: itemLines = [ nextLine, 0 ],
+ // level: state.level++
+ // });
+
+ var oldTight:Boolean = state.tight;
+ var oldDDIndent:int = state.ddIndent;
+ var oldIndent:int = state.blkIndent;
+ var oldTShift:int = state.tShift[ddLine];
+ var oldParentType:String = state.parentType;
+ state.blkIndent = state.ddIndent = state.tShift[ddLine] + 2;
+ state.tShift[ddLine] = contentStart - state.bMarks[ddLine];
+ state.tight = true;
+ state.parentType = 'deflist';
+
+ state.parser.tokenize(state, ddLine, endLine);// had, true....
+
+ // If any of list item is tight, mark list as tight
+ if (!state.tight || prevEmptyEnd) {
+ tight = false;
+ }
+ // Item become loose if finish with empty line,
+ // but we should filter last element, because it means list finish
+ prevEmptyEnd = (state.line - ddLine) > 1 && state.isEmpty(state.line - 1);
+
+ state.tShift[ddLine] = oldTShift;
+ state.tight = oldTight;
+ state.parentType = oldParentType;
+ state.blkIndent = oldIndent;
+ state.ddIndent = oldDDIndent;
+
+ tToken = new TagToken('dd_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({
+ // type: 'dd_close',
+ // level: --state.level
+ // });
+
+ lineToken.lastLine = nextLine = state.line;
+
+ if (nextLine >= endLine)
+ {
+ return;
+ }
+
+ if (state.tShift[nextLine] < state.blkIndent)
+ {
+ return;
+ }
+
+ contentStart = skipMarker(state, nextLine);
+ if (contentStart < 0) { break; }
+
+ ddLine = nextLine;
+
+ // go to the next loop iteration:
+ // insert DD tag and repeat checking
+ }
+
+ if (nextLine >= endLine) { break; }
+ dtLine = nextLine;
+
+ if (state.isEmpty(dtLine)) { break; }
+ if (state.tShift[dtLine] < state.blkIndent) { break; }
+
+ ddLine = dtLine + 1;
+ if (ddLine >= endLine) { break; }
+ if (state.isEmpty(ddLine)) { ddLine++; }
+ if (ddLine >= endLine) { break; }
+
+ if (state.tShift[ddLine] < state.blkIndent) { break; }
+ contentStart = skipMarker(state, ddLine);
+ if (contentStart < 0) { break; }
+
+ // go to the next loop iteration:
+ // insert DT and DD tags and repeat checking
+ }
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Fences.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Fences.as
index efa7d4b..870248a 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Fences.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Fences.as
@@ -37,11 +37,107 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var marker, len, params, nextLine, mem,
+ var state:BlockState = istate as BlockState;
+ var haveEndMarker:Boolean = false;
+ var pos:int = state.bMarks[startLine] + state.tShift[startLine];
+ var max:int = state.eMarks[startLine];
+
+ if (pos + 3 > max) { return false; }
+
+ var marker:Number = state.src.charCodeAt(pos);
+
+ if (marker !== 0x7E/* ~ */ && marker !== 0x60 /* ` */) {
+ return false;
+ }
+
+ // scan marker length
+ var mem:int = pos;
+ pos = state.skipChars(pos, marker);
+
+ var len:int = pos - mem;
+
+ if (len < 3) { return false; }
+
+ var params:String = state.src.slice(pos, max).trim();
+
+ if (params.indexOf('`') >= 0) { return false; }
+
+ // Since start is found, we can report success here in validation mode
+ if (silent) { return true; }
+
+ // search end of block
+ var nextLine:int = startLine;
+
+ // break out of endless loop when we hit the end
+ for (;;) {
+ nextLine++;
+ if (nextLine >= endLine) {
+ // unclosed block should be autoclosed by end of document.
+ // also block seems to be autoclosed by end of parent
+ break;
+ }
+
+ pos = mem = state.bMarks[nextLine] + state.tShift[nextLine];
+ max = state.eMarks[nextLine];
+
+ if (pos < max && state.tShift[nextLine] < state.blkIndent) {
+ // non-empty line with negative indent should stop the list:
+ // - ```
+ // test
+ break;
+ }
+
+ if (state.src.charCodeAt(pos) !== marker) { continue; }
+
+ if (state.tShift[nextLine] - state.blkIndent >= 4) {
+ // closing fence should be indented less than 4 spaces
+ continue;
+ }
+
+ pos = state.skipChars(pos, marker);
+
+ // closing code fence must be at least as long as the opening one
+ if (pos - mem < len) { continue; }
+
+ // make sure tail has spaces only
+ pos = state.skipSpaces(pos);
+
+ if (pos < max) { continue; }
+
+ haveEndMarker = true;
+ // found!
+ break;
+ }
+
+ // If a fence has heading spaces, they should be removed from its inner block
+ len = state.tShift[startLine];
+
+ state.line = nextLine + (haveEndMarker ? 1 : 0);
+ var token:BlockToken = new BlockToken('fence',state.getLines(startLine + 1, nextLine, len, true));
+ // for fences we're using the data property for the fence params
+ token.data = params;
+ token.firstLine = startLine;
+ token.lastLine = state.line;
+ token.level = state.level;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'fence',
+ // params: params,
+ // content: state.getLines(startLine + 1, nextLine, len, true),
+ // lines: [ startLine, state.line ],
+ // level: state.level
+ // });
+
+ return true;
+
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Footnote.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Footnote.as
index 1535cbc..3531463 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Footnote.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Footnote.as
@@ -37,11 +37,80 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var oldBMark, oldTShift, oldParentType, pos, label,
+ var state:BlockState = istate as BlockState
+ var start:int = state.bMarks[startLine] + state.tShift[startLine];
+ var max:int = state.eMarks[startLine];
+
+ // line should be at least 5 chars - "[^x]:"
+ if (start + 4 > max) { return false; }
+
+ if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }
+ if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ for (var pos:int = start + 2; pos < max; pos++) {
+ if (state.src.charCodeAt(pos) === 0x20) { return false; }
+ if (state.src.charCodeAt(pos) === 0x5D /* ] */) {
+ break;
+ }
+ }
+
+ if (pos === start + 2) { return false; } // no empty footnote labels
+ if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A /* : */) { return false; }
+ if (silent) { return true; }
+ pos++;
+
+ if (!state.env.footnotes) { state.env.footnotes = {}; }
+ if (!state.env.footnotes.refs) { state.env.footnotes.refs = {}; }
+ var label:String = state.src.slice(start + 2, pos - 2);
+ state.env.footnotes.refs[label] = -1;
+
+ var tToken:TagToken = new TagToken('footnote_reference_open');
+ tToken.data = label;
+ tToken.level = state.level++;
+ state.tokens.push(tToken);
+ // state.tokens.push({
+ // type: 'footnote_reference_open',
+ // label: label,
+ // level: state.level++
+ // });
+
+ var oldBMark:int = state.bMarks[startLine];
+ var oldTShift:int = state.tShift[startLine];
+ var oldParentType:String = state.parentType;
+ state.tShift[startLine] = state.skipSpaces(pos) - pos;
+ state.bMarks[startLine] = pos;
+ state.blkIndent += 4;
+ state.parentType = 'footnote';
+
+ if (state.tShift[startLine] < state.blkIndent) {
+ state.tShift[startLine] += state.blkIndent;
+ state.bMarks[startLine] -= state.blkIndent;
+ }
+
+ state.parser.tokenize(state, startLine, endLine);// had , true???
+
+ state.parentType = oldParentType;
+ state.blkIndent -= 4;
+ state.tShift[startLine] = oldTShift;
+ state.bMarks[startLine] = oldBMark;
+ tToken = new TagToken('footnote_reference_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({
+ // type: 'footnote_reference_close',
+ // level: --state.level
+ // });
+
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Heading.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Heading.as
index 82b5778..f936930 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Heading.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Heading.as
@@ -37,11 +37,81 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ var state:BlockState = istate as BlockState
+ var pos:int = state.bMarks[startLine] + state.tShift[startLine];
+ var max:int = state.eMarks[startLine];
+
+ if (pos >= max) { return false; }
+
+ var ch:Number = state.src.charCodeAt(pos);
+
+ if (ch !== 0x23/* # */ || pos >= max) { return false; }
+
+ // count heading level
+ var level:int = 1;
+ ch = state.src.charCodeAt(++pos);
+ while (ch === 0x23/* # */ && pos < max && level <= 6) {
+ level++;
+ ch = state.src.charCodeAt(++pos);
+ }
+
+ if (level > 6 || (pos < max && ch !== 0x20/* space */)) { return false; }
+
+ if (silent) { return true; }
+
+ // Let's cut tails like ' ### ' from the end of string
+
+ max = state.skipCharsBack(max, 0x20, pos); // space
+ var tmp:int = state.skipCharsBack(max, 0x23, pos); // #
+ if (tmp > pos && state.src.charCodeAt(tmp - 1) === 0x20/* space */) {
+ max = tmp;
+ }
+
+ state.line = startLine + 1;
+ // var tToken:TagToken = new TagToken('heading_open');
+ var token:BlockToken = new BlockToken('heading_open','');
+ token.numValue = level;
+ token.firstLine = startLine;
+ token.lastLine = state.line;
+ level = state.level;
+ state.tokens.push(token);
+
+ // state.tokens.push({ type: 'heading_open',
+ // hLevel: level,
+ // lines: [ startLine, state.line ],
+ // level: state.level
+ // });
+
+ // only if header is not empty
+ if (pos < max) {
+ token = new BlockToken('inline',state.src.slice(pos, max).trim());
+ token.level = state.level + 1;
+ token.firstLine = startLine;
+ token.lastLine = state.line;
+ state.tokens.push(token);
+
+ // state.tokens.push({
+ // type: 'inline',
+ // content: state.src.slice(pos, max).trim(),
+ // level: state.level + 1,
+ // lines: [ startLine, state.line ],
+ // children: []
+ // });
+ }
+ var tToken:TagToken = new TagToken('heading_close');
+ tToken.numValue = level;
+ tToken.level = state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({ type: 'heading_close', hLevel: level, level: state.level });
+
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Hr.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Hr.as
index d0abf96..78fa1a4 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Hr.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Hr.as
@@ -37,11 +37,57 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var marker, cnt, ch,
+ var state:BlockState = istate as BlockState;
+ var pos:int = state.bMarks[startLine];
+ var max:int = state.eMarks[startLine];
+
+ pos += state.tShift[startLine];
+
+ if (pos > max) { return false; }
+
+ var marker:Number = state.src.charCodeAt(pos++);
+
+ // Check hr marker
+ if (marker !== 0x2A/* * */ &&
+ marker !== 0x2D/* - */ &&
+ marker !== 0x5F/* _ */) {
+ return false;
+ }
+
+ // markers can be mixed with spaces, but there should be at least 3 one
+
+ var cnt:int = 1;
+ while (pos < max) {
+ var ch:Number = state.src.charCodeAt(pos++);
+ if (ch !== marker && ch !== 0x20/* space */) { return false; }
+ if (ch === marker) { cnt++; }
+ }
+
+ if (cnt < 3) { return false; }
+
+ if (silent) { return true; }
+
+ state.line = startLine + 1;
+ var token:BlockToken = new BlockToken('hr','');
+ token.firstLine = startLine;
+ token.lastLine = state.line;
+ token.level = state.level;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'hr',
+ // lines: [ startLine, state.line ],
+ // level: state.level
+ // });
+
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Htmlblock.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Htmlblock.as
index f943e55..fdafa02 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Htmlblock.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Htmlblock.as
@@ -34,15 +34,142 @@ package org.apache.royale.markdown
return _instance;
}
+ private const HTML_TAG_OPEN_RE:RegExp = /^<([a-zA-Z]{1,15})[\s\/>]/;
+ private const HTML_TAG_CLOSE_RE:RegExp = /^<\/([a-zA-Z]{1,15})[\s>]/;
+
+ private function isLetter(ch:Number):Boolean
+ {
+ /*eslint no-bitwise:0*/
+ var lc:Number = ch | 0x20; // to lower case
+ return (lc >= 0x61/* a */) && (lc <= 0x7a/* z */);
+ }
+
+
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var ch, match, nextLine,
+ var state:BlockState = istate as BlockState;
+ var pos:int = state.bMarks[startLine];
+ var max:int = state.eMarks[startLine];
+ var shift:int = state.tShift[startLine];
+
+ pos += shift;
+
+ if (!state.options.html) { return false; }
+
+ if (shift > 3 || pos + 2 >= max) { return false; }
+
+ if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; }
+
+ var ch:Number = state.src.charCodeAt(pos + 1);
+
+ if (ch === 0x21/* ! */ || ch === 0x3F/* ? */) {
+ // Directive start / comment start / processing instruction start
+ if (silent) { return true; }
+
+ } else if (ch === 0x2F/* / */ || isLetter(ch)) {
+
+ // Probably start or end of tag
+ if (ch === 0x2F/* \ */) {
+ // closing tag
+ var match:Array = state.src.slice(pos, max).match(HTML_TAG_CLOSE_RE);
+ if (!match) { return false; }
+ } else {
+ // opening tag
+ match = state.src.slice(pos, max).match(HTML_TAG_OPEN_RE);
+ if (!match) { return false; }
+ }
+ // Make sure tag name is valid
+ if (!htmlBlocks[match[1].toLowerCase()]) { return false; }
+ if (silent) { return true; }
+
+ } else {
+ return false;
+ }
+
+ // If we are here - we detected HTML block.
+ // Let's roll down till empty line (block end).
+ var nextLine:int = startLine + 1;
+ while (nextLine < state.lineMax && !state.isEmpty(nextLine)) {
+ nextLine++;
+ }
+
+ state.line = nextLine;
+ var token:BlockToken = new BlockToken('htmlblock',state.getLines(startLine, nextLine, 0, true));
+ token.level = state.level;
+ token.firstLine = startLine;
+ token.lastLine = state.line;
+ state.tokens.push(token);
+
+ // state.tokens.push({
+ // type: 'htmlblock',
+ // level: state.level,
+ // lines: [ startLine, state.line ],
+ // content: state.getLines(startLine, nextLine, 0, true)
+ // });
+
+ return true;
+
}
-
+
+ private const htmlBlocks:Object = {
+ 'article':1,
+ 'aside':1,
+ 'button':1,
+ 'blockquote':1,
+ 'body':1,
+ 'canvas':1,
+ 'caption':1,
+ 'col':1,
+ 'colgroup':1,
+ 'dd':1,
+ 'div':1,
+ 'dl':1,
+ 'dt':1,
+ 'embed':1,
+ 'fieldset':1,
+ 'figcaption':1,
+ 'figure':1,
+ 'footer':1,
+ 'form':1,
+ 'h1':1,
+ 'h2':1,
+ 'h3':1,
+ 'h4':1,
+ 'h5':1,
+ 'h6':1,
+ 'header':1,
+ 'hgroup':1,
+ 'hr':1,
+ 'iframe':1,
+ 'li':1,
+ 'map':1,
+ 'object':1,
+ 'ol':1,
+ 'output':1,
+ 'p':1,
+ 'pre':1,
+ 'progress':1,
+ 'script':1,
+ 'section':1,
+ 'style':1,
+ 'table':1,
+ 'tbody':1,
+ 'td':1,
+ 'textarea':1,
+ 'tfoot':1,
+ 'th':1,
+ 'tr':1,
+ 'thead':1,
+ 'ul':1,
+ 'video':1
+ };
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Lheading.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Lheading.as
index 9035060..9c5b927 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Lheading.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Lheading.as
@@ -37,11 +37,77 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var marker, pos, max,
+ var state:BlockState = istate as BlockState;
+ var next:int = startLine + 1;
+
+ if (next >= endLine) { return false; }
+ if (state.tShift[next] < state.blkIndent) { return false; }
+
+ // Scan next line
+
+ if (state.tShift[next] - state.blkIndent > 3) { return false; }
+
+ var pos:int = state.bMarks[next] + state.tShift[next];
+ var max:int = state.eMarks[next];
+
+ if (pos >= max) { return false; }
+
+ var marker:Number = state.src.charCodeAt(pos);
+
+ if (marker !== 0x2D/* - */ && marker !== 0x3D/* = */) { return false; }
+
+ pos = state.skipChars(pos, marker);
+
+ pos = state.skipSpaces(pos);
+
+ if (pos < max) { return false; }
+
+ pos = state.bMarks[startLine] + state.tShift[startLine];
+
+ state.line = next + 1;
+ var token:BlockToken = new BlockToken('heading_open','');
+ token.numValue = marker === 0x3D/* = */ ? 1 : 2;
+ token.firstLine = startLine;
+ token.lastLine = state.line;
+ token.level = state.level;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'heading_open',
+ // hLevel: marker === 0x3D/* = */ ? 1 : 2,
+ // lines: [ startLine, state.line ],
+ // level: state.level
+ // });
+ token = new BlockToken('inline',state.src.slice(pos, state.eMarks[startLine]).trim());
+ token.level = state.level + 1;
+ token.firstLine = startLine;
+ token.lastLine = state.line -1;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'inline',
+ // content: state.src.slice(pos, state.eMarks[startLine]).trim(),
+ // level: state.level + 1,
+ // lines: [ startLine, state.line - 1 ],
+ // children: []
+ // });
+ var tToken:TagToken = new TagToken('heading_close');
+ tToken.numValue = marker === 0x3D/* = */ ? 1 : 2;
+ tToken.level = state.level;
+ // state.tokens.push({
+ // type: 'heading_close',
+ // hLevel: marker === 0x3D/* = */ ? 1 : 2,
+ // level: state.level
+ // });
+
+ return true;
+
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/List.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/List.as
index 2c8a09d..80cf208 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/List.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/List.as
@@ -35,13 +35,271 @@ package org.apache.royale.markdown
}
/**
+ * Search `[-+*][\n ]`, returns next pos arter marker on success or -1 on fail.
+ */
+ public function skipBulletListMarker(state:BlockState, startLine:int):int{
+
+ var pos:int = state.bMarks[startLine] + state.tShift[startLine];
+ var max:int = state.eMarks[startLine];
+
+ if (pos >= max) { return -1; }
+
+ var marker:Number = state.src.charCodeAt(pos++);
+ // Check bullet
+ if (marker !== 0x2A/* * */ &&
+ marker !== 0x2D/* - */ &&
+ marker !== 0x2B/* + */) {
+ return -1;
+ }
+
+ if (pos < max && state.src.charCodeAt(pos) !== 0x20) {
+ // " 1.test " - is not a list item
+ return -1;
+ }
+
+ return pos;
+ }
+
+ /**
+ * Search `\d+[.)][\n ]`, returns next pos arter marker on success or -1 on fail.
+ */
+ public function skipOrderedListMarker(state:BlockState, startLine:int):int
+ {
+ var pos:int = state.bMarks[startLine] + state.tShift[startLine];
+ var max:int = state.eMarks[startLine];
+
+ if (pos + 1 >= max) { return -1; }
+
+ var ch:Number = state.src.charCodeAt(pos++);
+
+ if (ch < 0x30/* 0 */ || ch > 0x39/* 9 */) { return -1; }
+
+ for (;;) {
+ // EOL -> fail
+ if (pos >= max) { return -1; }
+
+ ch = state.src.charCodeAt(pos++);
+
+ if (ch >= 0x30/* 0 */ && ch <= 0x39/* 9 */) {
+ continue;
+ }
+
+ // found valid marker
+ if (ch === 0x29/* ) */ || ch === 0x2e/* . */) {
+ break;
+ }
+
+ return -1;
+ }
+
+
+ if (pos < max && state.src.charCodeAt(pos) !== 0x20/* space */) {
+ // " 1.test " - is not a list item
+ return -1;
+ }
+ return pos;
+ }
+
+ public function markTightParagraphs(state:BlockState, idx:int):void
+ {
+ var level:int = state.level + 2;
+
+ var len:int = state.tokens.length - 2
+ for (var i:int = idx + 2; i < len; i++) {
+ if (state.tokens[i].level === level && state.tokens[i].type === 'paragraph_open') {
+ state.tokens[i + 2].tight = true;
+ state.tokens[i].tight = true;
+ i += 2;
+ }
+ }
+ }
+
+
+ /**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ var state:BlockState = istate as BlockState;
+ var tight:Boolean = true;
+
+ // Detect list type and position after marker
+ var posAfterMarker:int = skipOrderedListMarker(state, startLine)
+ if (posAfterMarker >= 0) {
+ var isOrdered:Boolean = true;
+ } else if ((posAfterMarker = skipBulletListMarker(state, startLine)) >= 0) {
+ isOrdered = false;
+ } else {
+ return false;
+ }
+
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ // We should terminate list on style change. Remember first one to compare.
+ var markerCharCode:Number = state.src.charCodeAt(posAfterMarker - 1);
+
+ // For validation mode we can terminate immediately
+ if (silent) { return true; }
+
+ // Start list
+ var listTokIdx:int = state.tokens.length;
+
+ if (isOrdered) {
+ var start:int = state.bMarks[startLine] + state.tShift[startLine];
+ var markerValue:Number = Number(state.src.substr(start, posAfterMarker - start - 1));
+ var openToken:BlockToken = new BlockToken('ordered_list_open','');
+ openToken.numValue = markerValue;
+ // state.tokens.push({
+ // type: 'ordered_list_open',
+ // order: markerValue,
+ // lines: listLines = [ startLine, 0 ],
+ // level: state.level++
+ // });
+
+ } else {
+ openToken = new BlockToken('bullet_list_open','');
+ // state.tokens.push({
+ // type: 'bullet_list_open',
+ // lines: listLines = [ startLine, 0 ],
+ // level: state.level++
+ // });
+ }
+ openToken.firstLine = startLine;
+ openToken.level = state.level++;
+ state.tokens.push(openToken);
+
+ //
+ // Iterate list items
+ //
+
+ var nextLine:int = startLine;
+ var prevEmptyEnd:Boolean = false;
+ // terminatorRules = state.parser.ruler.getRules('list');
+
+ while (nextLine < endLine) {
+ var contentStart:int = state.skipSpaces(posAfterMarker);
+ var max:int = state.eMarks[nextLine];
+
+ if (contentStart >= max) {
+ // trimming space in "- \n 3" case, indent is 1 here
+ var indentAfterMarker:int = 1;
+ } else {
+ indentAfterMarker = contentStart - posAfterMarker;
+ }
+
+ // If we have more than 4 spaces, the indent is 1
+ // (the rest is just indented code block)
+ if (indentAfterMarker > 4) { indentAfterMarker = 1; }
+
+ // If indent is less than 1, assume that it's one, example:
+ // "-\n test"
+ if (indentAfterMarker < 1) { indentAfterMarker = 1; }
+
+ // " - test"
+ // ^^^^^ - calculating total length of this thing
+ var indent:int = (posAfterMarker - state.bMarks[nextLine]) + indentAfterMarker;
+
+ // Run subparser & write tokens
+ var itemToken:BlockToken = new BlockToken("list_item_open",'');
+ itemToken.firstLine = startLine;
+ itemToken.level = state.level++;
+ state.tokens.push(itemToken);
+ // state.tokens.push({
+ // type: 'list_item_open',
+ // lines: itemLines = [ startLine, 0 ],
+ // level: state.level++
+ // });
+
+ var oldIndent:int = state.blkIndent;
+ var oldTight:Boolean = state.tight;
+ var oldTShift:int = state.tShift[startLine];
+ var oldParentType:String = state.parentType;
+ state.tShift[startLine] = contentStart - state.bMarks[startLine];
+ state.blkIndent = indent;
+ state.tight = true;
+ state.parentType = 'list';
+
+ state.parser.tokenize(state, startLine, endLine);//had true??
+
+ // If any of list item is tight, mark list as tight
+ if (!state.tight || prevEmptyEnd) {
+ tight = false;
+ }
+ // Item become loose if finish with empty line,
+ // but we should filter last element, because it means list finish
+ prevEmptyEnd = (state.line - startLine) > 1 && state.isEmpty(state.line - 1);
+
+ state.blkIndent = oldIndent;
+ state.tShift[startLine] = oldTShift;
+ state.tight = oldTight;
+ state.parentType = oldParentType;
+ var tagToken:TagToken = new TagToken('list_item_close');
+ tagToken.level = --state.level;
+ state.tokens.push(tagToken);
+ // state.tokens.push({
+ // type: 'list_item_close',
+ // level: --state.level
+ // });
+
+ nextLine = startLine = state.line;
+ itemToken.lastLine = nextLine;
+ contentStart = state.bMarks[startLine];
+
+ if (nextLine >= endLine) { break; }
+
+ if (state.isEmpty(nextLine)) {
+ break;
+ }
+
+ //
+ // Try to check if list is terminated or continued.
+ //
+ if (state.tShift[nextLine] < state.blkIndent) { break; }
+
+ if(state.parser.rules.runLists(state,nextLine,endLine))
+ break;
+ // fail if terminating block found
+ // terminate = false;
+ // for (i = 0, l = terminatorRules.length; i < l; i++) {
+ // if (terminatorRules[i](state, nextLine, endLine, true)) {
+ // terminate = true;
+ // break;
+ // }
+ // }
+ // if (terminate) { break; }
+
+ // fail if list has another type
+ if (isOrdered) {
+ posAfterMarker = skipOrderedListMarker(state, nextLine);
+ if (posAfterMarker < 0) { break; }
+ } else {
+ posAfterMarker = skipBulletListMarker(state, nextLine);
+ if (posAfterMarker < 0) { break; }
+ }
+
+ if (markerCharCode !== state.src.charCodeAt(posAfterMarker - 1)) { break; }
+ }
+
+ // Finilize list
+ state.tokens.push({
+ type: isOrdered ? 'ordered_list_close' : 'bullet_list_close',
+ level: --state.level
+ });
+ openToken.lastLine = nextLine;
+
+ state.line = nextLine;
+
+ // mark paragraphs tight if needed
+ if (tight) {
+ markTightParagraphs(state, listTokIdx);
+ }
+
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Paragraph.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Paragraph.as
index 9c7da82..c379c54 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Paragraph.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Paragraph.as
@@ -37,11 +37,82 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var endLine, content, terminate, i, l,
+ // terminatorRules;
+ var nextLine:int = startLine + 1;
+
+ var state:BlockState = istate as BlockState;
+ endLine = state.lineMax;
+
+ // jump line-by-line until empty one or EOF
+ if (nextLine < endLine && !state.isEmpty(nextLine)) {
+ // terminatorRules = state.parser.ruler.getRules('paragraph');
+
+ for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {
+ // this would be a code block normally, but after paragraph
+ // it's considered a lazy continuation regardless of what's there
+ if (state.tShift[nextLine] - state.blkIndent > 3) { continue; }
+
+ // Some tags can terminate paragraph without empty lines.
+ if(state.parser.rules.runParagraphs(state,nextLine,endLine))
+ break;
+ // terminate = false;
+ // for (i = 0, l = terminatorRules.length; i < l; i++) {
+ // if (terminatorRules[i](state, nextLine, endLine, true)) {
+ // terminate = true;
+ // break;
+ // }
+ // }
+ // if (terminate) { break; }
+ }
+ }
+
+ var content:String = state.getLines(startLine, nextLine, state.blkIndent, false).trim();
+
+ state.line = nextLine;
+ if (content.length) {
+ var token:BlockToken = new BlockToken('paragraph_open','');
+ token.firstLine = startLine;
+ token.lastLine = state.line;
+ token.level = state.level;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'paragraph_open',
+ // tight: false,
+ // lines: [ startLine, state.line ],
+ // level: state.level
+ // });
+
+ token = new BlockToken('inline',content);
+ token.firstLine = startLine;
+ token.lastLine = state.line;
+ token.level = state.level + 1;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'inline',
+ // content: content,
+ // level: state.level + 1,
+ // lines: [ startLine, state.line ],
+ // children: []
+ // });
+ var tToken:TagToken = new TagToken('paragraph_close');
+ tToken.level = state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({
+ // type: 'paragraph_close',
+ // tight: false,
+ // level: state.level
+ // });
+ }
+
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Table.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Table.as
index c8034e7..1c83990 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Table.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/block/Table.as
@@ -34,15 +34,216 @@ package org.apache.royale.markdown
return _instance;
}
+ private function getLine(state:BlockState, line:int):String
+ {
+ var pos:int = state.bMarks[line] + state.blkIndent;
+ var max:int = state.eMarks[line];
+
+ return state.src.substr(pos, max - pos);
+ }
+
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var ch, lineText, pos, i, nextLine, rows, cell,
+ // aligns, t, tableLines, tbodyLines;
+
+ var state:BlockState = istate as BlockState;
+ // should have at least three lines
+ if (startLine + 2 > endLine) { return false; }
+
+ var nextLine:int = startLine + 1;
+
+ if (state.tShift[nextLine] < state.blkIndent) { return false; }
+
+ // first character of the second line should be '|' or '-'
+
+ var pos:int = state.bMarks[nextLine] + state.tShift[nextLine];
+ if (pos >= state.eMarks[nextLine]) { return false; }
+
+ var ch:Number = state.src.charCodeAt(pos);
+ if (ch !== 0x7C/* | */ && ch !== 0x2D/* - */ && ch !== 0x3A/* : */) { return false; }
+
+ var lineText:String = getLine(state, startLine + 1);
+ if (!COLUMNS.test(lineText)) { return false; }
+
+ var rows:Array = lineText.split('|');
+ if (rows.length <= 2) { return false; }
+ var aligns:Array = [];
+ for (var i:int = 0; i < rows.length; i++) {
+ var t:String = rows[i].trim();
+ if (!t) {
+ // allow empty columns before and after table, but not in between columns;
+ // e.g. allow ` |---| `, disallow ` ---||--- `
+ if (i === 0 || i === rows.length - 1) {
+ continue;
+ } else {
+ return false;
+ }
+ }
+
+ if (!ROWS.test(t)) { return false; }
+ if (t.charCodeAt(t.length - 1) === 0x3A/* : */) {
+ aligns.push(t.charCodeAt(0) === 0x3A/* : */ ? 'center' : 'right');
+ } else if (t.charCodeAt(0) === 0x3A/* : */) {
+ aligns.push('left');
+ } else {
+ aligns.push('');
+ }
+ }
+
+ lineText = getLine(state, startLine).trim();
+ if (lineText.indexOf('|') === -1) { return false; }
+ rows = lineText.replace(ROWS_2, '').split('|');
+ if (aligns.length !== rows.length) { return false; }
+ if (silent) { return true; }
+ var tableToken:BlockToken = new BlockToken('table_open','');
+ tableToken.firstLine = startLine;// lastine set when we're done
+ tableToken.level = state.level++;
+ state.tokens.push(tableToken);
+ // state.tokens.push({
+ // type: 'table_open',
+ // lines: tableLines = [ startLine, 0 ],
+ // level: state.level++
+ // });
+ var token:BlockToken = new BlockToken('thead_open','');
+ token.firstLine = startLine;
+ token.lastLine = startLine + 1;
+ token.level = state.level++;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'thead_open',
+ // lines: [ startLine, startLine + 1 ],
+ // level: state.level++
+ // });
+ token = new BlockToken('tr_open','');
+ token.firstLine = startLine;
+ token.lastLine = startLine + 1;
+ token.level = state.level++;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'tr_open',
+ // lines: [ startLine, startLine + 1 ],
+ // level: state.level++
+ // });
+
+ for (i = 0; i < rows.length; i++) {
+ token = new BlockToken('th_open','');
+ token.data = aligns[i];
+ token.firstLine = startLine;
+ token.lastLine = startLine + 1;
+ token.level = state.level++;
+ state.tokens.push(token);
+
+ // state.tokens.push({
+ // type: 'th_open',
+ // align: aligns[i],
+ // lines: [ startLine, startLine + 1 ],
+ // level: state.level++
+ // });
+
+ token = new BlockToken('inline',rows[i].trim());
+ token.firstLine = startLine;
+ token.lastLine = startLine + 1;
+ token.level = state.level;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'inline',
+ // content: rows[i].trim(),
+ // lines: [ startLine, startLine + 1 ],
+ // level: state.level,
+ // children: []
+ // });
+ var tToken:TagToken = new TagToken('th_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({ type: 'th_close', level: --state.level });
+ }
+ tToken = new TagToken('tr_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({ type: 'tr_close', level: --state.level });
+
+ tToken = new TagToken('thead_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({ type: 'thead_close', level: --state.level });
+
+ var tBodyToken:BlockToken = new BlockToken('tbody_open','');
+ tBodyToken.data = aligns[i];
+ tBodyToken.firstLine = startLine + 2;
+ tBodyToken.level = state.level++;
+ state.tokens.push(tBodyToken);
+ // state.tokens.push({
+ // type: 'tbody_open',
+ // lines: tbodyLines = [ startLine + 2, 0 ],
+ // level: state.level++
+ // });
+
+ for (nextLine = startLine + 2; nextLine < endLine; nextLine++) {
+ if (state.tShift[nextLine] < state.blkIndent) { break; }
+
+ lineText = getLine(state, nextLine).trim();
+ if (lineText.indexOf('|') === -1) { break; }
+ rows = lineText.replace(ROWS_2, '').split('|');
+
+ tToken = new TagToken('tr_open');
+ tToken.level = state.level++;
+ state.tokens.push(tToken);
+ // state.tokens.push({ type: 'tr_open', level: state.level++ });
+ for (i = 0; i < rows.length; i++) {
+ tToken = new TagToken('td_open');
+ tToken.data = aligns[i];
+ tToken.level = state.level++;
+ state.tokens.push(tToken);
+ // state.tokens.push({ type: 'td_open', align: aligns[i], level: state.level++ });
+ // 0x7c === '|'
+ var cell:String = rows[i].substring(
+ rows[i].charCodeAt(0) === 0x7c ? 1 : 0,
+ rows[i].charCodeAt(rows[i].length - 1) === 0x7c ? rows[i].length - 1 : rows[i].length
+ ).trim();
+ token = new BlockToken('inline',cell);
+ token.level = state.level;
+ state.tokens.push(token);
+ // state.tokens.push({
+ // type: 'inline',
+ // content: cell,
+ // level: state.level,
+ // children: []
+ // });
+ tToken = new TagToken('td_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({ type: 'td_close', level: --state.level });
+ }
+ tToken = new TagToken('tr_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({ type: 'tr_close', level: --state.level });
+ }
+ tToken = new TagToken('tbody_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({ type: 'tbody_close', level: --state.level });
+ tToken = new TagToken('table_close');
+ tToken.level = --state.level;
+ state.tokens.push(tToken);
+ // state.tokens.push({ type: 'table_close', level: --state.level });
+ tableToken.lastLine = tBodyToken.lastLine = nextLine;
+ // tableLines[1] = tbodyLines[1] = nextLine;
+ state.line = nextLine;
+ return true;
+
}
-
+ private const COLUMNS:RegExp = /^[-:| ]+$/;
+ private const ROWS:RegExp = /^:?-+:?$/;
+ private const ROWS_2:RegExp = /^\||\|$/g;
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Abbr.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Abbr.as
index dd20d73..8442650 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Abbr.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Abbr.as
@@ -18,6 +18,9 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ import org.apache.royale.markdown.helpers.parseLinkLabel;
+ import org.apache.royale.markdown.helpers.wrappedInParagraph;
+
public class Abbr extends Rule
{
private function Abbr()
@@ -36,12 +39,73 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.ContentToken
+ * @royaleignorecoercion org.apache.royale.markdown.TagToken
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:CoreState = istate as CoreState;
+ var tokens:Vector.<IToken> = state.tokens;//, i, l, content, pos;
+
+ if (state.inlineMode) {
+ return false;
+ }
+ var len:int = tokens.length - 1;
+ // Parse inlines
+ for (var i:int = 1; i < len; i++) {
+ var token:ContentToken = tokens[i] as ContentToken;
+ var lastToken:IToken = tokens[i - 1];
+ var nextToken:IToken = tokens[i + 1];
+ if(wrappedInParagraph(lastToken,token,nextToken))
+ {
+ var content:String = token.content;
+ while (content.length) {
+ var pos:int = parseAbbr(content, state.inlineParser, state.options, state.env);
+ if (pos < 0) { break; }
+ content = content.slice(pos).trim();
+ }
+
+ token.content = content;
+ if (!content.length) {
+ lastToken.tight = true;
+ nextToken.tight = true;
+ }
+ }
+ }
+ return true;
+ }
+
+ private function parseAbbr(str:String, inlineParser:InlineParser, options:MarkdownOptions, env:Environment):int
+ {
+ if (str.charCodeAt(0) !== 0x2A/* * */) { return -1; }
+ if (str.charCodeAt(1) !== 0x5B/* [ */) { return -1; }
+
+ if (str.indexOf(']:') === -1) { return -1; }
+
+ var state:InlineState = new InlineState(str, inlineParser, options, env, new Vector.<IToken>());
+ var labelEnd:int = parseLinkLabel(state, 1);
+
+ if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; }
+
+ var max:int = state.posMax;
+
+ // abbr title is always one line, so looking for ending "\n" here
+ for (var pos:int = labelEnd + 2; pos < max; pos++) {
+ if (state.src.charCodeAt(pos) === 0x0A) { break; }
+ }
+
+ var label:String = str.slice(2, labelEnd);
+ var title:String = str.slice(labelEnd + 2, pos).trim();
+ if (title.length === 0) { return -1; }
+ if (!env.abbreviations) { env.abbreviations = Object.create(null); }
+ // prepend ':' to avoid conflict with Object.prototype members (not needed with Object.create(null))
+ if (env.abbreviations[label] === undefined) {
+ env.abbreviations[label] = title;
+ }
+
+ return pos;
}
-
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Abbr2.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Abbr2.as
index 5ecdbe0..f22964e 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Abbr2.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Abbr2.as
@@ -34,14 +34,98 @@ package org.apache.royale.markdown
return _instance;
}
+ private const PUNCT_CHARS:String = ' \n()[]\'".,!?-';
+
+
+ // from Google closure library
+ // http://closure-library.googlecode.com/git-history/docs/local_closure_goog_string_string.js.source.html#line1021
+ private function regEscape(s:String):String {
+ return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1');
+ }
+
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.CoreState
+ * @royaleignorecoercion org.apache.royale.markdown.ContentToken
+ * @royaleignorecoercion Vector.<BlockToken>
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:CoreState = istate as CoreState;
+ // var i, j, l, tokens, token, text, nodes, pos, level, reg, m, regText,
+ var blockTokens:Vector.<BlockToken> = state.tokens as Vector.<BlockToken>;
+
+ if (!state.env.abbreviations) { return false; }
+ if (!state.env.abbrRegExp) {
+ var regText:String = '(^|[' + PUNCT_CHARS.split('').map(regEscape).join('') + '])'
+ + '(' + Object.keys(state.env.abbreviations).map(function (x:String):String {
+ return x.substr(1);
+ }).sort(function (a:*, b:*):Number {
+ return b.length - a.length;
+ }).map(regEscape).join('|') + ')'
+ + '($|[' + PUNCT_CHARS.split('').map(regEscape).join('') + '])';
+ state.env.abbrRegExp = new RegExp(regText, 'g');
+ }
+ var reg:RegExp = state.env.abbrRegExp;
+ var len:int = blockTokens.length;
+ for (var j:int = 0; j < len; j++) {
+ if (blockTokens[j].type !== 'inline') { continue; }
+ var tokens:Vector.<IToken> = blockTokens[j].children;
+
+ // We scan from the end, to keep position when new tags added.
+ for (var i:int = tokens.length - 1; i >= 0; i--) {
+ var token:ContentToken = tokens[i] as ContentToken;
+ if (token.type !== 'text') { continue; }
+
+ var pos:int = 0;
+ var text:String = token.content;
+ reg.lastIndex = 0;
+ var level:int = token.level;
+ var nodes:Vector.<IToken> = new Vector.<IToken>();
+ // global flag is set so we can loop through results while we have
+ var m:Object = reg.exec(text);
+ while (m) {
+ if (reg.lastIndex > pos) {
+ var newt:IToken = new ContentToken("text",text.slice(pos, m.index + m[1].length));
+ newt.level = level;
+ nodes.push(newt);
+ }
+
+ newt = new TagToken('abbr_open');
+ newt.title = state.env.abbreviations[m[2]];
+ newt.level = level++;
+ nodes.push(newt);
+
+ newt = new ContentToken("text",m[2]);
+ newt.level = level;
+ nodes.push(newt);
+
+ newt = new TagToken('abbr_close');
+ newt.level = --level;
+ nodes.push(newt);
+
+ pos = reg.lastIndex - m[3].length;
+ m = reg.exec(text);
+ }
+
+ if (!nodes.length) { continue; }
+
+ if (pos < text.length) {
+
+ newt = new ContentToken("text",text.slice(pos));
+ newt.level = level;
+ nodes.push(newt);
+
+ }
+
+ // replace current node
+ blockTokens[j].children = tokens = new Vector.<IToken>().concat(tokens.slice(0, i), nodes, tokens.slice(i + 1));
+ }
+ }
+
+ return true;
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Block.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Block.as
index 24fcbec..60398c7 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Block.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Block.as
@@ -38,9 +38,19 @@ package org.apache.royale.markdown
* @langversion 3.0
* @productversion Royale 0.9.9 *
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(iState:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:CoreState = iState as CoreState;
+ if (state.inlineMode) {
+ var token:BlockToken = new BlockToken("inline",state.src.replace(/\n/g, ' ').trim());
+ token.firstLine = 0;
+ token.lastLine = 1;
+ state.tokens.push(token);
+
+ } else {
+ state.blockParser.parse(state.src, state.options, state.env, state.tokens);
+ }
+ return true;
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Footnote_tail.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Footnote_tail.as
index a5d9aee..f16ff20 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Footnote_tail.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Footnote_tail.as
@@ -37,11 +37,91 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.CoreState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:CoreState = istate as CoreState;
+ // var i, l, j, t, lastParagraph, list, tokens, current, currentLabel,
+ var level:int = 0;
+ var insideRef:Boolean = false;
+ var refTokens:Object = {};
+
+ if (!state.env.footnotes) { return false; }
+
+ state.tokens = state.tokens.filter(function(tok:Token):Boolean {
+ if (tok.type === 'footnote_reference_open') {
+ insideRef = true;
+ var current:Array = [];
+ var currentLabel:String = tok.data;
+ return false;
+ }
+ if (tok.type === 'footnote_reference_close') {
+ insideRef = false;
+ // prepend ':' to avoid conflict with Object.prototype members
+ refTokens[currentLabel] = current;
+ return false;
+ }
+ if (insideRef) { current.push(tok); }
+ return !insideRef;
+ });
+
+ if (!state.env.footnotes.list) { return false; }
+ var list:Array = state.env.footnotes.list;
+ var token:IToken = new TagToken('footnote_block_open');
+ token.level = level++;
+ state.tokens.push(token);
+ var len:int = list.length;
+ for (var i:int = 0; i < len; i++) {
+ token = new TagToken('footnote_open');
+ token.id = i;
+ token.level = level++;
+ state.tokens.push(token);
+
+ if (list[i].tokens) {
+ var tokens:Vector.<IToken> = new Vector.<IToken>();
+ token = new TagToken('paragraph_open');
+ token.level = level++;
+ tokens.push(token);
+ var blockToken:BlockToken = new BlockToken('inline',"");
+ blockToken.level = level;
+ blockToken.children = list[i].tokens
+ tokens.push(blockToken);
+ token = new TagToken('paragraph_close');
+ token.level = --level;
+ tokens.push(token);
+ } else if (list[i].label) {
+ tokens = refTokens[list[i].label];
+ }
+
+ state.tokens = state.tokens.concat(tokens);
+ if (state.tokens[state.tokens.length - 1].type === 'paragraph_close') {
+ var lastParagraph:IToken = state.tokens.pop();
+ } else {
+ lastParagraph = null;
+ }
+
+ var t:int = list[i].count > 0 ? list[i].count : 1;
+ for (var j:int = 0; j < t; j++) {
+ token = new TagToken("footnote_anchor");
+ token.id = i;
+ token.subId = j;
+ token.level = level;
+ state.tokens.push(token);
+ }
+
+ if (lastParagraph) {
+ state.tokens.push(lastParagraph);
+ }
+ token = new TagToken("footnote_close");
+ token.level = --level;
+ state.tokens.push(token);
+ }
+ token = new TagToken("footnote_block_close");
+ token.level = --level;
+ state.tokens.push(token);
+ return true;
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Inline.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Inline.as
index d08fe95..61f3670 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Inline.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Inline.as
@@ -38,11 +38,24 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.BlockToken
+ * @royaleignorecoercion org.apache.royale.markdown.CoreState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:CoreState = istate as CoreState;
+ var tokens:Vector.<IToken> = state.tokens;
+
+ // Parse inlines
+ var len:int = tokens.length;
+ for (var i:int = 0; i < len; i++) {
+ var token:BlockToken = tokens[i] as BlockToken;
+ if (token.type === 'inline') {
+ state.inlineParser.parse(token.content, state.options, state.env, token.children);
+ }
+ }
+ return true;
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/References.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/References.as
index e957ac4..8cb190d 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/References.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/References.as
@@ -18,6 +18,13 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ import org.apache.royale.markdown.helpers.wrappedInParagraph;
+ import org.apache.royale.markdown.helpers.parseLinkLabel;
+ import org.apache.royale.markdown.helpers.parseLinkDestination;
+ import org.apache.royale.markdown.helpers.parseLinkTitle;
+ import org.apache.royale.markdown.helpers.normalizeReference;
+ import org.apache.royale.markdown.helpers.HRef;
+
public class References extends Rule
{
private function References()
@@ -37,12 +44,104 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.ContentToken
+ * @royaleignorecoercion org.apache.royale.markdown.CoreState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:CoreState = istate as CoreState;
+ var tokens:Vector.<IToken> = state.tokens;//, i, l, content, pos;
+
+ if(!state.env.references)
+ state.env.references = Object.create(null);
+
+ if (state.inlineMode) {
+ return false;
+ }
+
+ // Scan definitions in paragraph inlines
+ var len:int = tokens.length - 1;
+ for (var i:int = 1; i < len; i++) {
+ var token:ContentToken = tokens[i] as ContentToken;
+ var last:IToken = tokens[i - 1];
+ var next:IToken = tokens[i + 1];
+ if(wrappedInParagraph(last,token,next))
+ {
+ var content:String = token.content;
+ while (content.length) {
+ var pos:int = parseReference(content, state.inlineParser, state.options, state.env);
+ if (pos < 0) { break; }
+ content = content.slice(pos).trim();
+ }
+
+ token.content = content;
+ if (!content.length) {
+ last.tight = true;
+ next.tight = true;
+ }
+ }
+ }
+ return true;
}
+ public function parseReference(str:String, parser:InlineParser, options:MarkdownOptions, env:Environment):int
+ {
+ // var state, labelEnd, pos, max, code, start, href, title, label;
+
+ if (str.charCodeAt(0) !== 0x5B/* [ */) { return -1; }
+
+ if (str.indexOf(']:') === -1) { return -1; }
+
+ var state:InlineState = new InlineState(str, parser, options, env, new Vector.<IToken>);
+ var labelEnd:int = parseLinkLabel(state, 0);
+
+ if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; }
+
+ var max:int = state.posMax;
+
+ // [label]: destination 'title'
+ // ^^^ skip optional whitespace here
+ for (var pos:int = labelEnd + 2; pos < max; pos++) {
+ var code:Number = state.src.charCodeAt(pos);
+ if (code !== 0x20 && code !== 0x0A) { break; }
+ }
+
+ // [label]: destination 'title'
+ // ^^^^^^^^^^^ parse this
+ if (!parseLinkDestination(state, pos)) { return -1; }
+ var href:String = state.linkContent;
+ pos = state.position;
+
+ // [label]: destination 'title'
+ // ^^^ skipping those spaces
+ var start:int = pos;
+ for (pos = pos + 1; pos < max; pos++) {
+ code = state.src.charCodeAt(pos);
+ if (code !== 0x20 && code !== 0x0A) { break; }
+ }
+
+ // [label]: destination 'title'
+ // ^^^^^^^ parse this
+ if (pos < max && start !== pos && parseLinkTitle(state, pos)) {
+ var title:String = state.linkContent;
+ pos = state.position;
+ } else {
+ title = '';
+ pos = start;
+ }
+
+ // ensure that the end of the line is empty
+ while (pos < max && state.src.charCodeAt(pos) === 0x20/* space */) { pos++; }
+ if (pos < max && state.src.charCodeAt(pos) !== 0x0A) { return -1; }
+
+ var label:String = normalizeReference(str.slice(1, labelEnd));
+ if (env.references[label] === undefined) {
+ env.references[label] = new HRef(href,title);
+ }
+
+ return pos;
+ }
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Replacements.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Replacements.as
index a295fd6..d5d00e1 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Replacements.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Replacements.as
@@ -34,15 +34,81 @@ package org.apache.royale.markdown
return _instance;
}
+ private const RARE_RE:RegExp = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/;
+
+ private const SCOPED_ABBR_RE:RegExp = /\((c|tm|r|p)\)/ig;
+ private const SCOPED_ABBR:Object = {
+ 'c': '©',
+ 'r': '®',
+ 'p': '§',
+ 'tm': '™'
+ };
+
+ private function replaceScopedAbbr(str:String):String {
+ if (str.indexOf('(') < 0) { return str; }
+
+ return str.replace(SCOPED_ABBR_RE, function(match:String, name:String):String {
+ return SCOPED_ABBR[name.toLowerCase()];
+ });
+ }
+
+
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.CoreState
+ * @royaleignorecoercion org.apache.royale.markdown.BlockToken
+ * @royaleignorecoercion org.apache.royale.markdown.ContentToken
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:CoreState = istate as CoreState;
+ // var i, token, text, inlineTokens, blkIdx;
+
+ if (!state.options.typographer) { return false; }
+
+ for (var blkIdx:int = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {
+
+ if (state.tokens[blkIdx].type !== 'inline') { continue; }
+
+ var inlineTokens:Vector.<IToken> = (state.tokens[blkIdx] as BlockToken).children;
+
+ for (var i:int = inlineTokens.length - 1; i >= 0; i--) {
+ var token:ContentToken = inlineTokens[i] as ContentToken;
+ if (token.type === 'text') {
+ var text:String = token.content;
+
+ text = replaceScopedAbbr(text);
+
+ if (RARE_RE.test(text)) {
+ text = text
+ .replace(PLUS_MINUS, '±')
+ // .., ..., ....... -> …
+ // but ?..... & !..... -> ?.. & !..
+ .replace(ELLIPSIS, '…').replace(/([?!])…/g, '$1..')
+ .replace(QUEST_EXCLAM, '$1$1$1').replace(DOUBLE_COMMA, ',')
+ // em-dash
+ .replace(M_DASH, '$1\u2014$2')
+ // en-dash
+ .replace(N_DASH, '$1\u2013$2')
+ .replace(N_DASH_2, '$1\u2013$2');
+ }
+
+ token.content = text;
+ }
+ }
+ }
+ return true;
+
}
+ private const PLUS_MINUS:RegExp = /\+-/g;
+ private const ELLIPSIS:RegExp = /\.{2,}/g;
+ private const QUEST_EXCLAM:RegExp = /([?!]){4,}/g;
+ private const DOUBLE_COMMA:RegExp = /,{2,}/g;
+ private const M_DASH:RegExp = /(^|[^-])---([^-]|$)/mg;
+ private const N_DASH:RegExp = /(^|\s)--(\s|$)/mg;
+ private const N_DASH_2:RegExp = /(^|[^-\s])--([^-\s]|$)/mg;
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Smartquotes.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Smartquotes.as
index aff0796..1c93d95 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Smartquotes.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/core/Smartquotes.as
@@ -34,15 +34,150 @@ package org.apache.royale.markdown
return _instance;
}
+ private const QUOTE_TEST_RE:RegExp = /['"]/;
+ private const QUOTE_RE:RegExp = /['"]/g;
+ private const PUNCT_RE:RegExp = /[-\s()\[\]]/;
+ private const APOSTROPHE:String = '’';
+
+ // This function returns true if the character at `pos`
+ // could be inside a word.
+ private function isLetter(str:String, pos:int):Boolean
+ {
+ if (pos < 0 || pos >= str.length) { return false; }
+ return !PUNCT_RE.test(str[pos]);
+ }
+
+
+ private function replaceAt(str:String, index:int, ch:String):String
+ {
+ return str.substr(0, index) + ch + str.substr(index + 1);
+ }
+
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.CoreState
+ * @royaleignorecoercion org.apache.royale.markdown.ContentToken
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var i, token, text, t, pos, max, thisLevel, lastSpace, nextSpace, item,
+ // canOpen, canClose, j, isSingle, blkIdx, tokens,
+ // stack;
+ state = istate as CoreState;
+
+ if (!state.options.typographer) { return false; }
+
+ stack = [];
+
+ for (var blkIdx:int = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {
+
+ if (state.tokens[blkIdx].type !== 'inline') { continue; }
+
+ var tokens:Vector.<IToken> = (state.tokens[blkIdx] as BlockToken).children;
+ stack.length = 0;
+
+ for (var i:int = 0; i < tokens.length; i++) {
+ var token:ContentToken = tokens[i] as ContentToken;
+
+ if (token.type !== 'text' || QUOTE_TEST_RE.test(token.content)) { continue; }
+
+ this.level = tokens[i].level;
+
+ for (var j:int = stack.length - 1; j >= 0; j--) {
+ if (stack[j].level <= this.level) { break; }
+ }
+ stack.length = j + 1;
+
+ var text:String = token.content;
+ var pos:int = 0;
+ var max:int = text.length;
+
+ while (pos < max) {
+ QUOTE_RE.lastIndex = pos;
+ var t:Object = QUOTE_RE.exec(text);
+ if (!t) { break; }
+
+ var lastSpace:Boolean = !isLetter(text, t.index - 1);
+ pos = t.index + 1;
+ var isSingle:Boolean = (t[0] === "'");
+ var nextSpace:Boolean = !isLetter(text, pos);
+
+ if (!nextSpace && !lastSpace) {
+ // middle of word
+ if (isSingle) {
+ token.content = replaceAt(token.content, t.index, APOSTROPHE);
+ }
+ continue;
+ }
+
+ var canOpen:Boolean = !nextSpace;
+ var canClose:Boolean = !lastSpace;
+
+ if (canClose) {
+ // this could be a closing quote, rewind the stack to get a match
+ searchStack(token,tokens,t.index,isSingle);
+
+ }
+
+ if (canOpen) {
+ stack.push(new StackRef(i,t.index,isSingle,this.level));
+ // {
+ // token: i,
+ // pos: t.index,
+ // single: isSingle,
+ // level: thisLevel
+ // });
+ } else if (canClose && isSingle) {
+ token.content = replaceAt(token.content, t.index, APOSTROPHE);
+ }
+ }
+ }
+ }
+ return true;
}
+ private var stack:Array;
+ private var level:int;
+ private var state:CoreState;
+ private function searchStack(token:ContentToken,tokens:Vector.<IToken>,index:int,isSingle:Boolean):void{
+ for (var i:int = stack.length - 1; i >= 0; i--) {
+ var item:StackRef = stack[i];
+ if (stack[i].level < this.level) { break; }
+ if (item.single === isSingle && stack[i].level === this.level) {
+ item = stack[i];
+ var stackToken:ContentToken = tokens[item.token] as ContentToken
+ if (isSingle) {
+ stackToken.content = replaceAt(stackToken.content, item.pos, state.options.quotes[2]);
+ token.content = replaceAt(token.content, index, state.options.quotes[3]);
+ } else {
+ stackToken.content = replaceAt(stackToken.content, item.pos, state.options.quotes[0]);
+ token.content = replaceAt(token.content, index, state.options.quotes[1]);
+ }
+ stack.length = i;
+ return;
+ }
+ }
+
+ }
+
+ }
+}
+class StackRef
+{
+ public function StackRef(token:int,pos:int,single:Boolean,level:int)
+ {
+ this.token = token;
+ this.pos = pos;
+ this.single = single;
+ this.level = level;
}
+
+ public var token:int;
+ public var pos:int;
+ public var single:Boolean;
+ public var level:int;
+
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Autolink.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Autolink.as
index b2853d8..fc07d09 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Autolink.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Autolink.as
@@ -18,6 +18,11 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ import org.apache.royale.utils.string.sanitizeUrl;
+
+ /**
+ * Process autolinks '<protocol:...>'
+ */
public class Autolink extends Rule
{
private function Autolink()
@@ -33,16 +38,107 @@ package org.apache.royale.markdown
return _instance;
}
+ private const EMAIL_RE:RegExp = /^<([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/;
+ private const AUTOLINK_RE:RegExp = /^<([a-zA-Z.\-]{1,25}):([^<>\x00-\x20]*)>/;
/**
* parses the rule
* @langversion 3.0
* @productversion Royale 0.9.9 *
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var tail, linkMatch, emailMatch, url, fullUrl,
+ var state:InlineState = istate as InlineState;
+ var pos:int = state.position;
+
+ if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; }
+
+ var tail:String = state.src.slice(pos);
+
+ if (tail.indexOf('>') < 0) { return false; }
+
+ var linkMatch:Array = tail.match(AUTOLINK_RE);
+
+ if (linkMatch) {
+ if (urlSchema.indexOf(linkMatch[1].toLowerCase()) < 0) { return false; }
+
+ var url:String = linkMatch[0].slice(1, -1);
+ var fullUrl:String = sanitizeUrl(url);
+ // if (!state.parser.validateLink(url)) { return false; }
+
+ if (!silent) {
+ var token:LinkToken = new LinkToken('link_open',state.level);
+ token.href = fullUrl;
+ state.push(token);
+ // state.push({
+ // type: 'link_open',
+ // href: fullUrl,
+ // level: state.level
+ // });
+ state.push(new ContentToken('text',url,state.level + 1));
+ // state.push({
+ // type: 'text',
+ // content: url,
+ // level: state.level + 1
+ // });
+ state.push(new TagToken('link_close',state.level));
+ // state.push({ type: 'link_close', level: state.level });
+ }
+
+ state.position += linkMatch[0].length;
+ return true;
+ }
+
+ var emailMatch:Array = tail.match(EMAIL_RE);
+
+ if (emailMatch) {
+
+ url = emailMatch[0].slice(1, -1);
+
+ fullUrl = sanitizeUrl('mailto:' + url);
+ //TODO validate?
+ // if (!state.parser.validateLink(fullUrl)) { return false; }
+
+ if (!silent) {
+ token = new LinkToken('link_open',state.level);
+ token.href = fullUrl;
+ state.push(token);
+ // state.push({
+ // type: 'link_open',
+ // href: fullUrl,
+ // level: state.level
+ // });
+ state.push(new ContentToken('text',url,state.level + 1));
+ // state.push({
+ // type: 'text',
+ // content: url,
+ // level: state.level + 1
+ // });
+ state.push(new TagToken('link_close',state.level));
+ // state.push({ type: 'link_close', level: state.level });
+ }
+
+ state.position += emailMatch[0].length;
+ return true;
+ }
+
+ return false;
+
}
+ private var urlSchema:Array = ['coap','doi','javascript','aaa','aaas','about','acap','cap','cid','crid','data','dav','dict','dns',
+ 'file','ftp','geo','go','gopher','h323','http','https','iax','icap','im','imap','info','ipp','iris','iris.beep','iris.xpc',
+ 'iris.xpcs','iris.lwz','ldap','mailto','mid','msrp','msrps','mtqp','mupdate','news','nfs','ni','nih','nntp','opaquelocktoken','pop',
+ 'pres','rtsp','service','session','shttp','sieve','sip','sips','sms','snmp','soap.beep','soap.beeps','tag','tel','telnet','tftp',
+ 'thismessage','tn3270','tip','tv','urn','vemmi','ws','wss','xcon','xcon-userid','xmlrpc.beep','xmlrpc.beeps','xmpp','z39.50r',
+ 'z39.50s','adiumxtra','afp','afs','aim','apt','attachment','aw','beshare','bitcoin','bolo','callto','chrome','chrome-extension',
+ 'com-eventbrite-attendee','content','cvs','dlna-playsingle','dlna-playcontainer','dtn','dvb','ed2k','facetime','feed','finger',
+ 'fish','gg','git','gizmoproject','gtalk','hcp','icon','ipn','irc','irc6','ircs','itms','jar','jms','keyparc','lastfm','ldaps',
+ 'magnet','maps','market','message','mms','ms-help','msnim','mumble','mvn','notes','oid','palm','paparazzi','platform','proxy',
+ 'psyc','query','res','resource','rmi','rsync','rtmp','secondlife','sftp','sgn','skype','smb','soldat','spotify','ssh','steam',
+ 'svn','teamspeak','things','udp','unreal','ut2004','ventrilo','view-source','webcal','wtai','xfire','wyciwyg','xri','ymsgr'];
+
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Backticks.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Backticks.as
index 83615e7..a857c87 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Backticks.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Backticks.as
@@ -37,12 +37,61 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
- }
+ // var start, max, marker, matchStart, matchEnd,
+ var state:InlineState = istate as InlineState;
+ var pos:int = state.position;
+ var ch:Number = state.src.charCodeAt(pos);
+
+ if (ch !== 0x60/* ` */) { return false; }
+
+ var start:int = pos;
+ pos++;
+ var max:int = state.posMax;
+
+ while (pos < max && state.src.charCodeAt(pos) === 0x60/* ` */) { pos++; }
+
+ var marker:String = state.src.slice(start, pos);
+ var matchEnd:int
+ var matchStart:int = matchEnd = pos;
+
+ while ((matchStart = state.src.indexOf('`', matchEnd)) !== -1) {
+ matchEnd = matchStart + 1;
+
+ while (matchEnd < max && state.src.charCodeAt(matchEnd) === 0x60/* ` */) { matchEnd++; }
+
+ if (matchEnd - matchStart === marker.length) {
+ if (!silent) {
+ var content:String = state.src.slice(pos, matchStart)
+ .replace(LINE_END, ' ')
+ .trim();
+ var token:ContentToken = new ContentToken('code',content);
+ token.level = state.level;
+ state.push(token);
+ // state.push({
+ // type: 'code',
+ // content: state.src.slice(pos, matchStart)
+ // .replace(/[ \n]+/g, ' ')
+ // .trim(),
+ // block: false,
+ // level: state.level
+ // });
+ }
+ state.position = matchEnd;
+ return true;
+ }
+ }
+
+ if (!silent) { state.pending += marker; }
+ state.position += marker.length;
+ return true;
+
+ }
+ private const LINE_END:RegExp = /[ \n]+/g;
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Del.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Del.as
index 5af84d0..0e1b93d 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Del.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Del.as
@@ -18,6 +18,9 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ /**
+ * Process ~~deleted text~~
+ */
public class Del extends Rule
{
private function Del()
@@ -37,11 +40,94 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // pos,
+ // stack,
+ var state:InlineState = istate as InlineState;
+ var max:int = state.posMax;
+ var start:int = state.position;
+ var found:Boolean = false;
+ // lastChar,
+ // nextChar;
+
+ if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; }
+ if (silent) { return false; } // don't run any pairs in validation mode
+ if (start + 4 >= max) { return false; }
+ if (state.src.charCodeAt(start + 1) !== 0x7E/* ~ */) { return false; }
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ var lastChar:Number = start > 0 ? state.src.charCodeAt(start - 1) : -1;
+ var nextChar:Number = state.src.charCodeAt(start + 2);
+
+ if (lastChar === 0x7E/* ~ */) { return false; }
+ if (nextChar === 0x7E/* ~ */) { return false; }
+ if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
+
+ var pos:int = start + 2;
+ while (pos < max && state.src.charCodeAt(pos) === 0x7E/* ~ */) { pos++; }
+ if (pos > start + 3) {
+ // sequence of 4+ markers taking as literal, same as in a emphasis
+ state.position += pos - start;
+ if (!silent) { state.pending += state.src.slice(start, pos); }
+ return true;
+ }
+
+ state.position = start + 2;
+ var stack:int = 1;
+
+ while (state.position + 1 < max) {
+ if (state.src.charCodeAt(state.position) === 0x7E/* ~ */) {
+ if (state.src.charCodeAt(state.position + 1) === 0x7E/* ~ */) {
+ lastChar = state.src.charCodeAt(state.position - 1);
+ nextChar = state.position + 2 < max ? state.src.charCodeAt(state.position + 2) : -1;
+ if (nextChar !== 0x7E/* ~ */ && lastChar !== 0x7E/* ~ */) {
+ if (lastChar !== 0x20 && lastChar !== 0x0A) {
+ // closing '~~'
+ stack--;
+ } else if (nextChar !== 0x20 && nextChar !== 0x0A) {
+ // opening '~~'
+ stack++;
+ } // else {
+ // // standalone ' ~~ ' indented with spaces
+ // }
+ if (stack <= 0) {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+
+ state.parser.skipToken(state);
+ }
+
+ if (!found) {
+ // parser failed to find ending tag, so it's not valid emphasis
+ state.position = start;
+ return false;
+ }
+
+ // found!
+ state.posMax = state.position;
+ state.position = start + 2;
+
+ if (!silent) {
+ state.push(new TagToken('del_open',state.level++));
+ // state.push({ type: 'del_open', level: state.level++ });
+ state.parser.tokenize(state);
+ state.push(new TagToken('del_close',--state.level));
+ // state.push({ type: 'del_close', level: --state.level });
+ }
+
+ state.position = state.posMax + 2;
+ state.posMax = max;
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Emphasis.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Emphasis.as
index 5fba8e1..e1fb1b9 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Emphasis.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Emphasis.as
@@ -18,6 +18,9 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ /**
+ * Process *this* and _that_
+ */
public class Emphasis extends Rule
{
private function Emphasis()
@@ -34,15 +37,172 @@ package org.apache.royale.markdown
return _instance;
}
+ private function isAlphaNum(code:Number):Boolean
+ {
+ return (code >= 0x30 /* 0 */ && code <= 0x39 /* 9 */) ||
+ (code >= 0x41 /* A */ && code <= 0x5A /* Z */) ||
+ (code >= 0x61 /* a */ && code <= 0x7A /* z */);
+ }
+
+ // parse sequence of emphasis markers,
+ // "start" should point at a valid marker
+ private function scanDelims(state:InlineState, start:int):DelimDetails
+ {
+ var pos:int = start;
+ var canOpen:Boolean = true;
+ var canClose:Boolean = true;
+ var max:int = state.posMax;
+ var marker:Number = state.src.charCodeAt(start);
+
+ var lastChar:int = start > 0 ? state.src.charCodeAt(start - 1) : -1;
+
+ while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
+ if (pos >= max) { canOpen = false; }
+ var count:int = pos - start;
+
+ if (count >= 4) {
+ // sequence of four or more unescaped markers can't start/end an emphasis
+ canOpen = canClose = false;
+ } else {
+ var nextChar:int = pos < max ? state.src.charCodeAt(pos) : -1;
+
+ // check whitespace conditions
+ if (nextChar === 0x20 || nextChar === 0x0A) { canOpen = false; }
+ if (lastChar === 0x20 || lastChar === 0x0A) { canClose = false; }
+
+ if (marker === 0x5F /* _ */) {
+ // check if we aren't inside the word
+ if (isAlphaNum(lastChar)) { canOpen = false; }
+ if (isAlphaNum(nextChar)) { canClose = false; }
+ }
+ }
+
+ return new DelimDetails(canOpen,canClose,count);
+ }
+
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:InlineState = istate as InlineState;
+ var max:int = state.posMax;
+ var start:int = state.position;
+ var marker:Number = state.src.charCodeAt(start);
+ var found:Boolean = false;
+
+ if (marker !== 0x5F/* _ */ && marker !== 0x2A /* * */) { return false; }
+ if (silent) { return false; } // don't run any pairs in validation mode
+
+ var res:DelimDetails = scanDelims(state, start);
+ var startCount:int = res.delims;
+ if (!res.canOpen) {
+ state.position += startCount;
+ if (!silent) { state.pending += state.src.slice(start, state.position); }
+ return true;
+ }
+
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ state.position = start + startCount;
+ var stack:Array = [ startCount ];
+
+ while (state.position < max)
+ {
+ if (state.src.charCodeAt(state.position) === marker)
+ {
+ res = scanDelims(state, state.position);
+ var count:int = res.delims;
+ if (res.canClose)
+ {
+ var oldCount:int = stack.pop();
+ var newCount:int = count;
+
+ while (oldCount !== newCount)
+ {
+ if (newCount < oldCount) {
+ stack.push(oldCount - newCount);
+ break;
+ }
+
+ // assert(newCount > oldCount)
+ newCount -= oldCount;
+
+ if (stack.length === 0) { break; }
+ state.position += oldCount;
+ oldCount = stack.pop();
+ }
+
+ if (stack.length === 0) {
+ startCount = oldCount;
+ found = true;
+ break;
+ }
+ state.position += count;
+ continue;
+ }
+
+ if (res.canOpen) { stack.push(count); }
+ state.position += count;
+ continue;
+ }
+
+ state.parser.skipToken(state);
+ }
+
+ if (!found) {
+ // parser failed to find ending tag, so it's not valid emphasis
+ state.position = start;
+ return false;
+ }
+
+ // found!
+ state.posMax = state.position;
+ state.position = start + startCount;
+
+ if (!silent) {
+ if (startCount === 2 || startCount === 3) {
+ state.push(new TagToken('strong_open',state.level++));
+ // state.push({ type: 'strong_open', level: state.level++ });
+ }
+ if (startCount === 1 || startCount === 3) {
+ state.push(new TagToken('em_open',state.level++));
+ // state.push({ type: 'em_open', level: state.level++ });
+ }
+
+ state.parser.tokenize(state);
+
+ if (startCount === 1 || startCount === 3) {
+ state.push(new TagToken('em_close',--state.level));
+ // state.push({ type: 'em_close', level: --state.level });
+ }
+ if (startCount === 2 || startCount === 3) {
+ state.push(new TagToken('strong_close',--state.level));
+ // state.push({ type: 'strong_close', level: --state.level });
+ }
+ }
+
+ state.position = state.posMax + startCount;
+ state.posMax = max;
+ return true;
+
}
}
+}
+class DelimDetails
+{
+ public function DelimDetails(canOpen:Boolean,canClose:Boolean,delims:int)
+ {
+ this.canOpen = canOpen;
+ this.canClose = canClose;
+ this.delims = delims;
+ }
+ public var canOpen:Boolean;
+ public var canClose:Boolean;
+ public var delims:int;
+
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Entity.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Entity.as
index 1908a8b..0486d1e 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Entity.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Entity.as
@@ -18,6 +18,9 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ /**
+ * Process html entity - {, ¯, ", ...
+ */
public class Entity extends Rule
{
private function Entity()
@@ -34,15 +37,83 @@ package org.apache.royale.markdown
return _instance;
}
+ private var DIGITAL_RE:RegExp = /^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i;
+ private var NAMED_RE:RegExp = /^&([a-z][a-z0-9]{1,31});/i;
+
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:InlineState = istate as InlineState;
+ var pos:int = state.position;
+ var max:int = state.posMax;
+
+ if (state.src.charCodeAt(pos) !== 0x26/* & */) { return false; }
+
+ if (pos + 1 < max) {
+ var ch:Number = state.src.charCodeAt(pos + 1);
+
+ if (ch === 0x23 /* # */) {
+ var match:Array = state.src.slice(pos).match(DIGITAL_RE);
+ if (match) {
+ if (!silent) {
+ var code:int = match[1][0].toLowerCase() === 'x' ? parseInt(match[1].slice(1), 16) : parseInt(match[1], 10);
+ state.pending += isValidEntityCode(code) ? fromCodePoint(code) : fromCodePoint(0xFFFD);
+ }
+ state.position += match[0].length;
+ return true;
+ }
+ } else {
+ match = state.src.slice(pos).match(NAMED_RE);
+ if (match) {
+ var decoded:String = decodeEntity(match[1]);
+ if (match[1] !== decoded) {
+ if (!silent) { state.pending += decoded; }
+ state.position += match[0].length;
+ return true;
+ }
+ }
+ }
+ }
+
+ if (!silent) { state.pending += '&'; }
+ state.position++;
+ return true;
+
}
+ private function isValidEntityCode(c:int):Boolean
+ {
+ /*eslint no-bitwise:0*/
+ // broken sequence
+ if (c >= 0xD800 && c <= 0xDFFF) { return false; }
+ // never used
+ if (c >= 0xFDD0 && c <= 0xFDEF) { return false; }
+ if ((c & 0xFFFF) === 0xFFFF || (c & 0xFFFF) === 0xFFFE) { return false; }
+ // control codes
+ if (c >= 0x00 && c <= 0x08) { return false; }
+ if (c === 0x0B) { return false; }
+ if (c >= 0x0E && c <= 0x1F) { return false; }
+ if (c >= 0x7F && c <= 0x9F) { return false; }
+ // out of range
+ if (c > 0x10FFFF) { return false; }
+ return true;
+ }
+ private function fromCodePoint(c:int):String
+ {
+ /*eslint no-bitwise:0*/
+ if (c > 0xffff) {
+ c -= 0x10000;
+ var surrogate1:int = 0xd800 + (c >> 10),
+ surrogate2:int = 0xdc00 + (c & 0x3ff);
+
+ return String.fromCharCode(surrogate1, surrogate2);
+ }
+ return String.fromCharCode(c);
+ }
}
}
\ No newline at end of file
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Escape.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Escape.as
index 5071cab..79dcb30 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Escape.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Escape.as
@@ -22,6 +22,12 @@ package org.apache.royale.markdown
{
private function Escape()
{
+ ESCAPED = [];
+ // for (var i:int = 0; i < 256; i++)
+ // ESCAPED.push(0);
+
+ '\\!"#$%&\'()*+,./:;<=>?@[]^_`{|}~-'
+ .split('').forEach(function(ch:String):void { ESCAPED[ch.charCodeAt(0)] = 1; });
}
@@ -33,15 +39,61 @@ package org.apache.royale.markdown
return _instance;
}
+// Proceess escaped chars and hardbreaks
+
+ private var ESCAPED:Array;
+
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var ch
+ var state:InlineState = istate as InlineState;
+ var pos:int = state.position;
+ var max:int = state.posMax;
+
+ if (state.src.charCodeAt(pos) !== 0x5C/* \ */) { return false; }
+
+ pos++;
+
+ if (pos < max) {
+ var ch:Number = state.src.charCodeAt(pos);
+
+ if (ch < 256 && ESCAPED[ch]) {
+ if (!silent) { state.pending += state.src[pos]; }
+ state.position += 2;
+ return true;
+ }
+
+ if (ch == 0x0A) {
+ if (!silent) {
+ state.push(new TagToken('hardbreak',state.level));
+ // state.push({
+ // type: 'hardbreak',
+ // level: state.level
+ // });
+ }
+
+ pos++;
+ // skip leading whitespaces from next line
+ while (pos < max && state.src.charCodeAt(pos) === 0x20)
+ pos++;
+
+ state.position = pos;
+ return true;
+ }
+ }
+
+ if (!silent) { state.pending += '\\'; }
+ state.position++;
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/FootnoteRef.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/FootnoteRef.as
index 04b9a3d..42f2a87 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/FootnoteRef.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/FootnoteRef.as
@@ -18,6 +18,9 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ /**
+ * Process footnote references ([^...])
+ */
public class FootnoteRef extends Rule
{
private function FootnoteRef()
@@ -39,9 +42,64 @@ package org.apache.royale.markdown
* @langversion 3.0
* @productversion Royale 0.9.9 *
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:InlineState = istate as InlineState;
+ var max:int = state.posMax;
+ var start:int = state.position;
+
+ // should be at least 4 chars - "[^x]"
+ if (start + 3 > max) { return false; }
+
+ if (!state.env.footnotes || !state.env.footnotes.refs) { return false; }
+ if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }
+ if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ for (var pos:int = start + 2; pos < max; pos++) {
+ if (state.src.charCodeAt(pos) === 0x20) { return false; }
+ if (state.src.charCodeAt(pos) === 0x0A) { return false; }
+ if (state.src.charCodeAt(pos) === 0x5D /* ] */) {
+ break;
+ }
+ }
+
+ if (pos === start + 2) { return false; } // no empty footnote labels
+ if (pos >= max) { return false; }
+ pos++;
+
+ var label:String = state.src.slice(start + 2, pos - 1);
+ if (typeof state.env.footnotes.refs[':' + label] === 'undefined') { return false; }
+
+ if (!silent) {
+ if (!state.env.footnotes.list) { state.env.footnotes.list = []; }
+
+ if (state.env.footnotes.refs[':' + label] < 0) {
+ var footnoteId:int = state.env.footnotes.list.length;
+ state.env.footnotes.list[footnoteId] = { label: label, count: 0 };
+ state.env.footnotes.refs[':' + label] = footnoteId;
+ } else {
+ footnoteId = state.env.footnotes.refs[':' + label];
+ }
+
+ var footnoteSubId:int = state.env.footnotes.list[footnoteId].count;
+ state.env.footnotes.list[footnoteId].count++;
+ var token:TagToken = new TagToken('footnote_ref',state.level);
+ token.id = footnoteId;
+ token.subId = footnoteSubId;
+ state.push(token);
+ // state.push({
+ // type: 'footnote_ref',
+ // id: footnoteId,
+ // subId: footnoteSubId,
+ // level: state.level
+ // });
+ }
+
+ state.position = pos;
+ state.posMax = max;
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Htmltag.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Htmltag.as
index 73a9699..28bc14c 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Htmltag.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Htmltag.as
@@ -18,6 +18,9 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ /**
+ * Process html tags
+ */
public class Htmltag extends Rule
{
private function Htmltag()
@@ -35,13 +38,147 @@ package org.apache.royale.markdown
}
/**
+ * This code was copied from Remarkable. And the code is definitely remarkable... ;)
+ * It uses very complex functional composition to build a RegExp for finding HTML tags.
+ * I'd like to replace it with something that's easier to follow, but it'll do for now.
+ */
+
+ private function replace(regex:*=undefined, options:*=undefined):* {
+ regex = regex.source;
+ options = options || '';
+
+ return function self(name:*, val:*):* {
+ if (!name) {
+ return new RegExp(regex, options);
+ }
+ val = val.source || val;
+ regex = regex.replace(name, val);
+ return self;
+ };
+ }
+
+
+ private var attr_name:RegExp = /[a-zA-Z_:][a-zA-Z0-9:._-]*/;
+
+ private var unquoted:RegExp = /[^"'=<>`\x00-\x20]+/;
+ private var single_quoted:RegExp = /'[^']*'/;
+ private var double_quoted:RegExp = /"[^"]*"/;
+
+ private var _attr_value:RegExp;
+ private function get attr_value():RegExp
+ {
+ if(!_attr_value)
+ {
+ _attr_value = replace(/(?:unquoted|single_quoted|double_quoted)/)
+ ('unquoted', unquoted)
+ ('single_quoted', single_quoted)
+ ('double_quoted', double_quoted)
+ ();
+ }
+ return _attr_value;
+ }
+
+ private var _attribute:RegExp;
+ private function get attribute():RegExp
+ {
+ if(!_attribute)
+ {
+ _attribute = replace(/(?:\s+attr_name(?:\s*=\s*attr_value)?)/)
+ ('attr_name', attr_name)
+ ('attr_value', attr_value)
+ ();
+ }
+ return _attribute;
+ }
+
+ private var _open_tag:RegExp;
+ private function get open_tag():RegExp
+ {
+ if(!_open_tag)
+ {
+ _open_tag = replace(/<[A-Za-z][A-Za-z0-9]*attribute*\s*\/?>/)
+ ('attribute', attribute)
+ ();
+ }
+ return _open_tag;
+ }
+
+ private var close_tag:RegExp = /<\/[A-Za-z][A-Za-z0-9]*\s*>/;
+ private var comment:RegExp = /<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->/;
+ private var processing:RegExp = /<[?].*?[?]>/;
+ private var declaration:RegExp = /<![A-Z]+\s+[^>]*>/;
+ private var cdata:RegExp = /<!\[CDATA\[[\s\S]*?\]\]>/;
+
+ private var _HTML_TAG_RE:RegExp;
+
+ private function get HTML_TAG_RE():RegExp
+ {
+ if(!_HTML_TAG_RE)
+ {
+ _HTML_TAG_RE = replace(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)
+ ('open_tag', open_tag)
+ ('close_tag', close_tag)
+ ('comment', comment)
+ ('processing', processing)
+ ('declaration', declaration)
+ ('cdata', cdata)
+ ();
+ }
+ return _HTML_TAG_RE;
+ }
+ /**
+ * Here's the end of that mess...
+ */
+
+ private function isLetter(ch:Number):Boolean
+ {
+ var lc:Number = ch | 0x20; // to lower case
+ return (lc >= 0x61/* a */) && (lc <= 0x7a/* z */);
+ }
+
+ /**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:InlineState = istate as InlineState;
+ var pos:int = state.position;
+
+ if (!state.options.html) { return false; }
+
+ // Check start
+ var max:int = state.posMax;
+ if (state.src.charCodeAt(pos) !== 0x3C/* < */ ||
+ pos + 2 >= max) {
+ return false;
+ }
+
+ // Quick fail on second char
+ var ch:Number = state.src.charCodeAt(pos + 1);
+ if (ch !== 0x21/* ! */ &&
+ ch !== 0x3F/* ? */ &&
+ ch !== 0x2F/* / */ &&
+ !isLetter(ch)) {
+ return false;
+ }
+
+ var match:Array = state.src.slice(pos).match(HTML_TAG_RE);
+ if (!match) { return false; }
+
+ if (!silent) {
+ state.push(new ContentToken('htmltag',state.src.slice(pos, pos + match[0].length),state.level));
+ // state.push({
+ // type: 'htmltag',
+ // content: state.src.slice(pos, pos + match[0].length),
+ // level: state.level
+ // });
+ }
+ state.position += match[0].length;
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/InlineFootnote.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/InlineFootnote.as
index 28cc84b..99c8aa6 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/InlineFootnote.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/InlineFootnote.as
@@ -18,6 +18,10 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ import org.apache.royale.markdown.helpers.parseLinkLabel;
+ /**
+ * Process inline footnotes (^[...])
+ */
public class InlineFootnote extends Rule
{
private function InlineFootnote()
@@ -37,11 +41,60 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // var labelStart,
+ // labelEnd,
+ // footnoteId,
+ // oldLength,
+ var state:InlineState = istate as InlineState;
+ var max:int = state.posMax;
+ var start:int = state.position;
+
+ if (start + 2 >= max) { return false; }
+ if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; }
+ if (state.src.charCodeAt(start + 1) !== 0x5B/* [ */) { return false; }
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ var labelStart:int = start + 2;
+ var labelEnd:int = parseLinkLabel(state, start + 1);
+
+ // parser failed to find ']', so it's not a valid note
+ if (labelEnd < 0) { return false; }
+
+ // We found the end of the link, and know for a fact it's a valid link;
+ // so all that's left to do is to call tokenizer.
+ //
+ if (!silent) {
+ if (!state.env.footnotes) { state.env.footnotes = {}; }
+ if (!state.env.footnotes.list) { state.env.footnotes.list = []; }
+ var footnoteId:int = state.env.footnotes.list.length;
+
+ state.position = labelStart;
+ state.posMax = labelEnd;
+ var token:TagToken = new TagToken('footnote_ref',state.level);
+ token.id = footnoteId;
+ state.push(token);
+ // state.push({
+ // type: 'footnote_ref',
+ // id: footnoteId,
+ // level: state.level
+ // });
+ state.linkLevel++;
+ var oldLength:int = state.tokens.length;
+ state.parser.tokenize(state);
+ state.env.footnotes.list[footnoteId] = { tokens: state.tokens.splice(oldLength) };
+ state.linkLevel--;
+ }
+
+ state.position = labelEnd + 1;
+ state.posMax = max;
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Ins.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Ins.as
index 0e783c2..184dc1d 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Ins.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Ins.as
@@ -18,6 +18,9 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ /**
+ * Process ++inserted text++
+ */
public class Ins extends Rule
{
private function Ins()
@@ -37,11 +40,97 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:InlineState = istate as InlineState;
+ var max:int = state.posMax;
+ var start:int = state.position;
+ var found:Boolean = false;
+
+ if (state.src.charCodeAt(start) !== 0x2B/* + */) { return false; }
+ if (silent) { return false; } // don't run any pairs in validation mode
+ if (start + 4 >= max) { return false; }
+ if (state.src.charCodeAt(start + 1) !== 0x2B/* + */) { return false; }
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ var lastChar:Number = start > 0 ? state.src.charCodeAt(start - 1) : -1;
+ var nextChar:Number = state.src.charCodeAt(start + 2);
+
+ if (lastChar === 0x2B/* + */) { return false; }
+ if (nextChar === 0x2B/* + */) { return false; }
+ if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
+
+ var pos:int = start + 2;
+ while (pos < max && state.src.charCodeAt(pos) === 0x2B/* + */) { pos++; }
+ if (pos !== start + 2) {
+ // sequence of 3+ markers taking as literal, same as in a emphasis
+ state.position += pos - start;
+ if (!silent) { state.pending += state.src.slice(start, pos); }
+ return true;
+ }
+
+ state.position = start + 2;
+ var stack:int = 1;
+
+ while (state.position + 1 < max) {
+ if (state.src.charCodeAt(state.position) === 0x2B/* + */)
+ {
+ if (state.src.charCodeAt(state.position + 1) === 0x2B/* + */)
+ {
+ lastChar = state.src.charCodeAt(state.position - 1);
+ nextChar = state.position + 2 < max ? state.src.charCodeAt(state.position + 2) : -1;
+ if (nextChar !== 0x2B/* + */ && lastChar !== 0x2B/* + */)
+ {
+ if (lastChar !== 0x20 && lastChar !== 0x0A)
+ {
+ // closing '++'
+ stack--;
+ } else if (nextChar !== 0x20 && nextChar !== 0x0A) {
+ // opening '++'
+ stack++;
+ } // else {
+ // // standalone ' ++ ' indented with spaces
+ // }
+ if (stack <= 0)
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+
+ state.parser.skipToken(state);
+ }
+
+ if (!found)
+ {
+ // parser failed to find ending tag, so it's not valid emphasis
+ state.position = start;
+ return false;
+ }
+
+ // found!
+ state.posMax = state.position;
+ state.position = start + 2;
+
+ if (!silent)
+ {
+ state.push(new TagToken('ins_open',state.level++));
+ // state.push({ type: 'ins_open', level: state.level++ });
+ state.parser.tokenize(state);
+ state.push(new TagToken('ins_close',--state.level));
+ // state.push({ type: 'ins_close', level: --state.level });
+ }
+
+ state.position = state.posMax + 2;
+ state.posMax = max;
+ return true;
+
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Links.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Links.as
index d876ab6..4b1a8d9 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Links.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Links.as
@@ -18,6 +18,12 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ import org.apache.royale.markdown.helpers.parseLinkLabel;
+ import org.apache.royale.markdown.helpers.parseLinkDestination;
+ import org.apache.royale.markdown.helpers.parseLinkTitle;
+ import org.apache.royale.markdown.helpers.normalizeReference;
+ import org.apache.royale.markdown.helpers.HRef;
+
public class Links extends Rule
{
private function Links()
@@ -37,11 +43,186 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:InlineState = istate as InlineState;
+ var isImage:Boolean = false;
+ var oldPos:int = state.position;
+ var max:int = state.posMax;
+ var start:int = state.position;
+ var marker:Number = state.src.charCodeAt(start);
+
+ if (marker === 0x21/* ! */)
+ {
+ isImage = true;
+ marker = state.src.charCodeAt(++start);
+ }
+
+ if (marker !== 0x5B/* [ */) { return false; }
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ var labelStart:int = start + 1;
+ var labelEnd:int = parseLinkLabel(state, start);
+
+ // parser failed to find ']', so it's not a valid link
+ if (labelEnd < 0) { return false; }
+
+ var pos:int = labelEnd + 1;
+ if (pos < max && state.src.charCodeAt(pos) === 0x28/* ( */)
+ {
+ //
+ // Inline link
+ //
+
+ // [link]( <href> "title" )
+ // ^^ skipping these spaces
+ pos++;
+ for (; pos < max; pos++)
+ {
+ var code:Number = state.src.charCodeAt(pos);
+ if (code !== 0x20 && code !== 0x0A)
+ break;
+ }
+ if (pos >= max)
+ return false;
+
+ // [link]( <href> "title" )
+ // ^^^^^^ parsing link destination
+ start = pos;
+ if (parseLinkDestination(state, pos))
+ {
+ var href:String = state.linkContent;
+ pos = state.position;
+ } else {
+ href = '';
+ }
+
+ // [link]( <href> "title" )
+ // ^^ skipping these spaces
+ start = pos;
+ for (; pos < max; pos++)
+ {
+ code = state.src.charCodeAt(pos);
+ if (code !== 0x20 && code !== 0x0A) { break; }
+ }
+
+ // [link]( <href> "title" )
+ // ^^^^^^^ parsing link title
+ if (pos < max && start !== pos && parseLinkTitle(state, pos))
+ {
+ var title:String = state.linkContent;
+ pos = state.position;
+
+ // [link]( <href> "title" )
+ // ^^ skipping these spaces
+ for (; pos < max; pos++)
+ {
+ code = state.src.charCodeAt(pos);
+ if (code !== 0x20 && code !== 0x0A) { break; }
+ }
+ } else {
+ title = '';
+ }
+
+ if (pos >= max || state.src.charCodeAt(pos) !== 0x29/* ) */)
+ {
+ state.position = oldPos;
+ return false;
+ }
+ pos++;
+ } else {
+ //
+ // Link reference
+ //
+
+ // do not allow nested reference links
+ if (state.linkLevel > 0) { return false; }
+
+ // [foo] [bar]
+ // ^^ optional whitespace (can include newlines)
+ for (; pos < max; pos++)
+ {
+ code = state.src.charCodeAt(pos);
+ if (code !== 0x20 && code !== 0x0A) { break; }
+ }
+
+ if (pos < max && state.src.charCodeAt(pos) === 0x5B/* [ */)
+ {
+ start = pos + 1;
+ pos = parseLinkLabel(state, pos);
+ if (pos >= 0) {
+ var label:String = state.src.slice(start, pos++);
+ } else {
+ pos = start - 1;
+ }
+ }
+
+ // covers label === '' and label === undefined
+ // (collapsed reference link and shortcut reference link respectively)
+ if (!label) {
+ if (label == null) {
+ pos = labelEnd + 1;
+ }
+ label = state.src.slice(labelStart, labelEnd);
+ }
+
+ var ref:HRef = state.env.references[normalizeReference(label)];
+ if (!ref) {
+ state.position = oldPos;
+ return false;
+ }
+ href = ref.href;
+ title = ref.title;
+ }
+
+ //
+ // We found the end of the link, and know for a fact it's a valid link;
+ // so all that's left to do is to call tokenizer.
+ //
+ if (!silent) {
+ state.position = labelStart;
+ state.posMax = labelEnd;
+
+ if (isImage) {
+ // use data on links for alt
+ var linkToken:LinkToken = new LinkToken('image',state.level);
+ linkToken.title = title;
+ linkToken.href = href;
+ linkToken.data = state.src.substr(labelStart, labelEnd - labelStart);
+ state.push(linkToken);
+ // state.push({
+ // type: 'image',
+ // src: href,
+ // title: title,
+ // alt: state.src.substr(labelStart, labelEnd - labelStart),
+ // level: state.level
+ // });
+ } else {
+ linkToken = new LinkToken('link_open',state.level++);
+ linkToken.title = title;
+ linkToken.href = href;
+ state.push(linkToken);
+ // state.push({
+ // type: 'link_open',
+ // href: href,
+ // title: title,
+ // level: state.level++
+ // });
+ state.linkLevel++;
+ state.parser.tokenize(state);
+ state.linkLevel--;
+ state.push(new TagToken('link_close',--state.level));
+ // state.push({ type: 'link_close', level: --state.level });
+ }
+ }
+
+ state.position = pos;
+ state.posMax = max;
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Mark.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Mark.as
index 27a856b..19eb026 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Mark.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Mark.as
@@ -18,6 +18,9 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ /**
+ * Process ==highlighted text==
+ */
public class Mark extends Rule
{
private function Mark()
@@ -37,11 +40,94 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ // pos,
+ // stack,
+ var state:InlineState = istate as InlineState;
+ var max:int = state.posMax;
+ var start:int = state.position;
+ var found:Boolean = false;
+ // lastChar,
+ // nextChar;
+
+ if (state.src.charCodeAt(start) !== 0x3D/* = */) { return false; }
+ if (silent) { return false; } // don't run any pairs in validation mode
+ if (start + 4 >= max) { return false; }
+ if (state.src.charCodeAt(start + 1) !== 0x3D/* = */) { return false; }
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ var lastChar:Number = start > 0 ? state.src.charCodeAt(start - 1) : -1;
+ var nextChar:Number = state.src.charCodeAt(start + 2);
+
+ if (lastChar === 0x3D/* = */) { return false; }
+ if (nextChar === 0x3D/* = */) { return false; }
+ if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
+
+ var pos:int = start + 2;
+ while (pos < max && state.src.charCodeAt(pos) === 0x3D/* = */) { pos++; }
+ if (pos !== start + 2) {
+ // sequence of 3+ markers taking as literal, same as in a emphasis
+ state.position += pos - start;
+ if (!silent) { state.pending += state.src.slice(start, pos); }
+ return true;
+ }
+
+ state.position = start + 2;
+ var stack:int = 1;
+
+ while (state.position + 1 < max) {
+ if (state.src.charCodeAt(state.position) === 0x3D/* = */) {
+ if (state.src.charCodeAt(state.position + 1) === 0x3D/* = */) {
+ lastChar = state.src.charCodeAt(state.position - 1);
+ nextChar = state.position + 2 < max ? state.src.charCodeAt(state.position + 2) : -1;
+ if (nextChar !== 0x3D/* = */ && lastChar !== 0x3D/* = */) {
+ if (lastChar !== 0x20 && lastChar !== 0x0A) {
+ // closing '=='
+ stack--;
+ } else if (nextChar !== 0x20 && nextChar !== 0x0A) {
+ // opening '=='
+ stack++;
+ } // else {
+ // // standalone ' == ' indented with spaces
+ // }
+ if (stack <= 0) {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+
+ state.parser.skipToken(state);
+ }
+
+ if (!found) {
+ // parser failed to find ending tag, so it's not valid emphasis
+ state.position = start;
+ return false;
+ }
+
+ // found!
+ state.posMax = state.position;
+ state.position = start + 2;
+
+ if (!silent) {
+ state.push(new TagToken('mark_open',state.level++));
+ // state.push({ type: 'mark_open', level: state.level++ });
+ state.parser.tokenize(state);
+ state.push(new TagToken('mark_close',--state.level));
+ // state.push({ type: 'mark_close', level: --state.level });
+ }
+
+ state.position = state.posMax + 2;
+ state.posMax = max;
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Newline.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Newline.as
index 7216084..ac04e1b 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Newline.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Newline.as
@@ -37,11 +37,71 @@ package org.apache.royale.markdown
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ var state:InlineState = istate as InlineState;
+ var pos:int = state.position;
+
+ if (state.src.charCodeAt(pos) !== 0x0A/* \n */)
+ return false;
+
+ var pmax:int = state.pending.length - 1;
+ var max:int = state.posMax;
+
+ // ' \n' -> hardbreak
+ // Lookup in pending chars is bad practice! Don't copy to other rules!
+ // Pending string is stored in concat mode, indexed lookups will cause
+ // convertion to flat mode.
+ if (!silent)
+ {
+ if (pmax >= 0 && state.pending.charCodeAt(pmax) === 0x20)
+ {
+ if (pmax >= 1 && state.pending.charCodeAt(pmax - 1) === 0x20)
+ {
+ // Strip out all trailing spaces on this line.
+ for (var i:int = pmax - 2; i >= 0; i--)
+ {
+ if (state.pending.charCodeAt(i) !== 0x20) {
+ state.pending = state.pending.substring(0, i + 1);
+ break;
+ }
+ }
+ state.push(new TagToken('hardbreak',state.level));
+ // state.push({
+ // type: 'hardbreak',
+ // level: state.level
+ // });
+ } else {
+ state.pending = state.pending.slice(0, -1);
+ state.push(new TagToken('softbreak',state.level));
+ // state.push({
+ // type: 'softbreak',
+ // level: state.level
+ // });
+ }
+
+ } else {
+ state.push(new TagToken('softbreak',state.level));
+ // state.push({
+ // type: 'softbreak',
+ // level: state.level
+ // });
+ }
+ }
+
+ pos++;
+
+ // skip heading spaces for next line
+ while (pos < max && state.src.charCodeAt(pos) === 0x20)
+ pos++;
+
+ state.position = pos;
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Sub.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Sub.as
index 13c919a..b598937 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Sub.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Sub.as
@@ -18,6 +18,9 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.royale.markdown
{
+ /**
+ * Process ~subscript~
+ */
public class Sub extends Rule
{
private function Sub()
@@ -33,15 +36,71 @@ package org.apache.royale.markdown
return _instance;
}
+ // same as UNESCAPE_MD_RE plus a space
+ private const UNESCAPE_RE:RegExp = /\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g;
+ private const UNESCAPED_SPACE:RegExp = /(^|[^\\])(\\\\)*\s/;
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+
+ var state:InlineState = istate as InlineState;
+ var max:int = state.posMax;
+ var start:int = state.position;
+ var found:Boolean = false;
+
+ if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; }
+ if (silent) { return false; } // don't run any pairs in validation mode
+ if (start + 2 >= max) { return false; }
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ state.position = start + 1;
+
+ while (state.position < max) {
+ if (state.src.charCodeAt(state.position) === 0x7E/* ~ */) {
+ found = true;
+ break;
+ }
+
+ state.parser.skipToken(state);
+ }
+
+ if (!found || start + 1 === state.position) {
+ state.position = start;
+ return false;
+ }
+
+ var content:String = state.src.slice(start + 1, state.position);
+
+ // don't allow unescaped spaces/newlines inside
+ if (content.match(UNESCAPED_SPACE)) {
+ state.position = start;
+ return false;
+ }
+
+ // found!
+ state.posMax = state.position;
+ state.position = start + 1;
+
+ if (!silent) {
+ state.push(new ContentToken('sub',content.replace(UNESCAPE_RE, '$1'),state.level));
+ // state.push({
+ // type: 'sub',
+ // level: state.level,
+ // content: content.replace(UNESCAPE_RE, '$1')
+ // });
+ }
+
+ state.position = state.posMax + 1;
+ state.posMax = max;
+ return true;
+
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Sup.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Sup.as
index a5e1ea7..daf0f46 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Sup.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Sup.as
@@ -34,14 +34,68 @@ package org.apache.royale.markdown
return _instance;
}
+ // same as UNESCAPE_MD_RE plus a space
+ private const UNESCAPE_RE:RegExp = /\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g;
+ private const UNESCAPED_SPACE:RegExp = /(^|[^\\])(\\\\)*\s/;
/**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:InlineState = istate as InlineState;
+ var max:int = state.posMax;
+ var start:int = state.position;
+ var found:Boolean = false;
+
+ if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; }
+ if (silent) { return false; } // don't run any pairs in validation mode
+ if (start + 2 >= max) { return false; }
+ if (state.level >= state.options.maxNesting) { return false; }
+
+ state.position = start + 1;
+
+ while (state.position < max) {
+ if (state.src.charCodeAt(state.position) === 0x5E/* ^ */) {
+ found = true;
+ break;
+ }
+
+ state.parser.skipToken(state);
+ }
+
+ if (!found || start + 1 === state.position) {
+ state.position = start;
+ return false;
+ }
+
+ var content:String = state.src.slice(start + 1, state.position);
+
+ // don't allow unescaped spaces/newlines inside
+ if (content.match(UNESCAPED_SPACE)) {
+ state.position = start;
+ return false;
+ }
+
+ // found!
+ state.posMax = state.position;
+ state.position = start + 1;
+
+ if (!silent) {
+ state.push(new ContentToken('sup',content.replace(UNESCAPE_RE, '$1'),state.level));
+ // state.push({
+ // type: 'sup',
+ // level: state.level,
+ // content: content.replace(UNESCAPE_RE, '$1')
+ // });
+ }
+
+ state.position = state.posMax + 1;
+ state.posMax = max;
+ return true;
+
}
}
diff --git a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Text.as b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Text.as
index 9f9c50f..547d89f 100644
--- a/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Text.as
+++ b/frameworks/projects/Markdown/src/main/royale/org/apache/royale/markdown/rules/inline/Text.as
@@ -35,13 +35,65 @@ package org.apache.royale.markdown
}
/**
+ * Skip text characters for text token, place those to pending buffer and increment current pos
+ * Rule to skip pure text
+ * '{}$%@~+=:' reserved for extentions
+ */
+ private function isTerminatorChar(ch:Number):Boolean
+ {
+ switch (ch) {
+ case 0x0A/* \n */:
+ case 0x5C/* \ */:
+ case 0x60/* ` */:
+ case 0x2A/* * */:
+ case 0x5F/* _ */:
+ case 0x5E/* ^ */:
+ case 0x5B/* [ */:
+ case 0x5D/* ] */:
+ case 0x21/* ! */:
+ case 0x26/* & */:
+ case 0x3C/* < */:
+ case 0x3E/* > */:
+ case 0x7B/* { */:
+ case 0x7D/* } */:
+ case 0x24/* $ */:
+ case 0x25/* % */:
+ case 0x40/* @ */:
+ case 0x7E/* ~ */:
+ case 0x2B/* + */:
+ case 0x3D/* = */:
+ case 0x3A/* : */:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
* parses the rule
* @langversion 3.0
- * @productversion Royale 0.9.9 *
+ * @productversion Royale 0.9.9
+ * @royaleignorecoercion org.apache.royale.markdown.InlineState
*/
- override public function parse(state:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
+ override public function parse(istate:IState, silent:Boolean = false, startLine:int = -1, endLine:int = -1):Boolean
{
- throw new Error("Method not implemented.");
+ var state:InlineState = istate as InlineState;
+ var pos:int = state.position;
+
+ while (pos < state.posMax && !isTerminatorChar(state.src.charCodeAt(pos))) {
+ pos++;
+ }
+
+ if (pos == state.position)
+ return false;
+
+ if (!silent)
+ state.pending += state.src.slice(state.position, pos);
+
+ state.position = pos;
+
+ return true;
+
}
}
Re: [royale-asjs] branch feature/markdown updated: Filled in rules
Posted by Harbs <ha...@gmail.com>.
FYI,
This should be all the parsing code.
Now I need to port the testing code an re-implement the rendering in the “Royale” way of doing it…
That’s probably all I’m doing this week. I have “real” work to do… 😉
> On Jan 16, 2022, at 11:49 PM, harbs@apache.org wrote:
>
> The following commit(s) were added to refs/heads/feature/markdown by this push:
> new ea54f6f Filled in rules
> ea54f6f is described below
>
> commit ea54f6fc6d6d598888c4c945af97c2e1619757eb
> Author: Harbs <harbs@in-tools.com <ma...@in-tools.com>>
> AuthorDate: Sun Jan 16 23:49:28 2022 +0200
>
> Filled in rules
> ---
> .../org/apache/royale/markdown/BlockParser.as | 80 +
> .../org/apache/royale/markdown/BlockState.as | 182 +-
> .../org/apache/royale/markdown/BlockToken.as | 55 +-
> .../org/apache/royale/markdown/ContentToken.as | 38 +-
> .../org/apache/royale/markdown/CoreParser.as | 13 +-
> .../royale/org/apache/royale/markdown/CoreState.as | 42 +
> .../org/apache/royale/markdown/Environment.as | 5 +
> .../royale/org/apache/royale/markdown/IState.as | 8 +-
> .../royale/org/apache/royale/markdown/IToken.as | 12 +
> .../org/apache/royale/markdown/InlineParser.as | 59 +
> .../org/apache/royale/markdown/InlineState.as | 92 +-
> .../markdown/{CoreParser.as => LinkToken.as} | 19 +-
> .../block/BlockQuote.as => MarkdownOptions.as} | 35 +-
> .../org/apache/royale/markdown/MarkdownParser.as | 20 +-
> .../royale/org/apache/royale/markdown/TagToken.as | 37 +-
> .../royale/markdown/{BlockToken.as => Token.as} | 110 +-
> .../helpers/{normalizeReference.as => HRef.as} | 11 +-
> .../apache/royale/markdown/helpers/decodeEntity.as | 1769 ++++++++++++++++++++
> .../royale/markdown/helpers/normalizeReference.as | 6 +
> .../markdown/helpers/parseLinkDestination.as | 102 ++
> .../royale/markdown/helpers/parseLinkLabel.as | 76 +
> .../{normalizeReference.as => parseLinkTitle.as} | 39 +-
> .../{normalizeReference.as => unescapeMd.as} | 17 +-
> ...normalizeReference.as => wrappedInParagraph.as} | 21 +-
> .../apache/royale/markdown/rules/RulesManager.as | 121 +-
> .../royale/markdown/rules/block/BlockQuote.as | 148 +-
> .../org/apache/royale/markdown/rules/block/Code.as | 42 +-
> .../apache/royale/markdown/rules/block/Deflist.as | 254 ++-
> .../apache/royale/markdown/rules/block/Fences.as | 102 +-
> .../apache/royale/markdown/rules/block/Footnote.as | 75 +-
> .../apache/royale/markdown/rules/block/Heading.as | 76 +-
> .../org/apache/royale/markdown/rules/block/Hr.as | 52 +-
> .../royale/markdown/rules/block/Htmlblock.as | 135 +-
> .../apache/royale/markdown/rules/block/Lheading.as | 72 +-
> .../org/apache/royale/markdown/rules/block/List.as | 264 ++-
> .../royale/markdown/rules/block/Paragraph.as | 77 +-
> .../apache/royale/markdown/rules/block/Table.as | 209 ++-
> .../org/apache/royale/markdown/rules/core/Abbr.as | 72 +-
> .../org/apache/royale/markdown/rules/core/Abbr2.as | 90 +-
> .../org/apache/royale/markdown/rules/core/Block.as | 14 +-
> .../royale/markdown/rules/core/Footnote_tail.as | 86 +-
> .../apache/royale/markdown/rules/core/Inline.as | 19 +-
> .../royale/markdown/rules/core/References.as | 105 +-
> .../royale/markdown/rules/core/Replacements.as | 72 +-
> .../royale/markdown/rules/core/Smartquotes.as | 141 +-
> .../royale/markdown/rules/inline/Autolink.as | 100 +-
> .../royale/markdown/rules/inline/Backticks.as | 57 +-
> .../org/apache/royale/markdown/rules/inline/Del.as | 92 +-
> .../royale/markdown/rules/inline/Emphasis.as | 166 +-
> .../apache/royale/markdown/rules/inline/Entity.as | 77 +-
> .../apache/royale/markdown/rules/inline/Escape.as | 58 +-
> .../royale/markdown/rules/inline/FootnoteRef.as | 62 +-
> .../apache/royale/markdown/rules/inline/Htmltag.as | 143 +-
> .../royale/markdown/rules/inline/InlineFootnote.as | 59 +-
> .../org/apache/royale/markdown/rules/inline/Ins.as | 95 +-
> .../apache/royale/markdown/rules/inline/Links.as | 187 ++-
> .../apache/royale/markdown/rules/inline/Mark.as | 92 +-
> .../apache/royale/markdown/rules/inline/Newline.as | 66 +-
> .../org/apache/royale/markdown/rules/inline/Sub.as | 65 +-
> .../org/apache/royale/markdown/rules/inline/Sup.as | 60 +-
> .../apache/royale/markdown/rules/inline/Text.as | 58 +-
> 61 files changed, 6169 insertions(+), 342 deletions(-)