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 - &#123;, &#xAF;, &quot;, ...
+	 */
 	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(-)