This is a test Markdown file
It has some emphasis and some strong stuff to talk about
SomeCodeIsEvenDisplayed ()
{
public void IntoSomething ()
{
Console.WriteLine ("That looks like code");
}
}
You can even embed cool url like my website.
%{ | |
using System; | |
using System.IO; | |
using System.Linq; | |
using System.Collections.Generic; | |
namespace MarkdownParser | |
{ | |
class Counter | |
{ | |
public Counter (int count = 0) | |
{ | |
Count = count; | |
} | |
public int Count { | |
get; | |
set; | |
} | |
} | |
public class Parser | |
{ | |
int yacc_verbose_flag = 0; | |
public IEnumerable<IBlock> Parse (string input) | |
{ | |
return Parse (new StringReader (input)); | |
} | |
public IEnumerable<IBlock> Parse (TextReader reader) | |
{ | |
var lexer = new Tokenizer (reader); | |
return (IEnumerable<IBlock>)this.yyparse (lexer); | |
} | |
%} | |
%token ERROR | |
%token TEXT /* A string of character until the next newline/span */ | |
%token EMPTY_LINE | |
%token NEWLINE | |
%token TRIPLE_QUOTE | |
%token HASH | |
%token HEADING_LINE | |
%token HEADING_LINE_DASH | |
%token EMPH_MARKER | |
%token STRONG_MARKER | |
%token BULLET_MARKER | |
%token INLINE_CODE_MARKER | |
%token URL_MARKER | |
%start document | |
%% | |
document: opt_block_list { $$ = $1; ((List<IBlock>)$$).Reverse (); } | |
opt_block_list | |
: /* empty */ { $$ = new List<IBlock> (); } | |
| block opt_block_list { ((List<IBlock>)$2).Add ((IBlock)$1); $$ = $2; } | |
block | |
: block_inner EMPTY_LINE { $$ = $1; } | |
block_inner | |
: paragraph { $$ = $1; } | |
| heading { $$ = $1; } | |
| code { $$ = $1; } | |
| bullet_list { $$ = $1; } | |
paragraph: span_list NEWLINE { $$ = new Paragraph ((IList<ISpan>)$1); } | |
heading | |
: atx_heading { $$ = $1; } | |
/* | setex_heading { $$ = $1; }*/ | |
code | |
: TRIPLE_QUOTE TEXT NEWLINE opt_text_list TRIPLE_QUOTE NEWLINE { $$ = new Code (language: ((string)$2).Trim (), content: string.Join (Environment.NewLine, (IEnumerable<string>)$4)); } | |
opt_text_list: opt_text_list_inner { $$ = $1; ((List<string>)$1).Reverse (); } | |
opt_text_list_inner | |
: /* empty */ { $$ = new List<string> (); } | |
| text opt_text_list_inner { ((List<string>)$2).Add ((string)$1); $$ = $2; } | |
bullet_list | |
: BULLET_MARKER | |
span_list: span_list_inner { $$ = $1; ((List<ISpan>)$$).Reverse (); } | |
span_list_inner | |
: span { $$ = new List<ISpan> { (ISpan)$1 }; } | |
| span span_list_inner { ((List<ISpan>)$2).Add ((ISpan)$1); $$ = $2; } | |
span | |
: TEXT { $$ = new FormatedSpan (SpanFormating.None, (string)$1); } | |
| url { $$ = $1; } | |
| emphasis { $$ = $1; } | |
| strong { $$ = $1; } | |
| inline_code { $$ = $1; } | |
url: URL_MARKER TEXT URL_MARKER URL_MARKER TEXT URL_MARKER { $$ = new UrlSpan (href: (string)$5, content: (string)$2); } | |
inline_code: INLINE_CODE_MARKER TEXT INLINE_CODE_MARKER { $$ = new FormatedSpan (SpanFormating.Code, (string)$1); } | |
emphasis: EMPH_MARKER TEXT EMPH_MARKER { $$ = new FormatedSpan (SpanFormating.Emphasis, (string)$2); } | |
strong: STRONG_MARKER TEXT STRONG_MARKER { $$ = new FormatedSpan (SpanFormating.Strong, (string)$2); } | |
text: TEXT NEWLINE { $$ = $1; } | |
atx_heading | |
: hash_list text { $$ = new Heading (HeadingStyle.Atx, depth: ((Counter)$1).Count, content: ((string)$2).Trim ()); } | |
hash_list | |
: HASH { $$ = new Counter (1); } | |
| HASH hash_list { ((Counter)$2).Count++; $$ = $2; } | |
/*setex_heading: TEXT NEWLINE setex_heading_line NEWLINE { ((Heading)$3).Content = (string)$1; $$ = $3; } | |
setex_heading_line | |
: HEADING_LINE { $$ = new Heading (HeadingStyle.Setex, depth: 0); } | |
| HEADING_LINE_DASH { $$ = new Heading (HeadingStyle.Setex, depth: 1); }*/ | |
%% | |
} |
using System; | |
using System.IO; | |
using System.Linq; | |
using System.Collections.Generic; | |
using NUnit.Framework; | |
using MarkdownParser; | |
namespace MarkdownParserTests | |
{ | |
[TestFixture] | |
public class Test | |
{ | |
[Test] | |
public void TestMarkdownAstTest () | |
{ | |
var ast = new IBlock[] { | |
new Heading (HeadingStyle.Atx, 1, "My Test Markdown file"), | |
new Heading (HeadingStyle.Atx, 2, "Introduction"), | |
new Paragraph (new ISpan[] { new FormatedSpan ("This is a test Markdown file") }), | |
new Paragraph (new ISpan[] { | |
new FormatedSpan ("It has some "), | |
new FormatedSpan (SpanFormating.Emphasis, "emphasis"), | |
new FormatedSpan (" and some "), | |
new FormatedSpan (SpanFormating.Strong, "strong"), | |
new FormatedSpan (" stuff to talk about"), | |
}), | |
new Code (language: "csharp", content: @"SomeCodeIsEvenDisplayed () | |
{ | |
public void IntoSomething () | |
{ | |
Console.WriteLine (""That looks like code""); | |
} | |
}"), | |
new Paragraph (new ISpan[] { | |
new FormatedSpan ("You can even embed cool url like "), | |
new UrlSpan (href: "http://neteril.org", content: "my website"), | |
new FormatedSpan (".") | |
}) | |
}; | |
AssertAst (ast, "MarkdownParserTests.MarkdownSnippets.test_markdown.md"); | |
} | |
void AssertAst (IEnumerable<IBlock> expectedAst, string markdownRes) | |
{ | |
var reader = new StreamReader (GetType ().Assembly.GetManifestResourceStream (markdownRes)); | |
var parser = new Parser (); | |
IEnumerable<IBlock> ast = null; | |
try { | |
ast = parser.Parse (reader); | |
} catch (Exception e) { | |
Assert.Fail ("Parser failed: {0}", e.ToString ()); | |
} | |
CollectionAssert.AreEqual (expectedAst, ast); | |
} | |
} | |
} |
This is a test Markdown file
It has some emphasis and some strong stuff to talk about
SomeCodeIsEvenDisplayed ()
{
public void IntoSomething ()
{
Console.WriteLine ("That looks like code");
}
}
You can even embed cool url like my website.