Пример #1
0
        public void Should_show_current_timestamp_with_different_format()
        {
            var parser = new ButterflyParser();
            parser.LoadDefaultStrategies(new DefaultParseStrategyFactory());
            parser.MacroFactory = new ActivatorFactory<IButterflyMacro>(new NamedTypeRegistry<IButterflyMacro>().RegisterType<TimestampMacro>("timestamp"));

            var text = parser.ParseAndReturn("[::timestamp|format=yyyy]");
            AssertWithNoRegardForLineBreaks(text, string.Format("<p>{0}</p>", DateTime.UtcNow.Year));
        }
Пример #2
0
        public void Should_show_current_timestamp()
        {
            var parser = new ButterflyParser();
            parser.LoadDefaultStrategies(new DefaultParseStrategyFactory());
            parser.MacroFactory = new ActivatorFactory<IButterflyMacro>(new NamedTypeRegistry<IButterflyMacro>().RegisterType<TimestampMacro>("timestamp"));

            var text = parser.ParseAndReturn("[::timestamp]");
            Assert.That(text, Is.StringMatching(@"<p>\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ</p>"));
        }
Пример #3
0
        public void Should_generate_nested_scope_tree()
        {
            var parser = new ButterflyParser()
                .LoadDefaultStrategies(new DefaultParseStrategyFactory());

            var tree = parser.Parse("foo __bar ''baz ==lulz=='' --oh hai!--__").ScopeTree;

            /*
             * <p>
             *   <strong>
             *	   <em>
             *	     <tt>
             *	   <ins>
            */

            Assert.That(tree.Count, Is.EqualTo(5));
            Assert.That(tree.Nodes.Count(), Is.EqualTo(1));

            var p = tree.Nodes.First();
            Assert.That(p.Scope.GetType(), Is.EqualTo(ScopeTypeCache.Paragraph));
            Assert.That(p.Depth, Is.EqualTo(1));
            Assert.That(p.Parent, Is.Null);
            Assert.That(p.Count, Is.EqualTo(4));
            Assert.That(p.Children.Count(), Is.EqualTo(1));

            var strong = p.Children.First();
            Assert.That(strong.Scope.GetType(), Is.EqualTo(ScopeTypeCache.Strong));
            Assert.That(strong.Parent, Is.EqualTo(p));
            Assert.That(strong.Depth, Is.EqualTo(2));
            Assert.That(strong.Count, Is.EqualTo(3));
            Assert.That(strong.Children.Count(), Is.EqualTo(2));

            var em = strong.Children.First();
            Assert.That(em.Scope.GetType(), Is.EqualTo(ScopeTypeCache.Emphasis));
            Assert.That(em.Parent, Is.EqualTo(strong));
            Assert.That(em.Depth, Is.EqualTo(3));
            Assert.That(em.Count, Is.EqualTo(1));
            Assert.That(em.Children.Count(), Is.EqualTo(1));

            var ins = strong.Children.Last();
            Assert.That(ins.Scope.GetType(), Is.EqualTo(ScopeTypeCache.Underline));
            Assert.That(ins.Parent, Is.EqualTo(strong));
            Assert.That(ins.Depth, Is.EqualTo(3));
            Assert.That(ins.Count, Is.EqualTo(0));
            Assert.That(ins.Children.Count(), Is.EqualTo(0));

            var tt = em.Children.First();
            Assert.That(tt.Scope.GetType(), Is.EqualTo(ScopeTypeCache.Teletype));
            Assert.That(tt.Parent, Is.EqualTo(em));
            Assert.That(tt.Depth, Is.EqualTo(4));
            Assert.That(tt.Count, Is.EqualTo(0));
            Assert.That(tt.Children.Count(), Is.EqualTo(0));
        }
Пример #4
0
        public void Should_update_input_with_macro_value()
        {
            var parser = new ButterflyParser();
            parser.LoadDefaultStrategies(new DefaultParseStrategyFactory());
            parser.MacroFactory = new ActivatorFactory<IButterflyMacro>(new NamedTypeRegistry<IButterflyMacro>().RegisterType<FooMacro>("foo"));

            var result = parser.Parse("[::foo] foo [::foo]");
            var text = parser.FlushAndReturn();

            Assert.That(result.Markup, Is.EqualTo("bar foo bar"));
            AssertWithNoRegardForLineBreaks(text, "<p>bar foo bar</p>");
        }
Пример #5
0
        public void Should_parse_markup_in_macros()
        {
            var parser = new ButterflyParser();
            parser.LoadDefaultStrategies(new DefaultParseStrategyFactory());
            parser.MacroFactory = new ActivatorFactory<IButterflyMacro>(new NamedTypeRegistry<IButterflyMacro>().RegisterType<BarMacro>("bar"));

            var result = parser.Parse("[::bar]");
            var text = parser.FlushAndReturn();

            Assert.That(result.Markup, Is.EqualTo("__bold__"));
            AssertWithNoRegardForLineBreaks(text, "<p><strong>bold</strong></p>");
        }
Пример #6
0
        public ActionResult Index(ParseModel model)
        {
            var parser = new ButterflyParser();
            parser.LoadDefaultStrategies(new DefaultParseStrategyFactory());
            parser.Analyzer = new HtmlAnalyzer(new StringWriter());

            try {
                return Json(new { error = (string)null, html = parser.ParseAndReturn(model.MarkUp) });
            } catch (Exception e) {
                return Json(new { error = e.Message, html = (string)null });
            }
        }
Пример #7
0
        static void Main(string[] args)
        {
            var result = OptionParser.Parse<ButterflyOptions>(args);

            var contract = result.Contract;

            if (contract.Help) {
                Console.WriteLine(OptionParser.GetDescription<ButterflyOptions>());
                return;
            }

            string text;

            if (string.IsNullOrEmpty(contract.File)) {
                //read from stdin
                text = Console.In.ReadToEnd();
            } else {
                try {
                    text = File.ReadAllText(contract.File);
                } catch (Exception e) {
                    Console.WriteLine(string.Format("An error occurred trying to read from {0}", contract.File));
                    Console.WriteLine();
                    Console.WriteLine(e);
                    return;
                }
            }

            var parser = new ButterflyParser().LoadDefaultStrategies();
            try {
                Console.WriteLine(parser.ParseAndReturn(text));
            } catch (ParseException e) {
                Console.WriteLine("An error occurred during parsing");
                Console.WriteLine();
                Console.WriteLine(e);
            }
        }
Пример #8
0
 public virtual void SetUp()
 {
     Parser = new ButterflyParser().LoadDefaultStrategies();
 }
Пример #9
0
        public void Generate_html_formatting_help_file()
        {
            const string helpMarkup = @"
            ! Butterfly Markup
            (-''auto-generated on __[::timestamp]__''-)

            __Butterfly__ is a semantic markup syntax created and developed by [http://tommymontgomery.com/|Tommy Montgomery].
            It is similar to many wiki syntaxes (such as [http://www.mediawiki.org/wiki/MediaWiki|MediaWiki]). It's goal is to
            be familiar, easy to read, and simple to use.

            This document serves as both a test of the markup itself and documentation on how to use it. This document was
            automatically generated by a unit test using __Butterfly__ itself to generate everything inside the ==<body>== tag.

            !! Output Formats
            __Butterfly__ uses an ''Analyzer'' to transform markup to an output format. The default is HTML, but you can implement
            your own analyzer by injecting a custom implementation of ==ButterflyNet.Parser.ButterflyAnalyzer== into a
            ==ButterflyNet.Parser.ButterflyParser== instance.

            !! Text Formatting
            |! Style|! Markup|! Output|
            | Bold| ==[!this text is __bold__]==| this text is __bold__|
            | Emphasis| ==[!this text is ''emphasized'']==| this text is ''emphasized''|
            | Teletype| ==[!this text is ==reminiscient of a typewriter==]==| this text is ==reminiscient of a typewriter==|
            | Underline| ==[!this text is --important--]==| this text is --important--|
            | Strike-through| ==[!this text is ---deleted---]==| this text is ---deleted---|
            | Big| ==[!this text is (+big and (+huge+)+)]==| this text is (+big and (+huge+)+)|
            | Small| ==[!this text is (-small and (-tiny-)-)]==| this text is (-small and (-tiny-)-)|

            !!Links
            Hyperlinks are surrounded by brackets. You can specify the text by separating it from the URL with a ==|==.

            |! Markup|! Output|
            | ==[![link]]]==| [link]|
            | ==[![link|totally ''awesome'' link, brah!]]]==| [link|totally ''awesome'' link, brah!]|
            | ==[![http://example.com/]]]==| [http://example.com/]|
            | ==[![http://example.com/|external link]]]==| [http://example.com/|external link]|
            | ==[![link.html|link text with [bracket]]]]]]]==| [link.html|link text with [bracket]]]|

            You can change the base URL of local links by modifying the ==ButterflyParser.LocalLinkBaseUrl== property.

            !!Headers

            Headers start with a variable number of ==!== at the beginning of a line.

            {{{{plaintext
            !Header level 1
            !!Header level 2
            !!! !Header that starts with an exclamation point!
            }}}}

            !Header level 1
            !!Header level 2
            !!! !Header that starts with an exclamation point!

            !! Lists
            !!! Bullet Lists

            Bulleted lists are opened by a ==*== (unordered) or a ==#== (ordered) at the start of a line. To increase the nesting
            level, add more asterisks or hashes. You cannot mix list types at the same depth.

            The following markup:
            {{{{plaintext
            * Countries
            *# United States
            *#* West Coast
            *#** Washington
            *#** Oregon
            *#** California
            *#* East Coast
            *#** Florida
            *#** Maryland
            *#** Georgia
            *#** Massachusetts
            *# Canada
            *# Mexico
            * See also
            ** Wikipedia: [http://en.wikipedia.org/wiki/List_of_sovereign_states]
            }}}}

            Gets transformed into:

            * Countries
            *# United States
            *#* West Coast
            *#** Washington
            *#** Oregon
            *#** California
            *#* East Coast
            *#** Florida
            *#** Maryland
            *#** Georgia
            *#** Massachusetts
            *# Canada
            *# Mexico
            * See also
            ** Wikipedia: [http://en.wikipedia.org/wiki/List_of_sovereign_states]

            !!! Definition Lists
            Definition terms are opened by a ==;== at the start of a line. Definitions of those terms are opened by a ==:== at
            the start of the subsequent line.

            e.g.

            {{{{plaintext
            ;Elephant
            :Big grey animals that have superstitiously accurate memories
            ;Baby elephant
            :Baby elephants are called ''calves'', apparently
            }}}}

            transforms into

            ;Elephant
            :Big grey animals that have superstitiously accurate memories
            ;Baby elephant
            :Baby elephants are called ''calves'', apparently

            !! Preformatted Text
            !!! Single-line

            For single line snippets of preformatted text, start a line with a space.

            {{{{plaintext
            Not preformatted
             preformatted
            }}}}

            Not preformatted
             preformatted

            !!! Multi-line
            For multiline preformatted text, surround with =={{{== and ==}}}==. Note that markup is allowed
            inside these blocks.

            {{{{plaintext
            {{{
            this is
            preformatted
            text and line breaks
            and             whitespace
            are preserved (and so is __markup__)
            }}}
            }}}}

            {{{
            this is
            preformatted
            text and line breaks
            and             whitespace
            are preserved (and so is __markup__)
            }}}

            !!! Preformatted Code
            For chunks of code, surround with =={{{{== and ==}}}}==. All this does is disable formatting.

            {{{plaintext
            [!{{{{
            this is
            preformatted
            text and line breaks
            and             whitespace
            are preserved (and so is __markup__)
            }}}}]
            }}}

            {{{{
            this is
            preformatted
            text and line breaks
            and             whitespace
            are preserved (and so is __markup__)
            }}}}

            !!!Specifying a programming language with syntax highlighting
            You can specify a programming language immediately after the opening =={{{== or =={{{{==. By default,
            __Butterfly__ uses [http://sunlightjs.com/|Sunlight] for syntax highlighting, but it also supports
            [http://code.google.com/p/google-code-prettify/|Prettify], [http://softwaremaniacs.org/soft/highlight/en/|Highlight.js]
            and [http://alexgorbatchev.com/SyntaxHighlighter/|Syntax Highlighter].

            {{{{plaintext
            {{{csharp
            public class MyClass : ICloneable {
            public string GetSomething(int i) {
            if (i < 0) {
            return string.Empty;
            }

            return string.Format(""i: {0}"", i);
            }
            }
            }}}
            }}}}

            becomes

            {{{csharp
            public class MyClass : ICloneable {
            public string GetSomething(int i) {
            if (i < 0) {
            return string.Empty;
            }

            return string.Format(""i: {0}"", i);
            }
            }
            }}}

            !! Blockquotes

            Blockquotes are opened with ==<<== at the beginning of a line, and closed with ==>>==.

            {{{{plaintext
            <<this is a blockquote>>

            <<
            so is this
            >>

            <<
            you can have

            * markup
            * as well as __textual styles__
            ** inside a blockquote
            >>
            }}}}

            <<this is a blockquote>>

            <<
            so is this
            >>

            <<
            you can have

            * markup
            * as well as __textual styles__
            ** inside a blockquote
            >>

            !! Horizontal Ruler
            You can insert a horizontal ruler by creating a line consisting of four dashes ==[!----]==.

            {{{{plaintext
            this is some text
            ----
            here is more text
            }}}}

            this is some text
            ----
            here is more text

            !! Modules
            Modules are extensions to the parser that allow for injecting user-defined functionality in the form
            of function calls. Each module has a unique name, and can be passed arguments.

            !!! Images
            In __Butterfly__, images are implemented as modules.

            |! Markup|! Output|
            | ==[![:image|url=butterfly.png]]]==| [:image|url=butterfly.png]|
            | ==[![:image|url=butterfly.png|title=A pretty butterfly|width=100|height=150]]]==| [:image|url=butterfly.png|title=A pretty butterfly|width=100|height=150]|
            | ==[![:image|url=nonexistent.png|alt=[an image]]]]]]]==| [:image|url=nonexistent.png|alt=[an image]]]|

            You can change the base URL of local images by modifying the ==ButterflyParser.LocalImageBaseUrl== property.

            !!! HTML Entities
            Since __Butterfly__ escapes all output (when it transforms to HTML), you can't render an HTML entity
            (the ==&== gets encoded to ==&amp;==). To get around this you can use the HTML entity module to render
            an HTML entity.

            |! Markup|! Output|
            | ==[![:entity|value=copy]]]==| [:entity|value=copy]|
            | ==[![:entity|value=#169]]]==| [:entity|value=#169]|
            | ==[![:entity|value=#xa9]]]==| [:entity|value=#xa9]|

            !! Unicode

            __Butterfly__ is unicode-safe, so you can just use straight-up Unicode and it will render as Unicode (unencoded).
            Make sure that you are rendering your page in UTF-8.

            <<Один главный процесс и несколько рабочих, рабочие процессы работают под непривилегированным пользователем>>

            !! Forced Line Breaks

            To force a line break, use ==[!%%%]==.

            {{{{plaintext
            this text will
            be on the same line

            but this text %%% has a line break
            }}}}

            this text will
            be on the same line

            but this text %%% has a line break

            !! Tables
            To render a table, start a line with ==|==. Each cell is separated by a ==|==. Use ==|!==
            to render a table header instead of a table cell.

            {{{{plaintext
            |! cell 1 |! cell 2 |
            | row 2 cell 1 | row 2 cell 2|
            | row 3 cell 1 | row 3 cell 2| row 3 cell 3 |
            }}}}

            becomes

            |! cell 1 |! cell 2 |
            | row 2 cell 1 | row 2 cell 2|
            | row 3 cell 1 | row 3 cell 2| row 3 cell 3 |

            Table rows are separated by linefeeds. If you need more complicated markup inside a table row,
            you can open a multiline table row with ==|{== and close it with ==}|==.

            {{{{plaintext
            |! header |! header2 |
            |{ this is a multiline row
            You can have all kinds of markup in here.

            * like a list
            ** and even a nested list!

            | cells are still separated by a [!|]

            <<I'm sexy

            [:entity|value=mdash] [http://tommymontgomery.com/|Tommy Montgomery]
            >>
            }|
            }}}}

            becomes

            |! header |! header2 |
            |{ this is a multiline row
            You can have all kinds of markup in here.

            * like a list
            ** and even a nested list!

            | cells are still separated by a [!|]

            <<I'm sexy

            [:entity|value=mdash] [http://tommymontgomery.com/|Tommy Montgomery]
            >>
            }|

            !! Unparsed Text
            Surround text with ==[![!]== and ==]== to make the parser ignore it.

            {{{{plaintext
            [! this will __not__ be parsed
            * not a list

            | not a table |
            ]
            }}}}

            becomes

            [! this will __not__ be parsed
            * not a list

            | not a table |
            ]

            __Note__ that newlines are ignored as well, so a chunk of text inside ==[![!]]]== will
            always be one single paragraph.

            !! Macros
            Macros are another extensibility point. Macros are similar to modules, except that they are
            completely deterministic, whereas a module can render (or not render at all) in a variety of
            ways depending on context. A macro evaluates to a hard value.

            Macros are surrounded by ==[![::]== and ==]==.

            !!! Current Timestamp
            The ==timestamp== macro prints the current timestamp in a variety of formats designated by the
            [http://msdn.microsoft.com/en-us/library/az4se3k1.aspx|.NET date formats]. If no format
            is given, it defaults to [http://msdn.microsoft.com/en-us/library/az4se3k1.aspx#UniversalSortable|the
            Universal Sortable format].

            |! Markup|! Output|
            | ==[![::timestamp]]]==| [::timestamp]|
            | ==[![::timestamp|format=dddd, MMMM dd yyyy]]]==| [::timestamp|format=dddd, MMMM dd yyyy]|

            ";

            var parser = new ButterflyParser().LoadDefaultStrategies();
            parser.LocalImageBaseUrl = "";

            var stopWatch = Stopwatch.StartNew();
            var html = parser.ParseAndReturn(helpMarkup);
            stopWatch.Stop();
            Console.WriteLine("elapsed parsing time: {0}ms", stopWatch.ElapsedMilliseconds);

            var fileContents = string.Format(@"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN""
            ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"">

            <html xmlns=""http://www.w3.org/1999/xhtml"" lang=""en-US"">
            <head>
            <title>Butterfly Formatting Help</title>
            <meta http-equiv=""content-type"" content=""text/html; charset=utf-8""/>
            <style type=""text/css"">
            body {{
                background-color: #FFFFFF;
                color: #000000;
                font-family: ""Droid Sans"", Verdana, sans-serif;
                font-size: 12pt;
                width: 80%;
                min-width: 800px;
                margin: auto;
            }}

            code, tt, pre {{
                font-family: Consolas, Inconsolata, ""Courier New"", monospace;
            }}

            dt {{
                background-color: #EEEEEE;
                font-weight: bold;
                margin-top: 10px;
            }}

            a {{
                color: #000099;
                text-decoration: underline;
            }}
            a:hover {{
                background-color: #EEEEEE;
            }}
            a.external {{
                padding-right: 14px;
                background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwQAADsEBuJFr7QAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuN6eEncwAAABASURBVChTY2AYOiBtZtp/GMbm6v9AQWQMVkNIA4pBIMUwTbhsgIvDFOMLQLBpWEyEi6NrxiVBXQ3oIQXjU5YWADmkKHLJiLiZAAAAAElFTkSuQmCC);
                background-position: right center;
                background-repeat: no-repeat;
            }}

            table {{
                border-collapse: collapse;
            }}
            table, td, th {{
                border: 1px solid #999999;
                padding: 5px;
            }}
            th {{
                background-color: #CBB1CA;
            }}
            blockquote {{
                border-left: 2px solid #666666;
                background-color: #EEEEEE;
                padding: 5px;
            }}
            </style>
            <link rel=""stylesheet"" type=""text/css"" href=""http://dl.sunlightjs.com/latest/themes/sunlight.default.css""/>
            </head>
            <body>
            {0}

            <script type=""text/javascript"" src=""http://dl.sunlightjs.com/latest/sunlight-min.js""></script>
            <script type=""text/javascript"" src=""http://dl.sunlightjs.com/latest/lang/sunlight.csharp-min.js""></script>
            <script type=""text/javascript"">//<![CDATA[
            typeof(Sunlight) !== ""undefined"" && Sunlight.highlightAll();
            //]]></script>
            </body>
            </html>", html);

            File.WriteAllText(@"..\..\..\..\..\..\formatting.html", fileContents, Encoding.UTF8);
        }