From dd6c865ce58d4aa1844e609b522f88bc23f69f5d Mon Sep 17 00:00:00 2001 From: Leonid Date: Mon, 25 Nov 2024 00:18:40 +0500 Subject: [PATCH 01/15] create Markdown architecture --- cs/Markdown/Markdown.csproj | 10 +++++++++ cs/Markdown/Md.cs | 32 +++++++++++++++++++++++++++ cs/Markdown/Program.cs | 4 ++++ cs/Markdown/Tokenizer.cs | 21 ++++++++++++++++++ cs/Markdown/Tokens/BoldToken.cs | 8 +++++++ cs/Markdown/Tokens/EscapeToken.cs | 7 ++++++ cs/Markdown/Tokens/HeaderToken.cs | 8 +++++++ cs/Markdown/Tokens/ITokenPosition.cs | 7 ++++++ cs/Markdown/Tokens/ItalicToken.cs | 8 +++++++ cs/Markdown/Tokens/PairToken.cs | 12 ++++++++++ cs/Markdown/Tokens/SingleToken.cs | 10 +++++++++ cs/MarkdownTests/MarkdownTest.cs | 16 ++++++++++++++ cs/MarkdownTests/MarkdownTests.csproj | 28 +++++++++++++++++++++++ cs/clean-code.sln | 19 ++++++++++++++-- cs/clean-code.sln.DotSettings | 3 +++ 15 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 cs/Markdown/Markdown.csproj create mode 100644 cs/Markdown/Md.cs create mode 100644 cs/Markdown/Program.cs create mode 100644 cs/Markdown/Tokenizer.cs create mode 100644 cs/Markdown/Tokens/BoldToken.cs create mode 100644 cs/Markdown/Tokens/EscapeToken.cs create mode 100644 cs/Markdown/Tokens/HeaderToken.cs create mode 100644 cs/Markdown/Tokens/ITokenPosition.cs create mode 100644 cs/Markdown/Tokens/ItalicToken.cs create mode 100644 cs/Markdown/Tokens/PairToken.cs create mode 100644 cs/Markdown/Tokens/SingleToken.cs create mode 100644 cs/MarkdownTests/MarkdownTest.cs create mode 100644 cs/MarkdownTests/MarkdownTests.csproj diff --git a/cs/Markdown/Markdown.csproj b/cs/Markdown/Markdown.csproj new file mode 100644 index 000000000..2150e3797 --- /dev/null +++ b/cs/Markdown/Markdown.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/cs/Markdown/Md.cs b/cs/Markdown/Md.cs new file mode 100644 index 000000000..91db47a79 --- /dev/null +++ b/cs/Markdown/Md.cs @@ -0,0 +1,32 @@ +using Markdown.Tokens; +using System.Text; + +namespace Markdown; + +public class Md +{ + public string Render(string text) + { + var textLines = text.Split(Environment.NewLine).ToList(); + var sb = new StringBuilder(); + + foreach (var line in textLines) + { + sb.Append(RenderCurrentString(line)); + } + + return sb.ToString(); + } + + private string RenderCurrentString(string line) + { + var tokenizer = new Tokenizer(line); + return GenerateHtml(line, tokenizer.TokenizeLine()); + } + + private string GenerateHtml(string line, List Tokens) + { + // TODO some logic + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs new file mode 100644 index 000000000..39e2558e3 --- /dev/null +++ b/cs/Markdown/Program.cs @@ -0,0 +1,4 @@ +using Markdown; + +Md md = new Md(); +md.Render("text \n\n\n text123"); \ No newline at end of file diff --git a/cs/Markdown/Tokenizer.cs b/cs/Markdown/Tokenizer.cs new file mode 100644 index 000000000..a5415e521 --- /dev/null +++ b/cs/Markdown/Tokenizer.cs @@ -0,0 +1,21 @@ +using Markdown.Tokens; + +namespace Markdown; + +public class Tokenizer +{ + private Stack boldTokens; + private Stack italicTokens; + + public Tokenizer(string line) + { + // TODO some logic + throw new NotImplementedException(); + } + + public List TokenizeLine() + { + // TODO some logic + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/cs/Markdown/Tokens/BoldToken.cs b/cs/Markdown/Tokens/BoldToken.cs new file mode 100644 index 000000000..f24e79d5e --- /dev/null +++ b/cs/Markdown/Tokens/BoldToken.cs @@ -0,0 +1,8 @@ +namespace Markdown.Tokens; + +public class BoldToken : PairToken +{ + public override string MdView => "__"; + public override string HtmlTagOpen => ""; + public override string HtmlTagClose => ""; +} \ No newline at end of file diff --git a/cs/Markdown/Tokens/EscapeToken.cs b/cs/Markdown/Tokens/EscapeToken.cs new file mode 100644 index 000000000..83ffe42b5 --- /dev/null +++ b/cs/Markdown/Tokens/EscapeToken.cs @@ -0,0 +1,7 @@ +namespace Markdown.Tokens; + +public class EscapeToken : SingleToken +{ + public override string MdView => """\"""; + public override string HtmlTagOpen => ""; +} \ No newline at end of file diff --git a/cs/Markdown/Tokens/HeaderToken.cs b/cs/Markdown/Tokens/HeaderToken.cs new file mode 100644 index 000000000..533b92b13 --- /dev/null +++ b/cs/Markdown/Tokens/HeaderToken.cs @@ -0,0 +1,8 @@ +namespace Markdown.Tokens; + +public class HeaderToken : PairToken +{ + public override string MdView => "# "; + public override string HtmlTagOpen => "

"; + public override string HtmlTagClose => "

"; +} \ No newline at end of file diff --git a/cs/Markdown/Tokens/ITokenPosition.cs b/cs/Markdown/Tokens/ITokenPosition.cs new file mode 100644 index 000000000..ae1ffc0f4 --- /dev/null +++ b/cs/Markdown/Tokens/ITokenPosition.cs @@ -0,0 +1,7 @@ +namespace Markdown.Tokens; + +public interface ITokenPosition +{ + public int Position { get; set; } + public string HtmlView { get; } +} \ No newline at end of file diff --git a/cs/Markdown/Tokens/ItalicToken.cs b/cs/Markdown/Tokens/ItalicToken.cs new file mode 100644 index 000000000..ccf5c117c --- /dev/null +++ b/cs/Markdown/Tokens/ItalicToken.cs @@ -0,0 +1,8 @@ +namespace Markdown.Tokens; + +public class ItalicToken : PairToken +{ + public override string MdView => "_"; + public override string HtmlTagOpen => ""; + public override string HtmlTagClose => ""; +} \ No newline at end of file diff --git a/cs/Markdown/Tokens/PairToken.cs b/cs/Markdown/Tokens/PairToken.cs new file mode 100644 index 000000000..8f4b251c5 --- /dev/null +++ b/cs/Markdown/Tokens/PairToken.cs @@ -0,0 +1,12 @@ +namespace Markdown.Tokens; + +public abstract class PairToken : ITokenPosition +{ + public abstract string MdView { get; } + public abstract string HtmlTagOpen { get; } + public abstract string HtmlTagClose { get; } + public string HtmlView => IsClosed ? HtmlTagOpen : HtmlTagClose; + + public bool IsClosed { get; set; } + public int Position { get; set; } +} \ No newline at end of file diff --git a/cs/Markdown/Tokens/SingleToken.cs b/cs/Markdown/Tokens/SingleToken.cs new file mode 100644 index 000000000..f4f04a102 --- /dev/null +++ b/cs/Markdown/Tokens/SingleToken.cs @@ -0,0 +1,10 @@ +namespace Markdown.Tokens; + +public abstract class SingleToken : ITokenPosition +{ + public abstract string MdView { get; } + public abstract string HtmlTagOpen { get; } + + public string HtmlView => HtmlTagOpen; + public int Position { get; set; } +} \ No newline at end of file diff --git a/cs/MarkdownTests/MarkdownTest.cs b/cs/MarkdownTests/MarkdownTest.cs new file mode 100644 index 000000000..bcde4ae83 --- /dev/null +++ b/cs/MarkdownTests/MarkdownTest.cs @@ -0,0 +1,16 @@ +namespace MarkdownTests +{ + public class Tests + { + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Assert.Pass(); + } + } +} \ No newline at end of file diff --git a/cs/MarkdownTests/MarkdownTests.csproj b/cs/MarkdownTests/MarkdownTests.csproj new file mode 100644 index 000000000..ad8b21329 --- /dev/null +++ b/cs/MarkdownTests/MarkdownTests.csproj @@ -0,0 +1,28 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + diff --git a/cs/clean-code.sln b/cs/clean-code.sln index 2206d54db..ae4e5d792 100644 --- a/cs/clean-code.sln +++ b/cs/clean-code.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35514.174 d17.12 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chess", "Chess\Chess.csproj", "{DBFBE40E-EE0C-48F4-8763-EBD11C960081}" EndProject @@ -9,6 +9,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlDigit", "ControlDigi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "Samples\Samples.csproj", "{C3EF41D7-50EF-4CE1-B30A-D1D81C93D7FA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Markdown", "Markdown\Markdown.csproj", "{2A88730A-1C3F-42B6-AD70-FF890AEAC047}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarkdownTests", "MarkdownTests\MarkdownTests.csproj", "{5928AADB-6ACE-429E-B801-BE58A76299AC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,5 +31,16 @@ Global {C3EF41D7-50EF-4CE1-B30A-D1D81C93D7FA}.Debug|Any CPU.Build.0 = Debug|Any CPU {C3EF41D7-50EF-4CE1-B30A-D1D81C93D7FA}.Release|Any CPU.ActiveCfg = Release|Any CPU {C3EF41D7-50EF-4CE1-B30A-D1D81C93D7FA}.Release|Any CPU.Build.0 = Release|Any CPU + {2A88730A-1C3F-42B6-AD70-FF890AEAC047}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A88730A-1C3F-42B6-AD70-FF890AEAC047}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A88730A-1C3F-42B6-AD70-FF890AEAC047}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A88730A-1C3F-42B6-AD70-FF890AEAC047}.Release|Any CPU.Build.0 = Release|Any CPU + {5928AADB-6ACE-429E-B801-BE58A76299AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5928AADB-6ACE-429E-B801-BE58A76299AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5928AADB-6ACE-429E-B801-BE58A76299AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5928AADB-6ACE-429E-B801-BE58A76299AC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection EndGlobal diff --git a/cs/clean-code.sln.DotSettings b/cs/clean-code.sln.DotSettings index 135b83ecb..229f449d2 100644 --- a/cs/clean-code.sln.DotSettings +++ b/cs/clean-code.sln.DotSettings @@ -1,6 +1,9 @@  <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></Policy> + True True True Imported 10.10.2016 From f58bebf12ba53507367b9e65322dea53a6e2d5da Mon Sep 17 00:00:00 2001 From: Leonid Date: Mon, 25 Nov 2024 00:42:43 +0500 Subject: [PATCH 02/15] small fix ITokenPosition and Tokenizer --- cs/Markdown/Tokenizer.cs | 4 ++-- cs/Markdown/Tokens/ITokenPosition.cs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cs/Markdown/Tokenizer.cs b/cs/Markdown/Tokenizer.cs index a5415e521..46fb6edc2 100644 --- a/cs/Markdown/Tokenizer.cs +++ b/cs/Markdown/Tokenizer.cs @@ -4,8 +4,8 @@ namespace Markdown; public class Tokenizer { - private Stack boldTokens; - private Stack italicTokens; + private Stack boldTokens; + private Stack italicTokens; public Tokenizer(string line) { diff --git a/cs/Markdown/Tokens/ITokenPosition.cs b/cs/Markdown/Tokens/ITokenPosition.cs index ae1ffc0f4..e4157379b 100644 --- a/cs/Markdown/Tokens/ITokenPosition.cs +++ b/cs/Markdown/Tokens/ITokenPosition.cs @@ -2,6 +2,7 @@ public interface ITokenPosition { + public string MdView { get; } public int Position { get; set; } public string HtmlView { get; } } \ No newline at end of file From 29533014f9f77574e95d67e5aafd6070e8c969a2 Mon Sep 17 00:00:00 2001 From: Leonid Date: Mon, 25 Nov 2024 20:37:20 +0500 Subject: [PATCH 03/15] rebuilt architecture --- cs/Markdown/Markdown.csproj | 4 ++++ cs/Markdown/Md.cs | 32 ++++++++++++---------------- cs/Markdown/TagParser.cs | 24 +++++++++++++++++++++ cs/Markdown/Tags/BoldTag.cs | 11 ++++++++++ cs/Markdown/Tags/EscapeTag.cs | 9 ++++++++ cs/Markdown/Tags/H1Tag.cs | 11 ++++++++++ cs/Markdown/Tags/ITag.cs | 9 ++++++++ cs/Markdown/Tags/ItalicTextTag.cs | 11 ++++++++++ cs/Markdown/Tags/TagType.cs | 9 ++++++++ cs/Markdown/Token/IToken.cs | 10 +++++++++ cs/Markdown/Tokenizer.cs | 21 ------------------ cs/Markdown/Tokens/BoldToken.cs | 8 ------- cs/Markdown/Tokens/EscapeToken.cs | 7 ------ cs/Markdown/Tokens/HeaderToken.cs | 8 ------- cs/Markdown/Tokens/ITokenPosition.cs | 8 ------- cs/Markdown/Tokens/ItalicToken.cs | 8 ------- cs/Markdown/Tokens/PairToken.cs | 12 ----------- cs/Markdown/Tokens/SingleToken.cs | 10 --------- 18 files changed, 112 insertions(+), 100 deletions(-) create mode 100644 cs/Markdown/TagParser.cs create mode 100644 cs/Markdown/Tags/BoldTag.cs create mode 100644 cs/Markdown/Tags/EscapeTag.cs create mode 100644 cs/Markdown/Tags/H1Tag.cs create mode 100644 cs/Markdown/Tags/ITag.cs create mode 100644 cs/Markdown/Tags/ItalicTextTag.cs create mode 100644 cs/Markdown/Tags/TagType.cs create mode 100644 cs/Markdown/Token/IToken.cs delete mode 100644 cs/Markdown/Tokenizer.cs delete mode 100644 cs/Markdown/Tokens/BoldToken.cs delete mode 100644 cs/Markdown/Tokens/EscapeToken.cs delete mode 100644 cs/Markdown/Tokens/HeaderToken.cs delete mode 100644 cs/Markdown/Tokens/ITokenPosition.cs delete mode 100644 cs/Markdown/Tokens/ItalicToken.cs delete mode 100644 cs/Markdown/Tokens/PairToken.cs delete mode 100644 cs/Markdown/Tokens/SingleToken.cs diff --git a/cs/Markdown/Markdown.csproj b/cs/Markdown/Markdown.csproj index 2150e3797..312898fa7 100644 --- a/cs/Markdown/Markdown.csproj +++ b/cs/Markdown/Markdown.csproj @@ -7,4 +7,8 @@ enable + + + + diff --git a/cs/Markdown/Md.cs b/cs/Markdown/Md.cs index 91db47a79..21cf5a17f 100644 --- a/cs/Markdown/Md.cs +++ b/cs/Markdown/Md.cs @@ -1,30 +1,26 @@ -using Markdown.Tokens; -using System.Text; +using System.Text; +using Markdown.Tags; +using Markdown.Token; namespace Markdown; public class Md { - public string Render(string text) - { - var textLines = text.Split(Environment.NewLine).ToList(); - var sb = new StringBuilder(); - - foreach (var line in textLines) - { - sb.Append(RenderCurrentString(line)); - } - - return sb.ToString(); - } + private readonly List availableTags = + [ + new BoldTag(), + new H1Tag(), + new ItalicTextTag(), + new EscapeTag() + ]; - private string RenderCurrentString(string line) + public string Render(string text) { - var tokenizer = new Tokenizer(line); - return GenerateHtml(line, tokenizer.TokenizeLine()); + var parser = new TagParser(availableTags); + return GenerateHtml(text, parser.GetTokens(text)); } - private string GenerateHtml(string line, List Tokens) + private string GenerateHtml(string text, List tokens) { // TODO some logic throw new NotImplementedException(); diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs new file mode 100644 index 000000000..3101d8274 --- /dev/null +++ b/cs/Markdown/TagParser.cs @@ -0,0 +1,24 @@ +using System.Collections; +using Markdown.Tags; +using Markdown.Token; + +namespace Markdown; + +public class TagParser +{ + private readonly List<(Stack, TagType)> TagsOrder; + + public TagParser(List tags) + { + foreach (var tag in tags) + { + TagsOrder.Add((new Stack {}, tag.Type)); + } + } + + public List GetTokens(string text) + { + // TODO some logic + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs new file mode 100644 index 000000000..3fb205575 --- /dev/null +++ b/cs/Markdown/Tags/BoldTag.cs @@ -0,0 +1,11 @@ +using Markdown.Tags; + +namespace Markdown.Tags; + +public class BoldTag : ITag +{ + public string Head => ""; + public string Tail => ""; + public string MdView => "__"; + public TagType Type => TagType.BoldText; +} \ No newline at end of file diff --git a/cs/Markdown/Tags/EscapeTag.cs b/cs/Markdown/Tags/EscapeTag.cs new file mode 100644 index 000000000..56304334e --- /dev/null +++ b/cs/Markdown/Tags/EscapeTag.cs @@ -0,0 +1,9 @@ +namespace Markdown.Tags; + +public class EscapeTag : ITag +{ + public string Head => ""; + public string Tail => ""; + public string MdView => """\"""; + public TagType Type => TagType.Escape; +} \ No newline at end of file diff --git a/cs/Markdown/Tags/H1Tag.cs b/cs/Markdown/Tags/H1Tag.cs new file mode 100644 index 000000000..3e673d3a2 --- /dev/null +++ b/cs/Markdown/Tags/H1Tag.cs @@ -0,0 +1,11 @@ +using Markdown.Tags; + +namespace Markdown.Tags; + +public class H1Tag : ITag +{ + public string Head => "

"; + public string Tail => "

"; + public string MdView => "# "; + public TagType Type => TagType.Header; +} \ No newline at end of file diff --git a/cs/Markdown/Tags/ITag.cs b/cs/Markdown/Tags/ITag.cs new file mode 100644 index 000000000..ab07d4324 --- /dev/null +++ b/cs/Markdown/Tags/ITag.cs @@ -0,0 +1,9 @@ +namespace Markdown.Tags; + +public interface ITag +{ + public string MdView { get; } + public string Head { get;} + public string Tail { get;} + public TagType Type { get; } +} \ No newline at end of file diff --git a/cs/Markdown/Tags/ItalicTextTag.cs b/cs/Markdown/Tags/ItalicTextTag.cs new file mode 100644 index 000000000..0d63d276b --- /dev/null +++ b/cs/Markdown/Tags/ItalicTextTag.cs @@ -0,0 +1,11 @@ +using Markdown.Tags; + +namespace Markdown.Tags; + +public class ItalicTextTag : ITag +{ + public string Head => ""; + public string Tail => ""; + public string MdView => "_"; + public TagType Type => TagType.ItalicText; +} \ No newline at end of file diff --git a/cs/Markdown/Tags/TagType.cs b/cs/Markdown/Tags/TagType.cs new file mode 100644 index 000000000..073baa3ba --- /dev/null +++ b/cs/Markdown/Tags/TagType.cs @@ -0,0 +1,9 @@ +namespace Markdown.Tags; + +public enum TagType +{ + Header, + ItalicText, + BoldText, + Escape +} \ No newline at end of file diff --git a/cs/Markdown/Token/IToken.cs b/cs/Markdown/Token/IToken.cs new file mode 100644 index 000000000..87e6e67da --- /dev/null +++ b/cs/Markdown/Token/IToken.cs @@ -0,0 +1,10 @@ +using Markdown.Tags; + +namespace Markdown.Token; + +public interface IToken +{ + public string SourceText { get; } + public string ConvertedText { get; } + public int Position { get; set; } +} \ No newline at end of file diff --git a/cs/Markdown/Tokenizer.cs b/cs/Markdown/Tokenizer.cs deleted file mode 100644 index 46fb6edc2..000000000 --- a/cs/Markdown/Tokenizer.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Markdown.Tokens; - -namespace Markdown; - -public class Tokenizer -{ - private Stack boldTokens; - private Stack italicTokens; - - public Tokenizer(string line) - { - // TODO some logic - throw new NotImplementedException(); - } - - public List TokenizeLine() - { - // TODO some logic - throw new NotImplementedException(); - } -} \ No newline at end of file diff --git a/cs/Markdown/Tokens/BoldToken.cs b/cs/Markdown/Tokens/BoldToken.cs deleted file mode 100644 index f24e79d5e..000000000 --- a/cs/Markdown/Tokens/BoldToken.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Markdown.Tokens; - -public class BoldToken : PairToken -{ - public override string MdView => "__"; - public override string HtmlTagOpen => ""; - public override string HtmlTagClose => ""; -} \ No newline at end of file diff --git a/cs/Markdown/Tokens/EscapeToken.cs b/cs/Markdown/Tokens/EscapeToken.cs deleted file mode 100644 index 83ffe42b5..000000000 --- a/cs/Markdown/Tokens/EscapeToken.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Markdown.Tokens; - -public class EscapeToken : SingleToken -{ - public override string MdView => """\"""; - public override string HtmlTagOpen => ""; -} \ No newline at end of file diff --git a/cs/Markdown/Tokens/HeaderToken.cs b/cs/Markdown/Tokens/HeaderToken.cs deleted file mode 100644 index 533b92b13..000000000 --- a/cs/Markdown/Tokens/HeaderToken.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Markdown.Tokens; - -public class HeaderToken : PairToken -{ - public override string MdView => "# "; - public override string HtmlTagOpen => "

"; - public override string HtmlTagClose => "

"; -} \ No newline at end of file diff --git a/cs/Markdown/Tokens/ITokenPosition.cs b/cs/Markdown/Tokens/ITokenPosition.cs deleted file mode 100644 index e4157379b..000000000 --- a/cs/Markdown/Tokens/ITokenPosition.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Markdown.Tokens; - -public interface ITokenPosition -{ - public string MdView { get; } - public int Position { get; set; } - public string HtmlView { get; } -} \ No newline at end of file diff --git a/cs/Markdown/Tokens/ItalicToken.cs b/cs/Markdown/Tokens/ItalicToken.cs deleted file mode 100644 index ccf5c117c..000000000 --- a/cs/Markdown/Tokens/ItalicToken.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Markdown.Tokens; - -public class ItalicToken : PairToken -{ - public override string MdView => "_"; - public override string HtmlTagOpen => ""; - public override string HtmlTagClose => ""; -} \ No newline at end of file diff --git a/cs/Markdown/Tokens/PairToken.cs b/cs/Markdown/Tokens/PairToken.cs deleted file mode 100644 index 8f4b251c5..000000000 --- a/cs/Markdown/Tokens/PairToken.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Markdown.Tokens; - -public abstract class PairToken : ITokenPosition -{ - public abstract string MdView { get; } - public abstract string HtmlTagOpen { get; } - public abstract string HtmlTagClose { get; } - public string HtmlView => IsClosed ? HtmlTagOpen : HtmlTagClose; - - public bool IsClosed { get; set; } - public int Position { get; set; } -} \ No newline at end of file diff --git a/cs/Markdown/Tokens/SingleToken.cs b/cs/Markdown/Tokens/SingleToken.cs deleted file mode 100644 index f4f04a102..000000000 --- a/cs/Markdown/Tokens/SingleToken.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Markdown.Tokens; - -public abstract class SingleToken : ITokenPosition -{ - public abstract string MdView { get; } - public abstract string HtmlTagOpen { get; } - - public string HtmlView => HtmlTagOpen; - public int Position { get; set; } -} \ No newline at end of file From 30980274ac029c9ea693dbe2975cf1442338c462 Mon Sep 17 00:00:00 2001 From: Leonid Date: Mon, 25 Nov 2024 21:41:15 +0500 Subject: [PATCH 04/15] small refactor --- cs/Markdown/Markdown.csproj | 4 ---- cs/Markdown/Md.cs | 8 ++++---- cs/Markdown/TagParser.cs | 1 + cs/Markdown/Token/Token.cs | 8 ++++++++ 4 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 cs/Markdown/Token/Token.cs diff --git a/cs/Markdown/Markdown.csproj b/cs/Markdown/Markdown.csproj index 312898fa7..2150e3797 100644 --- a/cs/Markdown/Markdown.csproj +++ b/cs/Markdown/Markdown.csproj @@ -7,8 +7,4 @@ enable - - - - diff --git a/cs/Markdown/Md.cs b/cs/Markdown/Md.cs index 21cf5a17f..52b7f9542 100644 --- a/cs/Markdown/Md.cs +++ b/cs/Markdown/Md.cs @@ -4,9 +4,9 @@ namespace Markdown; -public class Md +public static class Md { - private readonly List availableTags = + private static List availableTags = [ new BoldTag(), new H1Tag(), @@ -14,13 +14,13 @@ public class Md new EscapeTag() ]; - public string Render(string text) + public static string Render(string text) { var parser = new TagParser(availableTags); return GenerateHtml(text, parser.GetTokens(text)); } - private string GenerateHtml(string text, List tokens) + private static string GenerateHtml(string text, List tokens) { // TODO some logic throw new NotImplementedException(); diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index 3101d8274..4aca805b2 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -18,6 +18,7 @@ public TagParser(List tags) public List GetTokens(string text) { + var tokens = new List {}; // TODO some logic throw new NotImplementedException(); } diff --git a/cs/Markdown/Token/Token.cs b/cs/Markdown/Token/Token.cs new file mode 100644 index 000000000..647f4e6a0 --- /dev/null +++ b/cs/Markdown/Token/Token.cs @@ -0,0 +1,8 @@ +namespace Markdown.Token; + +public class Token(string sourceText, string convertedText, int position) : IToken +{ + public string SourceText { get; } = sourceText; + public string ConvertedText { get; } = convertedText; + public int Position { get; set; } = position; +} \ No newline at end of file From 0e78fce72a0a8c448072ffb0b0b81e97bab2eadb Mon Sep 17 00:00:00 2001 From: Leonid Date: Tue, 26 Nov 2024 19:25:21 +0500 Subject: [PATCH 05/15] base realization --- cs/Markdown/Md.cs | 15 +++++++-- cs/Markdown/Program.cs | 5 +-- cs/Markdown/TagParser.cs | 54 ++++++++++++++++++++++++++++--- cs/Markdown/Tags/BoldTag.cs | 48 +++++++++++++++++++++++++++ cs/Markdown/Tags/EscapeTag.cs | 20 ++++++++++++ cs/Markdown/Tags/H1Tag.cs | 21 ++++++++++++ cs/Markdown/Tags/ITag.cs | 6 ++++ cs/Markdown/Tags/ItalicTextTag.cs | 47 +++++++++++++++++++++++++++ cs/Markdown/Tags/TagKind.cs | 8 +++++ cs/Markdown/Tags/TagType.cs | 1 + 10 files changed, 217 insertions(+), 8 deletions(-) create mode 100644 cs/Markdown/Tags/TagKind.cs diff --git a/cs/Markdown/Md.cs b/cs/Markdown/Md.cs index 52b7f9542..1ee40ff65 100644 --- a/cs/Markdown/Md.cs +++ b/cs/Markdown/Md.cs @@ -22,7 +22,18 @@ public static string Render(string text) private static string GenerateHtml(string text, List tokens) { - // TODO some logic - throw new NotImplementedException(); + var currentTokens = tokens.OrderBy(t => t.Position).ToList(); + int position = 0; + var sb = new StringBuilder(); + foreach (var token in currentTokens) + { + sb.Append(text[position..token.Position]); + sb.Append(token.ConvertedText); + position = token.Position + token.SourceText.Length; + } + + sb.Append(text[position..text.Length]); + + return sb.ToString(); } } \ No newline at end of file diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs index 39e2558e3..5b88a97d1 100644 --- a/cs/Markdown/Program.cs +++ b/cs/Markdown/Program.cs @@ -1,4 +1,5 @@ using Markdown; -Md md = new Md(); -md.Render("text \n\n\n text123"); \ No newline at end of file +// text \n\n\n _text123_ +Console.WriteLine(Md.Render("__markdown _bobo_ __ a")); +// _text123_ __markdown__ a \ No newline at end of file diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index 4aca805b2..7f3396b8c 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -6,20 +6,66 @@ namespace Markdown; public class TagParser { - private readonly List<(Stack, TagType)> TagsOrder; + //private readonly List<(Stack, TagType)> TagsOrder; + private readonly Dictionary > TagsOrder = new(); + private readonly List<(Func, ITag)> Rules = new(); public TagParser(List tags) { foreach (var tag in tags) { - TagsOrder.Add((new Stack {}, tag.Type)); + Rules.Add((tag.TagRule, tag)); + TagsOrder.Add(tag.Type, new Stack()); + tag.GetCurrentStack(TagsOrder[tag.Type]); } } public List GetTokens(string text) { var tokens = new List {}; - // TODO some logic - throw new NotImplementedException(); + var globalContext = TagType.None; + var textPointer = 0; + while (textPointer != text.Length) + { + foreach (var rule in Rules) + { + var result = rule.Item1(text[textPointer], textPointer); + if (result == TagKind.Open) + { + globalContext = rule.Item2.Type; + var sourceText = rule.Item2.MdView; + var convertedText = rule.Item2.Head; + var pos = rule.Item2.TokenPosition; + tokens.Add(new Token.Token(sourceText, convertedText, pos)); + ResetAllRules(); + break; + // TagsOrder[rule.Item2.Type].Append(rule.Item2.CreateNewTag()); + } + if (result == TagKind.Close) + { + globalContext = rule.Item2.Type; + var sourceText = rule.Item2.MdView; + var convertedText = rule.Item2.Tail; + var pos = rule.Item2.TokenPosition; + tokens.Add(new Token.Token(sourceText, convertedText, pos)); + ResetAllRules(); + break; + // TagsOrder[rule.Item2.Type].Append(rule.Item2.CreateNewTag()); + } + } + + textPointer++; + // Обработка конца строки проверка стэка с типом Header + } + + return tokens; + } + + private void ResetAllRules() + { + foreach (var rule in Rules) + { + rule.Item2.ResetRule(); + } } } \ No newline at end of file diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs index 3fb205575..f2b001632 100644 --- a/cs/Markdown/Tags/BoldTag.cs +++ b/cs/Markdown/Tags/BoldTag.cs @@ -8,4 +8,52 @@ public class BoldTag : ITag public string Tail => ""; public string MdView => "__"; public TagType Type => TagType.BoldText; + private int state; + private Stack currentStack; + public int TokenPosition { get; set; } + + public TagKind TagRule(char ch, int position) + { + if (state == 2 && char.IsLetter(ch) && currentStack.Count == 0) + { + state = 0; + currentStack.Push(CreateNewTag()); + return TagKind.Open; + } + if (state == 2 && (char.IsLetter(ch) || ch == ' ')) + { + state = 0; + currentStack.Pop(); + return TagKind.Close; + } + if (state == 1 && ch == '_') + { + state = 2; + } + else if (ch == '_') + { + state = 1; + TokenPosition = position; + } + if ((state == 1 || state == 2) && ch != '_') + { + state = 0; + } + return TagKind.None; + } + + public ITag CreateNewTag() + { + return new BoldTag(); + } + + public void GetCurrentStack(in Stack stack) + { + currentStack = stack; + } + + public void ResetRule() + { + state = 0; + } } \ No newline at end of file diff --git a/cs/Markdown/Tags/EscapeTag.cs b/cs/Markdown/Tags/EscapeTag.cs index 56304334e..9a1e49cb5 100644 --- a/cs/Markdown/Tags/EscapeTag.cs +++ b/cs/Markdown/Tags/EscapeTag.cs @@ -6,4 +6,24 @@ public class EscapeTag : ITag public string Tail => ""; public string MdView => """\"""; public TagType Type => TagType.Escape; + private Stack currentStack; + public int TokenPosition { get; set; } + + public TagKind TagRule(char ch, int position) + { + return TagKind.None; + } + + public ITag CreateNewTag() + { + return new EscapeTag(); + } + public void GetCurrentStack(in Stack stack) + { + currentStack = stack; + } + + public void ResetRule() + { + } } \ No newline at end of file diff --git a/cs/Markdown/Tags/H1Tag.cs b/cs/Markdown/Tags/H1Tag.cs index 3e673d3a2..2d5288b31 100644 --- a/cs/Markdown/Tags/H1Tag.cs +++ b/cs/Markdown/Tags/H1Tag.cs @@ -8,4 +8,25 @@ public class H1Tag : ITag public string Tail => ""; public string MdView => "# "; public TagType Type => TagType.Header; + private Stack currentStack; + public int TokenPosition { get; set; } + + public TagKind TagRule(char ch, int position) + { + return TagKind.None; + } + + public ITag CreateNewTag() + { + return new H1Tag(); + } + + public void GetCurrentStack(in Stack stack) + { + currentStack = stack; + } + + public void ResetRule() + { + } } \ No newline at end of file diff --git a/cs/Markdown/Tags/ITag.cs b/cs/Markdown/Tags/ITag.cs index ab07d4324..cd98890e0 100644 --- a/cs/Markdown/Tags/ITag.cs +++ b/cs/Markdown/Tags/ITag.cs @@ -6,4 +6,10 @@ public interface ITag public string Head { get;} public string Tail { get;} public TagType Type { get; } + public int TokenPosition { get; set; } + + public TagKind TagRule(char ch, int position); + public ITag CreateNewTag(); + public void GetCurrentStack(in Stack stack); + public void ResetRule(); } \ No newline at end of file diff --git a/cs/Markdown/Tags/ItalicTextTag.cs b/cs/Markdown/Tags/ItalicTextTag.cs index 0d63d276b..30e11cddd 100644 --- a/cs/Markdown/Tags/ItalicTextTag.cs +++ b/cs/Markdown/Tags/ItalicTextTag.cs @@ -1,4 +1,5 @@ using Markdown.Tags; +using Microsoft.VisualBasic; namespace Markdown.Tags; @@ -8,4 +9,50 @@ public class ItalicTextTag : ITag public string Tail => ""; public string MdView => "_"; public TagType Type => TagType.ItalicText; + private bool state; + private Stack currentStack; + private int startPosition; + public int TokenPosition { get; set; } + + public TagKind TagRule(char ch, int position) + { + if (state && char.IsLetter(ch) && currentStack.Count == 0) + { + state = false; + currentStack.Push(CreateNewTag()); + return TagKind.Open; + } + if (state && (char.IsLetter(ch) || ch == ' ')) + { + state = false; + currentStack.Pop(); + return TagKind.Close; + } + if (ch == '_') + { + state = true; + TokenPosition = position; + } + if (state && ch != '_') + { + state = false; + } + + return TagKind.None; + } + + public ITag CreateNewTag() + { + return new ItalicTextTag(); + } + + public void GetCurrentStack(in Stack stack) + { + currentStack = stack; + } + + public void ResetRule() + { + state = false; + } } \ No newline at end of file diff --git a/cs/Markdown/Tags/TagKind.cs b/cs/Markdown/Tags/TagKind.cs new file mode 100644 index 000000000..b48209736 --- /dev/null +++ b/cs/Markdown/Tags/TagKind.cs @@ -0,0 +1,8 @@ +namespace Markdown.Tags; + +public enum TagKind +{ + None, + Open, + Close +} \ No newline at end of file diff --git a/cs/Markdown/Tags/TagType.cs b/cs/Markdown/Tags/TagType.cs index 073baa3ba..62b32b39b 100644 --- a/cs/Markdown/Tags/TagType.cs +++ b/cs/Markdown/Tags/TagType.cs @@ -2,6 +2,7 @@ public enum TagType { + None, Header, ItalicText, BoldText, From d954e38daa8e91b1cb07fd1837d3e953b5ede111 Mon Sep 17 00:00:00 2001 From: Leonid Date: Tue, 26 Nov 2024 21:00:02 +0500 Subject: [PATCH 06/15] add escape --- cs/Markdown/Program.cs | 4 +--- cs/Markdown/TagParser.cs | 18 +++++++++++++----- cs/Markdown/Tags/BoldTag.cs | 10 ++++++++-- cs/Markdown/Tags/EscapeTag.cs | 18 +++++++++++++++++- cs/Markdown/Tags/ItalicTextTag.cs | 9 +++++++-- 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs index 5b88a97d1..8b7c2a885 100644 --- a/cs/Markdown/Program.cs +++ b/cs/Markdown/Program.cs @@ -1,5 +1,3 @@ using Markdown; -// text \n\n\n _text123_ -Console.WriteLine(Md.Render("__markdown _bobo_ __ a")); -// _text123_ __markdown__ a \ No newline at end of file +Console.WriteLine(Md.Render("__test \\_ _markdown_ text__ another text")); \ No newline at end of file diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index 7f3396b8c..1b4fe7524 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -8,6 +8,7 @@ public class TagParser { //private readonly List<(Stack, TagType)> TagsOrder; private readonly Dictionary > TagsOrder = new(); + private readonly Dictionary> TokensOrder = new(); private readonly List<(Func, ITag)> Rules = new(); public TagParser(List tags) @@ -16,6 +17,7 @@ public TagParser(List tags) { Rules.Add((tag.TagRule, tag)); TagsOrder.Add(tag.Type, new Stack()); + TokensOrder.Add(tag.Type, new Stack()); tag.GetCurrentStack(TagsOrder[tag.Type]); } } @@ -36,18 +38,24 @@ public List GetTokens(string text) var sourceText = rule.Item2.MdView; var convertedText = rule.Item2.Head; var pos = rule.Item2.TokenPosition; - tokens.Add(new Token.Token(sourceText, convertedText, pos)); + TokensOrder[rule.Item2.Type].Push(new Token.Token(sourceText, convertedText, pos)); + //tokens.Add(new Token.Token(sourceText, convertedText, pos)); ResetAllRules(); break; // TagsOrder[rule.Item2.Type].Append(rule.Item2.CreateNewTag()); } if (result == TagKind.Close) { + IToken prevToken; + if (TokensOrder[rule.Item2.Type].TryPop(out prevToken)) + { + tokens.Add(prevToken); + var sourceText = rule.Item2.MdView; + var convertedText = rule.Item2.Tail; + var pos = rule.Item2.TokenPosition; + tokens.Add(new Token.Token(sourceText, convertedText, pos)); + } globalContext = rule.Item2.Type; - var sourceText = rule.Item2.MdView; - var convertedText = rule.Item2.Tail; - var pos = rule.Item2.TokenPosition; - tokens.Add(new Token.Token(sourceText, convertedText, pos)); ResetAllRules(); break; // TagsOrder[rule.Item2.Type].Append(rule.Item2.CreateNewTag()); diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs index f2b001632..d872fe1a2 100644 --- a/cs/Markdown/Tags/BoldTag.cs +++ b/cs/Markdown/Tags/BoldTag.cs @@ -23,8 +23,14 @@ public TagKind TagRule(char ch, int position) if (state == 2 && (char.IsLetter(ch) || ch == ' ')) { state = 0; - currentStack.Pop(); - return TagKind.Close; + ITag tag; + if (currentStack.TryPop(out tag)) + { + return TagKind.Close; + } + return TagKind.None; + //currentStack.Pop(); + //return TagKind.Close; } if (state == 1 && ch == '_') { diff --git a/cs/Markdown/Tags/EscapeTag.cs b/cs/Markdown/Tags/EscapeTag.cs index 9a1e49cb5..6c438d49f 100644 --- a/cs/Markdown/Tags/EscapeTag.cs +++ b/cs/Markdown/Tags/EscapeTag.cs @@ -3,14 +3,30 @@ public class EscapeTag : ITag { public string Head => ""; - public string Tail => ""; + private string symbol; + public string Tail => symbol; public string MdView => """\"""; public TagType Type => TagType.Escape; private Stack currentStack; public int TokenPosition { get; set; } + private char previousCharecter; public TagKind TagRule(char ch, int position) { + if (previousCharecter == '\\' && (ch == '_' || ch == '\\')) + { + TokenPosition = position; + symbol = ch.ToString(); + previousCharecter = ch; + return TagKind.Close; + } + if (ch == '\\') + { + TokenPosition = position; + previousCharecter = ch; + return TagKind.Open; + } + previousCharecter = ch; return TagKind.None; } diff --git a/cs/Markdown/Tags/ItalicTextTag.cs b/cs/Markdown/Tags/ItalicTextTag.cs index 30e11cddd..317cc10e1 100644 --- a/cs/Markdown/Tags/ItalicTextTag.cs +++ b/cs/Markdown/Tags/ItalicTextTag.cs @@ -25,8 +25,13 @@ public TagKind TagRule(char ch, int position) if (state && (char.IsLetter(ch) || ch == ' ')) { state = false; - currentStack.Pop(); - return TagKind.Close; + ITag tag; + if (currentStack.TryPop(out tag)) + { + return TagKind.Close; + } + //currentStack.Pop(); + return TagKind.None; } if (ch == '_') { From ec240a37763d84157998c298e6e5902d55c94b5a Mon Sep 17 00:00:00 2001 From: Leonid Date: Tue, 26 Nov 2024 21:02:01 +0500 Subject: [PATCH 07/15] small fixes --- cs/Markdown/TagParser.cs | 5 ----- cs/Markdown/Tags/BoldTag.cs | 2 -- cs/Markdown/Tags/ItalicTextTag.cs | 1 - 3 files changed, 8 deletions(-) diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index 1b4fe7524..68590787b 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -6,7 +6,6 @@ namespace Markdown; public class TagParser { - //private readonly List<(Stack, TagType)> TagsOrder; private readonly Dictionary > TagsOrder = new(); private readonly Dictionary> TokensOrder = new(); private readonly List<(Func, ITag)> Rules = new(); @@ -39,10 +38,8 @@ public List GetTokens(string text) var convertedText = rule.Item2.Head; var pos = rule.Item2.TokenPosition; TokensOrder[rule.Item2.Type].Push(new Token.Token(sourceText, convertedText, pos)); - //tokens.Add(new Token.Token(sourceText, convertedText, pos)); ResetAllRules(); break; - // TagsOrder[rule.Item2.Type].Append(rule.Item2.CreateNewTag()); } if (result == TagKind.Close) { @@ -58,12 +55,10 @@ public List GetTokens(string text) globalContext = rule.Item2.Type; ResetAllRules(); break; - // TagsOrder[rule.Item2.Type].Append(rule.Item2.CreateNewTag()); } } textPointer++; - // Обработка конца строки проверка стэка с типом Header } return tokens; diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs index d872fe1a2..b662624c0 100644 --- a/cs/Markdown/Tags/BoldTag.cs +++ b/cs/Markdown/Tags/BoldTag.cs @@ -29,8 +29,6 @@ public TagKind TagRule(char ch, int position) return TagKind.Close; } return TagKind.None; - //currentStack.Pop(); - //return TagKind.Close; } if (state == 1 && ch == '_') { diff --git a/cs/Markdown/Tags/ItalicTextTag.cs b/cs/Markdown/Tags/ItalicTextTag.cs index 317cc10e1..170f019c2 100644 --- a/cs/Markdown/Tags/ItalicTextTag.cs +++ b/cs/Markdown/Tags/ItalicTextTag.cs @@ -30,7 +30,6 @@ public TagKind TagRule(char ch, int position) { return TagKind.Close; } - //currentStack.Pop(); return TagKind.None; } if (ch == '_') From 7d337ad538c957114d0fbe725e6d3d5766ff5743 Mon Sep 17 00:00:00 2001 From: Leonid Date: Sat, 30 Nov 2024 23:53:12 +0500 Subject: [PATCH 08/15] raw variant of state machine --- cs/Markdown/Md.cs | 8 +- cs/Markdown/Program.cs | 4 +- cs/Markdown/Rule/Rule.cs | 66 ++++++ cs/Markdown/SymbolStatus.cs | 15 ++ cs/Markdown/SymbolStatusParser.cs | 25 ++ cs/Markdown/TagParser.cs | 86 ++++--- cs/Markdown/Tags/BoldTag.cs | 378 ++++++++++++++++++++++++++---- cs/Markdown/Tags/EscapeTag.cs | 88 ++++--- cs/Markdown/Tags/H1Tag.cs | 95 ++++++-- cs/Markdown/Tags/ITag.cs | 22 +- cs/Markdown/Tags/ItalicTextTag.cs | 149 ++++++++---- 11 files changed, 758 insertions(+), 178 deletions(-) create mode 100644 cs/Markdown/Rule/Rule.cs create mode 100644 cs/Markdown/SymbolStatus.cs create mode 100644 cs/Markdown/SymbolStatusParser.cs diff --git a/cs/Markdown/Md.cs b/cs/Markdown/Md.cs index 1ee40ff65..251ab8d0f 100644 --- a/cs/Markdown/Md.cs +++ b/cs/Markdown/Md.cs @@ -8,10 +8,10 @@ public static class Md { private static List availableTags = [ - new BoldTag(), + //new BoldTag(), new H1Tag(), - new ItalicTextTag(), - new EscapeTag() + //new ItalicTextTag(), + //new EscapeTag() ]; public static string Render(string text) @@ -29,7 +29,7 @@ private static string GenerateHtml(string text, List tokens) { sb.Append(text[position..token.Position]); sb.Append(token.ConvertedText); - position = token.Position + token.SourceText.Length; + position = token.Position + token.SourceText.Length > text.Length ? text.Length : token.Position + token.SourceText.Length; } sb.Append(text[position..text.Length]); diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs index 8b7c2a885..a4fe4e540 100644 --- a/cs/Markdown/Program.cs +++ b/cs/Markdown/Program.cs @@ -1,3 +1,5 @@ using Markdown; -Console.WriteLine(Md.Render("__test \\_ _markdown_ text__ another text")); \ No newline at end of file +Console.WriteLine(Md.Render("# Aboba")); +//__test \_ _markdown_ text__ another text +// _Markdown123_ \ No newline at end of file diff --git a/cs/Markdown/Rule/Rule.cs b/cs/Markdown/Rule/Rule.cs new file mode 100644 index 000000000..a03f3c3a0 --- /dev/null +++ b/cs/Markdown/Rule/Rule.cs @@ -0,0 +1,66 @@ +using System.ComponentModel.DataAnnotations; +using Markdown.Tags; + +namespace Markdown.Rule; + +public class Rule +{ + private readonly SymbolStatus[] usedSymbols; + private Dictionary> states; + private List tokens = new(); + private readonly int inputStateNumber; + private readonly int[] subOutputStateNumbers; + private readonly int outputStateNumber; + private int currentState; + private ITag currentTag; + + public Rule(ITag tag) + { + usedSymbols = tag.UsedSymbols; + states = tag.States; + currentTag = tag; + inputStateNumber = tag.InputStateNumber; + subOutputStateNumbers = tag.SubOutputStateNumbers; + outputStateNumber = tag.OutputStateNumber; + } + + public TagKind MoveByRule(char ch, int position) + { + var symbol = SymbolStatusParser.ParseSymbolStatus(ch); + + if (!usedSymbols.Contains(symbol)) + { + symbol = SymbolStatus.anotherSymbol; + } + + currentState = states[currentState][symbol]; + + if (symbol == SymbolStatus.eof && (currentState == outputStateNumber || subOutputStateNumbers.Contains(currentState))) + { + tokens.Add(new Token.Token(currentTag.MdView, currentTag.Tail, position + 1)); + return TagKind.Close; + } + + if (currentState == inputStateNumber) + { + tokens.Add(new Token.Token(currentTag.MdView, currentTag.Head, position - (currentTag.MdView.Length - 1))); + } + else if (subOutputStateNumbers.Contains(currentState)) + { + tokens.Add(new Token.Token(currentTag.MdView, currentTag.Tail, position - (currentTag.MdView.Length - 1))); // ? + } + else if (currentState == outputStateNumber) + { + tokens.Add(new Token.Token(currentTag.MdView, currentTag.Tail, position - (currentTag.MdView.Length - 1))); // ? + return TagKind.Close; + } + else if (currentState == 0) + { + tokens.Clear(); + } + + return TagKind.None; + } + + public List GetTokens() { return tokens; } +} \ No newline at end of file diff --git a/cs/Markdown/SymbolStatus.cs b/cs/Markdown/SymbolStatus.cs new file mode 100644 index 000000000..dfee05115 --- /dev/null +++ b/cs/Markdown/SymbolStatus.cs @@ -0,0 +1,15 @@ +namespace Markdown; + +public enum SymbolStatus +{ + text, + digit, + underscore, + backslash, + eof, + newline, + space, + sharp, + anotherSymbol, + none +} \ No newline at end of file diff --git a/cs/Markdown/SymbolStatusParser.cs b/cs/Markdown/SymbolStatusParser.cs new file mode 100644 index 000000000..32ce1abd7 --- /dev/null +++ b/cs/Markdown/SymbolStatusParser.cs @@ -0,0 +1,25 @@ +namespace Markdown; + +public static class SymbolStatusParser +{ + public static SymbolStatus ParseSymbolStatus(char symbol) + { + if (char.IsLetter(symbol)) + return SymbolStatus.text; + if (char.IsDigit(symbol)) + return SymbolStatus.digit; + if (symbol == ' ') + return SymbolStatus.space; + if (symbol == '_') + return SymbolStatus.underscore; + if (symbol == '\\') + return SymbolStatus.backslash; + if (symbol == '\n') + return SymbolStatus.newline; + if (symbol == '\0') + return SymbolStatus.eof; + if (symbol == '#') + return SymbolStatus.sharp; + return SymbolStatus.none; + } +} \ No newline at end of file diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index 68590787b..a7a798eb4 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -6,69 +6,81 @@ namespace Markdown; public class TagParser { - private readonly Dictionary > TagsOrder = new(); - private readonly Dictionary> TokensOrder = new(); - private readonly List<(Func, ITag)> Rules = new(); + //private readonly Dictionary > TagsOrder = new(); + //private readonly Dictionary> TokensOrder = new(); + //private readonly List<(Func, ITag)> Rules = new(); + + private readonly List Rules = new(); public TagParser(List tags) { foreach (var tag in tags) { - Rules.Add((tag.TagRule, tag)); - TagsOrder.Add(tag.Type, new Stack()); - TokensOrder.Add(tag.Type, new Stack()); - tag.GetCurrentStack(TagsOrder[tag.Type]); + //Rules.Add((tag.TagRule, tag)); + //TagsOrder.Add(tag.Type, new Stack()); + //TokensOrder.Add(tag.Type, new Stack()); + //tag.GetCurrentStack(TagsOrder[tag.Type]); + //tag.InitialzeStates(); + + Rules.Add(new Rule.Rule(tag)); } } public List GetTokens(string text) { var tokens = new List {}; - var globalContext = TagType.None; var textPointer = 0; while (textPointer != text.Length) { + //foreach (var rule in Rules) + //{ + // var result = rule.Item1(text[textPointer], textPointer); + // if (result == TagKind.Close) + // { + // tokens.Add(new Token.Token(rule.Item2.MdView, rule.Item2.Head, rule.Item2.Positions[0])); + // tokens.Add(new Token.Token(rule.Item2.MdView, rule.Item2.Tail, rule.Item2.Positions[1])); + // } + //} + foreach (var rule in Rules) { - var result = rule.Item1(text[textPointer], textPointer); - if (result == TagKind.Open) - { - globalContext = rule.Item2.Type; - var sourceText = rule.Item2.MdView; - var convertedText = rule.Item2.Head; - var pos = rule.Item2.TokenPosition; - TokensOrder[rule.Item2.Type].Push(new Token.Token(sourceText, convertedText, pos)); - ResetAllRules(); - break; - } + var result = rule.MoveByRule(text[textPointer], textPointer); if (result == TagKind.Close) { - IToken prevToken; - if (TokensOrder[rule.Item2.Type].TryPop(out prevToken)) - { - tokens.Add(prevToken); - var sourceText = rule.Item2.MdView; - var convertedText = rule.Item2.Tail; - var pos = rule.Item2.TokenPosition; - tokens.Add(new Token.Token(sourceText, convertedText, pos)); - } - globalContext = rule.Item2.Type; - ResetAllRules(); - break; + tokens.AddRange(rule.GetTokens()); } } textPointer++; } - return tokens; - } - - private void ResetAllRules() - { foreach (var rule in Rules) { - rule.Item2.ResetRule(); + var result = rule.MoveByRule('\0', textPointer - 1); + if (result == TagKind.Close) + { + tokens.AddRange(rule.GetTokens()); + } } + + //foreach (var rule in Rules) + //{ + // var result = rule.Item1('\0', textPointer - 1); + // if (result == TagKind.Close) + // { + // tokens.Add(new Token.Token(rule.Item2.MdView, rule.Item2.Head, rule.Item2.Positions[0])); + // tokens.Add(new Token.Token(rule.Item2.MdView, rule.Item2.Tail, rule.Item2.Positions[1])); + // } + //} + + return tokens; } + + //private void ResetAllRules() + //{ + // foreach (var rule in Rules) + // { + // rule.Item2.ResetRule(); + // } + //} } \ No newline at end of file diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs index b662624c0..738e2e754 100644 --- a/cs/Markdown/Tags/BoldTag.cs +++ b/cs/Markdown/Tags/BoldTag.cs @@ -8,56 +8,344 @@ public class BoldTag : ITag public string Tail => ""; public string MdView => "__"; public TagType Type => TagType.BoldText; - private int state; - private Stack currentStack; - public int TokenPosition { get; set; } + //private int state; + //private Stack currentStack; + //public int TokenPosition { get; set; } - public TagKind TagRule(char ch, int position) - { - if (state == 2 && char.IsLetter(ch) && currentStack.Count == 0) - { - state = 0; - currentStack.Push(CreateNewTag()); - return TagKind.Open; - } - if (state == 2 && (char.IsLetter(ch) || ch == ' ')) - { - state = 0; - ITag tag; - if (currentStack.TryPop(out tag)) - { - return TagKind.Close; - } - return TagKind.None; - } - if (state == 1 && ch == '_') - { - state = 2; - } - else if (ch == '_') - { - state = 1; - TokenPosition = position; - } - if ((state == 1 || state == 2) && ch != '_') - { - state = 0; - } - return TagKind.None; - } + public int InputStateNumber { get; } = 2; + public int[] SubOutputStateNumbers { get; } = {11, 16}; + public int OutputStateNumber { get; } = 21; - public ITag CreateNewTag() - { - return new BoldTag(); - } + private static Dictionary> states = new(); + + public Dictionary> States { get; } = InitialzeStates(); - public void GetCurrentStack(in Stack stack) + public SymbolStatus[] UsedSymbols { get; } = { - currentStack = stack; - } + SymbolStatus.text, SymbolStatus.digit, SymbolStatus.underscore + , SymbolStatus.eof, SymbolStatus.newline, SymbolStatus.space, + SymbolStatus.anotherSymbol + }; - public void ResetRule() + public static Dictionary> InitialzeStates() { - state = 0; + states.Add(0, new Dictionary()); + states.Add(1, new Dictionary()); + states.Add(2, new Dictionary()); + states.Add(3, new Dictionary()); + states.Add(4, new Dictionary()); + states.Add(5, new Dictionary()); + states.Add(6, new Dictionary()); + states.Add(7, new Dictionary()); + states.Add(8, new Dictionary()); + states.Add(9, new Dictionary()); + states.Add(10, new Dictionary()); + states.Add(11, new Dictionary()); + states.Add(12, new Dictionary()); + states.Add(13, new Dictionary()); + states.Add(14, new Dictionary()); + states.Add(15, new Dictionary()); + states.Add(16, new Dictionary()); + states.Add(17, new Dictionary()); + states.Add(18, new Dictionary()); + states.Add(19, new Dictionary()); + states.Add(20, new Dictionary()); + states.Add(21, new Dictionary()); + + states.Add(22, new Dictionary()); + states.Add(23, new Dictionary()); + states.Add(24, new Dictionary()); + states.Add(25, new Dictionary()); + states.Add(26, new Dictionary()); + states.Add(27, new Dictionary()); + states.Add(28, new Dictionary()); + states.Add(29, new Dictionary()); + states.Add(30, new Dictionary()); + states.Add(31, new Dictionary()); + + states[0].Add(SymbolStatus.text, 0); + states[0].Add(SymbolStatus.digit, 0); + states[0].Add(SymbolStatus.underscore, 1); + states[0].Add(SymbolStatus.eof, 0); + states[0].Add(SymbolStatus.newline, 0); + states[0].Add(SymbolStatus.space, 0); + states[0].Add(SymbolStatus.anotherSymbol, 0); + + states[1].Add(SymbolStatus.text, 9); + states[1].Add(SymbolStatus.digit, 0); + states[1].Add(SymbolStatus.underscore, 2); + states[1].Add(SymbolStatus.eof, 0); + states[1].Add(SymbolStatus.newline, 0); + states[1].Add(SymbolStatus.space, 9); + states[1].Add(SymbolStatus.anotherSymbol, 9); + + // Tag Open + states[2].Add(SymbolStatus.text, 3); + states[2].Add(SymbolStatus.digit, 0); + states[2].Add(SymbolStatus.underscore, 7); + states[2].Add(SymbolStatus.eof, 0); + states[2].Add(SymbolStatus.newline, 0); + states[2].Add(SymbolStatus.space, 4); + states[2].Add(SymbolStatus.anotherSymbol, 3); + + states[3].Add(SymbolStatus.text, 3); + states[3].Add(SymbolStatus.digit, 0); + states[3].Add(SymbolStatus.underscore, 6); + states[3].Add(SymbolStatus.eof, 0); + states[3].Add(SymbolStatus.newline, 0); + states[3].Add(SymbolStatus.space, 4); + states[3].Add(SymbolStatus.anotherSymbol, 3); + + states[4].Add(SymbolStatus.text, 5); + states[4].Add(SymbolStatus.digit, 0); + states[4].Add(SymbolStatus.underscore, 1); + states[4].Add(SymbolStatus.eof, 0); + states[4].Add(SymbolStatus.newline, 0); + states[4].Add(SymbolStatus.space, 4); + states[4].Add(SymbolStatus.anotherSymbol, 5); + + states[5].Add(SymbolStatus.text, 5); + states[5].Add(SymbolStatus.digit, 0); + states[5].Add(SymbolStatus.underscore, 6); + states[5].Add(SymbolStatus.eof, 0); + states[5].Add(SymbolStatus.newline, 0); + states[5].Add(SymbolStatus.space, 4); + states[5].Add(SymbolStatus.anotherSymbol, 5); + + states[6].Add(SymbolStatus.text, 17); + states[6].Add(SymbolStatus.digit, 0); + states[6].Add(SymbolStatus.underscore, 21); + states[6].Add(SymbolStatus.eof, 0); + states[6].Add(SymbolStatus.newline, 17); + states[6].Add(SymbolStatus.space, 4); + states[6].Add(SymbolStatus.anotherSymbol, 17); + + states[7].Add(SymbolStatus.text, 0); + states[7].Add(SymbolStatus.digit, 0); + states[7].Add(SymbolStatus.underscore, 8); + states[7].Add(SymbolStatus.eof, 0); + states[7].Add(SymbolStatus.newline, 0); + states[7].Add(SymbolStatus.space, 0); + states[7].Add(SymbolStatus.anotherSymbol, 0); + + states[8].Add(SymbolStatus.text, 0); + states[8].Add(SymbolStatus.digit, 0); + states[8].Add(SymbolStatus.underscore, 0); + states[8].Add(SymbolStatus.eof, 0); + states[8].Add(SymbolStatus.newline, 0); + states[8].Add(SymbolStatus.space, 0); + states[8].Add(SymbolStatus.anotherSymbol, 0); + + states[9].Add(SymbolStatus.text, 9); + states[9].Add(SymbolStatus.digit, 0); + states[9].Add(SymbolStatus.underscore, 10); + states[9].Add(SymbolStatus.eof, 0); + states[9].Add(SymbolStatus.newline, 0); + states[9].Add(SymbolStatus.space, 9); + states[9].Add(SymbolStatus.anotherSymbol, 9); + + states[10].Add(SymbolStatus.text, 0); + states[10].Add(SymbolStatus.digit, 0); + states[10].Add(SymbolStatus.underscore, 11); + states[10].Add(SymbolStatus.eof, 0); + states[10].Add(SymbolStatus.newline, 0); + states[10].Add(SymbolStatus.space, 0); + states[10].Add(SymbolStatus.anotherSymbol, 0); + + // TagSubOpen + states[11].Add(SymbolStatus.text, 12); + states[11].Add(SymbolStatus.digit, 0); + states[11].Add(SymbolStatus.underscore, 22); + states[11].Add(SymbolStatus.eof, 0); + states[11].Add(SymbolStatus.newline, 0); + states[11].Add(SymbolStatus.space, 13); + states[11].Add(SymbolStatus.anotherSymbol, 12); + + states[12].Add(SymbolStatus.text, 12); + states[12].Add(SymbolStatus.digit, 0); + states[12].Add(SymbolStatus.underscore, 15); + states[12].Add(SymbolStatus.eof, 0); + states[12].Add(SymbolStatus.newline, 0); + states[12].Add(SymbolStatus.space, 13); + states[12].Add(SymbolStatus.anotherSymbol, 12); + + states[13].Add(SymbolStatus.text, 14); + states[13].Add(SymbolStatus.digit, 0); + states[13].Add(SymbolStatus.underscore, 9); + states[13].Add(SymbolStatus.eof, 0); + states[13].Add(SymbolStatus.newline, 0); + states[13].Add(SymbolStatus.space, 13); + states[13].Add(SymbolStatus.anotherSymbol, 14); + + states[14].Add(SymbolStatus.text, 14); + states[14].Add(SymbolStatus.digit, 0); + states[14].Add(SymbolStatus.underscore, 15); + states[14].Add(SymbolStatus.eof, 0); + states[14].Add(SymbolStatus.newline, 0); + states[14].Add(SymbolStatus.space, 13); + states[14].Add(SymbolStatus.anotherSymbol, 14); + + states[15].Add(SymbolStatus.text, 0); + states[15].Add(SymbolStatus.digit, 0); + states[15].Add(SymbolStatus.underscore, 16); + states[15].Add(SymbolStatus.eof, 0); + states[15].Add(SymbolStatus.newline, 0); + states[15].Add(SymbolStatus.space, 0); + states[15].Add(SymbolStatus.anotherSymbol, 0); + + // TagSubClose + states[16].Add(SymbolStatus.text, 9); + states[16].Add(SymbolStatus.digit, 0); + states[16].Add(SymbolStatus.underscore, 16); + states[16].Add(SymbolStatus.eof, 21); + states[16].Add(SymbolStatus.newline, 21); + states[16].Add(SymbolStatus.space, 9); + states[16].Add(SymbolStatus.anotherSymbol, 9); + + states[17].Add(SymbolStatus.text, 17); + states[17].Add(SymbolStatus.digit, 0); + states[17].Add(SymbolStatus.underscore, 20); + states[17].Add(SymbolStatus.eof, 0); + states[17].Add(SymbolStatus.newline, 0); + states[17].Add(SymbolStatus.space, 18); + states[17].Add(SymbolStatus.anotherSymbol, 17); + + states[18].Add(SymbolStatus.text, 19); + states[18].Add(SymbolStatus.digit, 0); + states[18].Add(SymbolStatus.underscore, 20); + states[18].Add(SymbolStatus.eof, 0); + states[18].Add(SymbolStatus.newline, 0); + states[18].Add(SymbolStatus.space, 18); + states[18].Add(SymbolStatus.anotherSymbol, 19); + + states[19].Add(SymbolStatus.text, 19); + states[19].Add(SymbolStatus.digit, 0); + states[19].Add(SymbolStatus.underscore, 20); + states[19].Add(SymbolStatus.eof, 0); + states[19].Add(SymbolStatus.newline, 0); + states[19].Add(SymbolStatus.space, 18); + states[19].Add(SymbolStatus.anotherSymbol, 19); + + states[20].Add(SymbolStatus.text, 3); + states[20].Add(SymbolStatus.digit, 0); + states[20].Add(SymbolStatus.underscore, 24); + states[20].Add(SymbolStatus.eof, 0); + states[20].Add(SymbolStatus.newline, 0); + states[20].Add(SymbolStatus.space, 4); + states[20].Add(SymbolStatus.anotherSymbol, 3); + + // TagClose + states[21].Add(SymbolStatus.text, 0); + states[21].Add(SymbolStatus.digit, 0); + states[21].Add(SymbolStatus.underscore, 1); + states[21].Add(SymbolStatus.eof, 0); + states[21].Add(SymbolStatus.newline, 0); + states[21].Add(SymbolStatus.space, 0); + states[21].Add(SymbolStatus.anotherSymbol, 0); + + states[22].Add(SymbolStatus.text, 9); + states[22].Add(SymbolStatus.digit, 0); + states[22].Add(SymbolStatus.underscore, 9); + states[22].Add(SymbolStatus.eof, 0); + states[22].Add(SymbolStatus.newline, 0); + states[22].Add(SymbolStatus.space, 9); + states[22].Add(SymbolStatus.anotherSymbol, 9); + + states[23].Add(SymbolStatus.text, 11); + states[23].Add(SymbolStatus.digit, 0); + states[23].Add(SymbolStatus.underscore, 11); + states[23].Add(SymbolStatus.eof, 0); + states[23].Add(SymbolStatus.newline, 0); + states[23].Add(SymbolStatus.space, 11); + states[23].Add(SymbolStatus.anotherSymbol, 11); + + states[24].Add(SymbolStatus.text, 26); + states[24].Add(SymbolStatus.digit, 0); + states[24].Add(SymbolStatus.underscore, 25); + states[24].Add(SymbolStatus.eof, 0); + states[24].Add(SymbolStatus.newline, 0); + states[24].Add(SymbolStatus.space, 27); + states[24].Add(SymbolStatus.anotherSymbol, 26); + + states[25].Add(SymbolStatus.text, 17); + states[25].Add(SymbolStatus.digit, 0); + states[25].Add(SymbolStatus.underscore, 17); + states[25].Add(SymbolStatus.eof, 0); + states[25].Add(SymbolStatus.newline, 0); + states[25].Add(SymbolStatus.space, 17); + states[25].Add(SymbolStatus.anotherSymbol, 17); + + states[26].Add(SymbolStatus.text, 26); + states[26].Add(SymbolStatus.digit, 0); + states[26].Add(SymbolStatus.underscore, 29); + states[26].Add(SymbolStatus.eof, 0); + states[26].Add(SymbolStatus.newline, 0); + states[26].Add(SymbolStatus.space, 27); + states[26].Add(SymbolStatus.anotherSymbol, 26); + + states[27].Add(SymbolStatus.text, 28); + states[27].Add(SymbolStatus.digit, 0); + states[27].Add(SymbolStatus.underscore, 24); + states[27].Add(SymbolStatus.eof, 0); + states[27].Add(SymbolStatus.newline, 0); + states[27].Add(SymbolStatus.space, 27); + states[27].Add(SymbolStatus.anotherSymbol, 28); + + states[28].Add(SymbolStatus.text, 28); + states[28].Add(SymbolStatus.digit, 0); + states[28].Add(SymbolStatus.underscore, 29); + states[28].Add(SymbolStatus.eof, 0); + states[28].Add(SymbolStatus.newline, 0); + states[28].Add(SymbolStatus.space, 27); + states[28].Add(SymbolStatus.anotherSymbol, 28); + + states[29].Add(SymbolStatus.text, 0); + states[29].Add(SymbolStatus.digit, 0); + states[29].Add(SymbolStatus.underscore, 30); + states[29].Add(SymbolStatus.eof, 0); + states[29].Add(SymbolStatus.newline, 0); + states[29].Add(SymbolStatus.space, 0); + states[29].Add(SymbolStatus.anotherSymbol, 0); + + states[30].Add(SymbolStatus.text, 17); + states[30].Add(SymbolStatus.digit, 0); + states[30].Add(SymbolStatus.underscore, 31); + states[30].Add(SymbolStatus.eof, 0); + states[30].Add(SymbolStatus.newline, 0); + states[30].Add(SymbolStatus.space, 18); + states[30].Add(SymbolStatus.anotherSymbol, 17); + + states[31].Add(SymbolStatus.text, 26); + states[31].Add(SymbolStatus.digit, 0); + states[31].Add(SymbolStatus.underscore, 31); + states[31].Add(SymbolStatus.eof, 0); + states[31].Add(SymbolStatus.newline, 0); + states[31].Add(SymbolStatus.space, 27); + states[31].Add(SymbolStatus.anotherSymbol, 26); + + return states; } + //public int[] Positions { get; set; } = { 0, 0 }; + //public int[] MdLen { get; set; } = { 0, 0 }; + //public char[] PrevSymbols { get; set; } = { ' ', ' ' }; + + //public TagKind TagRule(char ch, int position) + //{ + // return TagKind.None; + //} + + //public ITag CreateNewTag() + //{ + // return new BoldTag(); + //} + + //public void GetCurrentStack(in Stack stack) + //{ + // currentStack = stack; + //} + + //public void ResetRule() + //{ + // state = 0; + //} } \ No newline at end of file diff --git a/cs/Markdown/Tags/EscapeTag.cs b/cs/Markdown/Tags/EscapeTag.cs index 6c438d49f..81c48511a 100644 --- a/cs/Markdown/Tags/EscapeTag.cs +++ b/cs/Markdown/Tags/EscapeTag.cs @@ -7,39 +7,69 @@ public class EscapeTag : ITag public string Tail => symbol; public string MdView => """\"""; public TagType Type => TagType.Escape; - private Stack currentStack; - public int TokenPosition { get; set; } - private char previousCharecter; + //private Stack currentStack; + //public int TokenPosition { get; set; } + //private char previousCharecter; - public TagKind TagRule(char ch, int position) - { - if (previousCharecter == '\\' && (ch == '_' || ch == '\\')) - { - TokenPosition = position; - symbol = ch.ToString(); - previousCharecter = ch; - return TagKind.Close; - } - if (ch == '\\') - { - TokenPosition = position; - previousCharecter = ch; - return TagKind.Open; - } - previousCharecter = ch; - return TagKind.None; - } + public int InputStateNumber { get; } = 1; + public int[] SubOutputStateNumbers { get; } = Array.Empty(); + public int OutputStateNumber { get; } = 2; - public ITag CreateNewTag() - { - return new EscapeTag(); - } - public void GetCurrentStack(in Stack stack) + private static Dictionary> states = new(); + + public Dictionary> States { get; } = InitialzeStates(); + + public SymbolStatus[] UsedSymbols { get; } = { - currentStack = stack; - } + SymbolStatus.backslash, SymbolStatus.underscore, SymbolStatus.anotherSymbol + }; - public void ResetRule() + public static Dictionary> InitialzeStates() { + states.Add(0, new Dictionary()); + states.Add(1, new Dictionary()); + states.Add(2, new Dictionary()); + + states[0].Add(SymbolStatus.backslash, 1); + states[0].Add(SymbolStatus.underscore, 0); + states[0].Add(SymbolStatus.anotherSymbol, 0); + + // Tag Open + states[1].Add(SymbolStatus.backslash, 2); + states[1].Add(SymbolStatus.underscore, 2); + states[1].Add(SymbolStatus.anotherSymbol, 0); + + // Tag Close + states[2].Add(SymbolStatus.backslash, 0); + states[2].Add(SymbolStatus.underscore, 0); + states[2].Add(SymbolStatus.anotherSymbol, 0); + + return states; } + + //public void InitialzeStates() + //{ + + //} + //public int[] Positions { get; set; } = { 0, 0 }; + //public int[] MdLen { get; set; } = { 0, 0 }; + //public char[] PrevSymbols { get; set; } = { ' ', ' ' }; + + //public TagKind TagRule(char ch, int position) + //{ + // return TagKind.None; + //} + + //public ITag CreateNewTag() + //{ + // return new EscapeTag(); + //} + //public void GetCurrentStack(in Stack stack) + //{ + // currentStack = stack; + //} + + //public void ResetRule() + //{ + //} } \ No newline at end of file diff --git a/cs/Markdown/Tags/H1Tag.cs b/cs/Markdown/Tags/H1Tag.cs index 2d5288b31..e88f6a902 100644 --- a/cs/Markdown/Tags/H1Tag.cs +++ b/cs/Markdown/Tags/H1Tag.cs @@ -8,25 +8,92 @@ public class H1Tag : ITag public string Tail => ""; public string MdView => "# "; public TagType Type => TagType.Header; - private Stack currentStack; - public int TokenPosition { get; set; } + //private Stack currentStack; + //public int TokenPosition { get; set; } - public TagKind TagRule(char ch, int position) - { - return TagKind.None; - } + public int InputStateNumber { get; } = 3; + public int[] SubOutputStateNumbers { get; } = Array.Empty(); + public int OutputStateNumber { get; } = 5; - public ITag CreateNewTag() - { - return new H1Tag(); - } + private static Dictionary> states = new(); + + public Dictionary> States { get; } = InitialzeStates(); - public void GetCurrentStack(in Stack stack) + public SymbolStatus[] UsedSymbols { get; } = { - currentStack = stack; - } + SymbolStatus.eof, SymbolStatus.newline, SymbolStatus.space, + SymbolStatus.sharp, SymbolStatus.anotherSymbol + }; - public void ResetRule() + public static Dictionary> InitialzeStates() { + states.Add(0, new Dictionary()); + states.Add(1, new Dictionary()); + states.Add(2, new Dictionary()); + states.Add(3, new Dictionary()); + states.Add(4, new Dictionary()); + states.Add(5, new Dictionary()); + + states[0].Add(SymbolStatus.sharp, 1); + states[0].Add(SymbolStatus.space, 2); + states[0].Add(SymbolStatus.newline, 0); + states[0].Add(SymbolStatus.eof, 0); + states[0].Add(SymbolStatus.anotherSymbol, 2); + + states[1].Add(SymbolStatus.sharp, 0); + states[1].Add(SymbolStatus.space, 3); + states[1].Add(SymbolStatus.newline, 0); + states[1].Add(SymbolStatus.eof, 0); + states[1].Add(SymbolStatus.anotherSymbol, 0); + + states[2].Add(SymbolStatus.sharp, 2); + states[2].Add(SymbolStatus.space, 2); + states[2].Add(SymbolStatus.newline, 0); + states[2].Add(SymbolStatus.eof, 0); + states[2].Add(SymbolStatus.anotherSymbol, 2); + + // Tag Open + states[3].Add(SymbolStatus.sharp, 4); + states[3].Add(SymbolStatus.space, 4); + states[3].Add(SymbolStatus.newline, 5); + states[3].Add(SymbolStatus.eof, 5); + states[3].Add(SymbolStatus.anotherSymbol, 4); + + states[4].Add(SymbolStatus.sharp, 4); + states[4].Add(SymbolStatus.space, 4); + states[4].Add(SymbolStatus.newline, 5); + states[4].Add(SymbolStatus.eof, 5); + states[4].Add(SymbolStatus.anotherSymbol, 4); + + // Tag Close + states[5].Add(SymbolStatus.sharp, 0); + states[5].Add(SymbolStatus.space, 0); + states[5].Add(SymbolStatus.newline, 0); + states[5].Add(SymbolStatus.eof, 0); + states[5].Add(SymbolStatus.anotherSymbol, 0); + + return states; } + //public int[] Positions { get; set; } = { 0, 0 }; + //public int[] MdLen { get; set; } = { 0, 0 }; + //public char[] PrevSymbols { get; set; } = { ' ', ' ' }; + + //public TagKind TagRule(char ch, int position) + //{ + // return TagKind.None; + //} + + //public ITag CreateNewTag() + //{ + // return new H1Tag(); + //} + + //public void GetCurrentStack(in Stack stack) + //{ + // currentStack = stack; + //} + + //public void ResetRule() + //{ + //} } \ No newline at end of file diff --git a/cs/Markdown/Tags/ITag.cs b/cs/Markdown/Tags/ITag.cs index cd98890e0..390799ca3 100644 --- a/cs/Markdown/Tags/ITag.cs +++ b/cs/Markdown/Tags/ITag.cs @@ -6,10 +6,22 @@ public interface ITag public string Head { get;} public string Tail { get;} public TagType Type { get; } - public int TokenPosition { get; set; } - public TagKind TagRule(char ch, int position); - public ITag CreateNewTag(); - public void GetCurrentStack(in Stack stack); - public void ResetRule(); + public SymbolStatus[] UsedSymbols { get; } + public Dictionary> States { get; } + + public int InputStateNumber { get; } + public int[] SubOutputStateNumbers { get; } + public int OutputStateNumber { get; } + + // public int TokenPosition { get; set; } + + //public TagKind TagRule(char ch, int position); + // public ITag CreateNewTag(); + // public void GetCurrentStack(in Stack stack); + // public void ResetRule(); + + // public void InitialzeStates(); + // public int[] Positions { get; set; } + // public char[] PrevSymbols { get; set; } } \ No newline at end of file diff --git a/cs/Markdown/Tags/ItalicTextTag.cs b/cs/Markdown/Tags/ItalicTextTag.cs index 170f019c2..4f72292fd 100644 --- a/cs/Markdown/Tags/ItalicTextTag.cs +++ b/cs/Markdown/Tags/ItalicTextTag.cs @@ -9,54 +9,117 @@ public class ItalicTextTag : ITag public string Tail => ""; public string MdView => "_"; public TagType Type => TagType.ItalicText; - private bool state; - private Stack currentStack; - private int startPosition; - public int TokenPosition { get; set; } - public TagKind TagRule(char ch, int position) - { - if (state && char.IsLetter(ch) && currentStack.Count == 0) - { - state = false; - currentStack.Push(CreateNewTag()); - return TagKind.Open; - } - if (state && (char.IsLetter(ch) || ch == ' ')) - { - state = false; - ITag tag; - if (currentStack.TryPop(out tag)) - { - return TagKind.Close; - } - return TagKind.None; - } - if (ch == '_') - { - state = true; - TokenPosition = position; - } - if (state && ch != '_') - { - state = false; - } - - return TagKind.None; - } + public int InputStateNumber { get; } = 1; + public int[] SubOutputStateNumbers { get; } = Array.Empty(); + public int OutputStateNumber { get; } = 4; - public ITag CreateNewTag() - { - return new ItalicTextTag(); - } + //private bool state; + //private Stack currentStack; + //private int startPosition; + //public int TokenPosition { get; set; } + + private static Dictionary> states = new(); - public void GetCurrentStack(in Stack stack) + public Dictionary> States { get; } = InitialzeStates(); + + public SymbolStatus[] UsedSymbols { get; } = { - currentStack = stack; - } + SymbolStatus.text, SymbolStatus.digit, SymbolStatus.underscore + , SymbolStatus.eof, SymbolStatus.newline, SymbolStatus.space + }; - public void ResetRule() + public static Dictionary> InitialzeStates() { - state = false; + states.Add(0, new Dictionary()); + states.Add(1, new Dictionary()); + states.Add(2, new Dictionary()); + states.Add(3, new Dictionary()); + states.Add(4, new Dictionary()); + + states[0].Add(SymbolStatus.text, 0); + states[0].Add(SymbolStatus.digit, 0); + states[0].Add(SymbolStatus.underscore, 1); + states[0].Add(SymbolStatus.backslash, 0); + states[0].Add(SymbolStatus.eof, 0); + states[0].Add(SymbolStatus.newline, 0); + states[0].Add(SymbolStatus.space, 0); + + // Начало + states[1].Add(SymbolStatus.text, 2); + states[1].Add(SymbolStatus.digit, 0); + states[1].Add(SymbolStatus.underscore, 0); + states[1].Add(SymbolStatus.backslash, 2); + states[1].Add(SymbolStatus.eof, 0); + states[1].Add(SymbolStatus.newline, 0); + states[1].Add(SymbolStatus.space, 0); + + states[2].Add(SymbolStatus.text, 2); + states[2].Add(SymbolStatus.digit, 0); + states[2].Add(SymbolStatus.underscore, 3); + states[2].Add(SymbolStatus.backslash, 2); + states[2].Add(SymbolStatus.eof, 0); + states[2].Add(SymbolStatus.newline, 0); + states[2].Add(SymbolStatus.space, 0); + + states[3].Add(SymbolStatus.text, 4); + states[3].Add(SymbolStatus.digit, 0); + states[3].Add(SymbolStatus.underscore, 0); + states[3].Add(SymbolStatus.backslash, 5); + states[3].Add(SymbolStatus.eof, 4); + states[3].Add(SymbolStatus.newline, 4); + states[3].Add(SymbolStatus.space, 4); + + // 4 состояние выхода + states[4].Add(SymbolStatus.text, 0); + states[4].Add(SymbolStatus.digit, 0); + states[4].Add(SymbolStatus.underscore, 0); + states[4].Add(SymbolStatus.backslash, 0); + states[4].Add(SymbolStatus.eof, 0); + states[4].Add(SymbolStatus.newline, 0); + states[4].Add(SymbolStatus.space, 0); + + return states; } + + //private int gloabalState; + //public int[] Positions { get; set; } = { 0, 0 }; + //public int[] MdLen { get; set; } = { 0, 0 }; + //public char[] PrevSymbols { get; set; } = { ' ', ' ' }; + + //public TagKind TagRule(char ch, int position) + //{ + // gloabalState = states[gloabalState][SymbolStatusParser.ParseSymbolStatus(ch)]; + // if (gloabalState == 1) + // { + // Positions[0] = position; + // MdLen[0] = 1; + // PrevSymbols[0] = ch; + // return TagKind.Open; + // } + + // if (gloabalState == 4) + // { + // Positions[1] = position; + // MdLen[1] = 1; + // PrevSymbols[1] = ch; + // return TagKind.Close; + // } + // return TagKind.None; + //} + + //public ITag CreateNewTag() + //{ + // return new ItalicTextTag(); + //} + + //public void GetCurrentStack(in Stack stack) + //{ + // currentStack = stack; + //} + + //public void ResetRule() + //{ + // state = false; + //} } \ No newline at end of file From db4069a9581c6abce3d07eb29757df78e8afa007 Mon Sep 17 00:00:00 2001 From: Leonid Date: Sun, 1 Dec 2024 22:06:06 +0500 Subject: [PATCH 09/15] non refactor works bold and italic --- cs/Markdown/Md.cs | 3 +- cs/Markdown/Program.cs | 2 +- cs/Markdown/Rules/BoldRule.cs | 88 ++++++++ cs/Markdown/Rules/EscapeRule.cs | 38 ++++ cs/Markdown/Rules/H1Rule.cs | 38 ++++ cs/Markdown/Rules/IRule.cs | 12 ++ cs/Markdown/Rules/ItalicRule.cs | 98 +++++++++ cs/Markdown/{Rule => Rules}/Rule.cs | 2 +- cs/Markdown/TagParser.cs | 38 ++-- cs/Markdown/Tags/BoldTag.cs | 287 ++++++-------------------- cs/Markdown/Tags/EscapeTag.cs | 4 +- cs/Markdown/Tags/H1Tag.cs | 4 +- cs/Markdown/Tags/ItalicTextTag.cs | 160 +++++++++++--- cs/MarkdownTests/MarkdownTest.cs | 60 +++++- cs/MarkdownTests/MarkdownTests.csproj | 1 + 15 files changed, 557 insertions(+), 278 deletions(-) create mode 100644 cs/Markdown/Rules/BoldRule.cs create mode 100644 cs/Markdown/Rules/EscapeRule.cs create mode 100644 cs/Markdown/Rules/H1Rule.cs create mode 100644 cs/Markdown/Rules/IRule.cs create mode 100644 cs/Markdown/Rules/ItalicRule.cs rename cs/Markdown/{Rule => Rules}/Rule.cs (98%) diff --git a/cs/Markdown/Md.cs b/cs/Markdown/Md.cs index 251ab8d0f..5a1b1b516 100644 --- a/cs/Markdown/Md.cs +++ b/cs/Markdown/Md.cs @@ -16,7 +16,8 @@ public static class Md public static string Render(string text) { - var parser = new TagParser(availableTags); + //var parser = new TagParser(availableTags); + var parser = new TagParser(); return GenerateHtml(text, parser.GetTokens(text)); } diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs index a4fe4e540..6b18889f8 100644 --- a/cs/Markdown/Program.cs +++ b/cs/Markdown/Program.cs @@ -1,5 +1,5 @@ using Markdown; -Console.WriteLine(Md.Render("# Aboba")); +Console.WriteLine(Md.Render("__a _b_ _c_ d__")); //__test \_ _markdown_ text__ another text // _Markdown123_ \ No newline at end of file diff --git a/cs/Markdown/Rules/BoldRule.cs b/cs/Markdown/Rules/BoldRule.cs new file mode 100644 index 000000000..432d125d8 --- /dev/null +++ b/cs/Markdown/Rules/BoldRule.cs @@ -0,0 +1,88 @@ +using Markdown.Tags; + +namespace Markdown.Rule; + +public class BoldRule : IRule +{ + private readonly ITag tag = new BoldTag(); + private List tokens = new(); + private bool isItalicInStart; + private bool isItalicInMiddle; + private bool isTagClosed; + private int currentState; + + // TODO List + // 1. Жирный начался в одном слове но кончился в другом + + public TagKind MoveByRule(char ch, int position) + { + var symbol = SymbolStatusParser.ParseSymbolStatus(ch); + + if (!tag.UsedSymbols.Contains(symbol)) + { + symbol = SymbolStatus.anotherSymbol; + } + + currentState = tag.States[currentState][symbol]; + + if (currentState == 0) + { + ClearTokens(); + } + + if (currentState == tag.InputStateNumber) + { + tokens.Add(new Token.Token(tag.MdView, tag.Head, position - (tag.MdView.Length - 1))); + } + else if (currentState == tag.OutputStateNumber) + { + tokens.Add(new Token.Token(tag.MdView, tag.Tail, position - (tag.MdView.Length - 1))); + isTagClosed = true; + } + else if (currentState == 9) + { + if (isItalicInMiddle) + { + isItalicInStart = false; + isItalicInMiddle = false; + isTagClosed = false; + currentState = 0; + tokens.Clear(); + } + else + { + isItalicInStart = !isItalicInStart; + } + } + else if (currentState == 10 || currentState == 12) + { + if (isItalicInStart) + { + isItalicInStart = false; + isItalicInMiddle = false; + isTagClosed = false; + currentState = 0; + tokens.Clear(); + } + else + { + isItalicInMiddle = !isItalicInMiddle; + } + + } + + // (!isItalicInStart || symbol == SymbolStatus.eof) + if (isTagClosed && ((!isItalicInMiddle && !isItalicInStart) || symbol == SymbolStatus.eof)) // (!isItalicInMiddle && !isItalicInStart) + { + isTagClosed = false; + currentState = 0; + return TagKind.Close; + } + + return TagKind.None; + } + + public List GetTokens() { return tokens; } + + public void ClearTokens() { tokens.Clear(); } +} \ No newline at end of file diff --git a/cs/Markdown/Rules/EscapeRule.cs b/cs/Markdown/Rules/EscapeRule.cs new file mode 100644 index 000000000..39f78ef33 --- /dev/null +++ b/cs/Markdown/Rules/EscapeRule.cs @@ -0,0 +1,38 @@ +using Markdown.Tags; + +namespace Markdown.Rule; + +public class EscapeRule : IRule +{ + private readonly ITag tag = new EscapeTag(); + private List tokens = new(); + private int currentState; + + public TagKind MoveByRule(char ch, int position) + { + var symbol = SymbolStatusParser.ParseSymbolStatus(ch); + + if (!tag.UsedSymbols.Contains(symbol)) + { + symbol = SymbolStatus.anotherSymbol; + } + + currentState = tag.States[currentState][symbol]; + + if (currentState == tag.InputStateNumber) + { + tokens.Add(new Token.Token(tag.MdView, tag.Head, position - (tag.MdView.Length - 1))); + } + else if (currentState == tag.OutputStateNumber) + { + tokens.Add(new Token.Token(tag.MdView, ch.ToString(), position - (tag.MdView.Length - 1))); + return TagKind.Close; + } + + return TagKind.None; + } + + public List GetTokens() { return tokens; } + + public void ClearTokens() { tokens.Clear(); } +} \ No newline at end of file diff --git a/cs/Markdown/Rules/H1Rule.cs b/cs/Markdown/Rules/H1Rule.cs new file mode 100644 index 000000000..ee88f3120 --- /dev/null +++ b/cs/Markdown/Rules/H1Rule.cs @@ -0,0 +1,38 @@ +using Markdown.Tags; + +namespace Markdown.Rule; + +public class H1Rule : IRule +{ + private readonly ITag tag = new H1Tag(); + private List tokens = new(); + private int currentState; + + public TagKind MoveByRule(char ch, int position) + { + var symbol = SymbolStatusParser.ParseSymbolStatus(ch); + + if (!tag.UsedSymbols.Contains(symbol)) + { + symbol = SymbolStatus.anotherSymbol; + } + + currentState = tag.States[currentState][symbol]; + + if (currentState == tag.InputStateNumber) + { + tokens.Add(new Token.Token(tag.MdView, tag.Head, position - (tag.MdView.Length - 1))); + } + else if (currentState == tag.OutputStateNumber) + { + tokens.Add(new Token.Token(tag.MdView, tag.Tail, position - (tag.MdView.Length - 1))); + return TagKind.Close; + } + + return TagKind.None; + } + + public List GetTokens() { return tokens; } + + public void ClearTokens() { tokens.Clear(); } +} \ No newline at end of file diff --git a/cs/Markdown/Rules/IRule.cs b/cs/Markdown/Rules/IRule.cs new file mode 100644 index 000000000..fd844f832 --- /dev/null +++ b/cs/Markdown/Rules/IRule.cs @@ -0,0 +1,12 @@ +using Markdown.Tags; + +namespace Markdown.Rule; + +public interface IRule +{ + public TagKind MoveByRule(char ch, int position); + + public List GetTokens(); + + public void ClearTokens(); +} \ No newline at end of file diff --git a/cs/Markdown/Rules/ItalicRule.cs b/cs/Markdown/Rules/ItalicRule.cs new file mode 100644 index 000000000..8a87a03c4 --- /dev/null +++ b/cs/Markdown/Rules/ItalicRule.cs @@ -0,0 +1,98 @@ +using Markdown.Tags; + +namespace Markdown.Rule; + +public class ItalicRule : IRule +{ + // TODO List + // 1. проверка обрыва строки (✓) + // 2. старт тэга в странном месте, возможно проблема (✕) + + private readonly ITag tag = new ItalicTextTag(); + private List tokens = new(); + private bool isBoldInMiddle; + private bool isBoldInStart; + private bool isTagClosed; + private int currentState; + + public TagKind MoveByRule(char ch, int position) + { + var symbol = SymbolStatusParser.ParseSymbolStatus(ch); + + if (!tag.UsedSymbols.Contains(symbol)) + { + symbol = SymbolStatus.anotherSymbol; + } + + currentState = tag.States[currentState][symbol]; + + if (currentState == 0) + { + ClearTokens(); + } + + if (currentState == tag.InputStateNumber || currentState == 14) + { + tokens.Add(new Token.Token(tag.MdView, tag.Head, position - (tag.MdView.Length - 1))); + } + else if (currentState == tag.OutputStateNumber) + { + if (symbol == SymbolStatus.eof) + { + tokens.Add(new Token.Token(tag.MdView, tag.Tail, position)); + } + else + { + tokens.Add(new Token.Token(tag.MdView, tag.Tail, position - tag.MdView.Length)); + } + isTagClosed = true; + //return TagKind.Close; + } + else if (currentState == 10) + { + //isBoldInStart = !isBoldInStart; + if (isBoldInMiddle) + { + isBoldInMiddle = false; + isBoldInStart = false; + isTagClosed = false; + currentState = 0; + tokens.Clear(); + } + else + { + isBoldInStart = !isBoldInStart; + } + } + else if (currentState == 7) + { + //isBoldInMiddle = !isBoldInMiddle; + if (isBoldInStart) + { + isBoldInMiddle = false; + isBoldInStart = false; + isTagClosed = false; + currentState = 0; + tokens.Clear(); + + } + else + { + isBoldInMiddle = !isBoldInMiddle; + } + } + + if (isTagClosed && (!isBoldInMiddle || symbol == SymbolStatus.eof)) + { + isTagClosed = false; + currentState = 0; + return TagKind.Close; + } + + return TagKind.None; + } + + public List GetTokens() { return tokens; } + + public void ClearTokens() { tokens.Clear(); } +} \ No newline at end of file diff --git a/cs/Markdown/Rule/Rule.cs b/cs/Markdown/Rules/Rule.cs similarity index 98% rename from cs/Markdown/Rule/Rule.cs rename to cs/Markdown/Rules/Rule.cs index a03f3c3a0..88d385988 100644 --- a/cs/Markdown/Rule/Rule.cs +++ b/cs/Markdown/Rules/Rule.cs @@ -12,7 +12,7 @@ public class Rule private readonly int[] subOutputStateNumbers; private readonly int outputStateNumber; private int currentState; - private ITag currentTag; + private readonly ITag currentTag; public Rule(ITag tag) { diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index a7a798eb4..1f4f2da11 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -1,4 +1,5 @@ using System.Collections; +using Markdown.Rule; using Markdown.Tags; using Markdown.Token; @@ -10,21 +11,31 @@ public class TagParser //private readonly Dictionary> TokensOrder = new(); //private readonly List<(Func, ITag)> Rules = new(); - private readonly List Rules = new(); + // + //private readonly List Rules = new(); - public TagParser(List tags) - { - foreach (var tag in tags) - { - //Rules.Add((tag.TagRule, tag)); - //TagsOrder.Add(tag.Type, new Stack()); - //TokensOrder.Add(tag.Type, new Stack()); - //tag.GetCurrentStack(TagsOrder[tag.Type]); - //tag.InitialzeStates(); + //public TagParser(List tags) + //{ + // foreach (var tag in tags) + // { + // //Rules.Add((tag.TagRule, tag)); + // //TagsOrder.Add(tag.Type, new Stack()); + // //TokensOrder.Add(tag.Type, new Stack()); + // //tag.GetCurrentStack(TagsOrder[tag.Type]); + // //tag.InitialzeStates(); - Rules.Add(new Rule.Rule(tag)); - } - } + // Rules.Add(new Rule.Rule(tag)); + // } + //} + // + + private List Rules = + [ + new BoldRule(), + new ItalicRule(), + //new EscapeRule(), + //new H1Rule() + ]; public List GetTokens(string text) { @@ -48,6 +59,7 @@ public List GetTokens(string text) if (result == TagKind.Close) { tokens.AddRange(rule.GetTokens()); + rule.ClearTokens(); } } diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs index 738e2e754..8b7023e09 100644 --- a/cs/Markdown/Tags/BoldTag.cs +++ b/cs/Markdown/Tags/BoldTag.cs @@ -12,11 +12,11 @@ public class BoldTag : ITag //private Stack currentStack; //public int TokenPosition { get; set; } - public int InputStateNumber { get; } = 2; + public int InputStateNumber { get; } = 2; // 4 public int[] SubOutputStateNumbers { get; } = {11, 16}; - public int OutputStateNumber { get; } = 21; + public int OutputStateNumber { get; } = 11; - private static Dictionary> states = new(); + //private static Dictionary> states = new(); public Dictionary> States { get; } = InitialzeStates(); @@ -29,6 +29,8 @@ public class BoldTag : ITag public static Dictionary> InitialzeStates() { + var states = new Dictionary>(); + states.Add(0, new Dictionary()); states.Add(1, new Dictionary()); states.Add(2, new Dictionary()); @@ -42,26 +44,6 @@ public static Dictionary> InitialzeStates() states.Add(10, new Dictionary()); states.Add(11, new Dictionary()); states.Add(12, new Dictionary()); - states.Add(13, new Dictionary()); - states.Add(14, new Dictionary()); - states.Add(15, new Dictionary()); - states.Add(16, new Dictionary()); - states.Add(17, new Dictionary()); - states.Add(18, new Dictionary()); - states.Add(19, new Dictionary()); - states.Add(20, new Dictionary()); - states.Add(21, new Dictionary()); - - states.Add(22, new Dictionary()); - states.Add(23, new Dictionary()); - states.Add(24, new Dictionary()); - states.Add(25, new Dictionary()); - states.Add(26, new Dictionary()); - states.Add(27, new Dictionary()); - states.Add(28, new Dictionary()); - states.Add(29, new Dictionary()); - states.Add(30, new Dictionary()); - states.Add(31, new Dictionary()); states[0].Add(SymbolStatus.text, 0); states[0].Add(SymbolStatus.digit, 0); @@ -76,252 +58,101 @@ public static Dictionary> InitialzeStates() states[1].Add(SymbolStatus.underscore, 2); states[1].Add(SymbolStatus.eof, 0); states[1].Add(SymbolStatus.newline, 0); - states[1].Add(SymbolStatus.space, 9); + states[1].Add(SymbolStatus.space, 0); // ? states[1].Add(SymbolStatus.anotherSymbol, 9); // Tag Open - states[2].Add(SymbolStatus.text, 3); + states[2].Add(SymbolStatus.text, 4); states[2].Add(SymbolStatus.digit, 0); - states[2].Add(SymbolStatus.underscore, 7); + states[2].Add(SymbolStatus.underscore, 3); states[2].Add(SymbolStatus.eof, 0); states[2].Add(SymbolStatus.newline, 0); - states[2].Add(SymbolStatus.space, 4); - states[2].Add(SymbolStatus.anotherSymbol, 3); + states[2].Add(SymbolStatus.space, 5); + states[2].Add(SymbolStatus.anotherSymbol, 4); - states[3].Add(SymbolStatus.text, 3); + states[3].Add(SymbolStatus.text, 0); states[3].Add(SymbolStatus.digit, 0); - states[3].Add(SymbolStatus.underscore, 6); + states[3].Add(SymbolStatus.underscore, 3); states[3].Add(SymbolStatus.eof, 0); states[3].Add(SymbolStatus.newline, 0); - states[3].Add(SymbolStatus.space, 4); - states[3].Add(SymbolStatus.anotherSymbol, 3); + states[3].Add(SymbolStatus.space, 0); + states[3].Add(SymbolStatus.anotherSymbol, 0); - states[4].Add(SymbolStatus.text, 5); + states[4].Add(SymbolStatus.text, 4); states[4].Add(SymbolStatus.digit, 0); - states[4].Add(SymbolStatus.underscore, 1); + states[4].Add(SymbolStatus.underscore, 7); states[4].Add(SymbolStatus.eof, 0); states[4].Add(SymbolStatus.newline, 0); - states[4].Add(SymbolStatus.space, 4); - states[4].Add(SymbolStatus.anotherSymbol, 5); + states[4].Add(SymbolStatus.space, 5); + states[4].Add(SymbolStatus.anotherSymbol, 4); - states[5].Add(SymbolStatus.text, 5); + states[5].Add(SymbolStatus.text, 6); states[5].Add(SymbolStatus.digit, 0); - states[5].Add(SymbolStatus.underscore, 6); + states[5].Add(SymbolStatus.underscore, 12); states[5].Add(SymbolStatus.eof, 0); states[5].Add(SymbolStatus.newline, 0); - states[5].Add(SymbolStatus.space, 4); - states[5].Add(SymbolStatus.anotherSymbol, 5); + states[5].Add(SymbolStatus.space, 5); + states[5].Add(SymbolStatus.anotherSymbol, 6); - states[6].Add(SymbolStatus.text, 17); + states[6].Add(SymbolStatus.text, 6); states[6].Add(SymbolStatus.digit, 0); - states[6].Add(SymbolStatus.underscore, 21); + states[6].Add(SymbolStatus.underscore, 7); states[6].Add(SymbolStatus.eof, 0); - states[6].Add(SymbolStatus.newline, 17); - states[6].Add(SymbolStatus.space, 4); - states[6].Add(SymbolStatus.anotherSymbol, 17); + states[6].Add(SymbolStatus.newline, 0); + states[6].Add(SymbolStatus.space, 5); + states[6].Add(SymbolStatus.anotherSymbol, 6); - states[7].Add(SymbolStatus.text, 0); + states[7].Add(SymbolStatus.text, 10); states[7].Add(SymbolStatus.digit, 0); states[7].Add(SymbolStatus.underscore, 8); states[7].Add(SymbolStatus.eof, 0); states[7].Add(SymbolStatus.newline, 0); - states[7].Add(SymbolStatus.space, 0); - states[7].Add(SymbolStatus.anotherSymbol, 0); - - states[8].Add(SymbolStatus.text, 0); - states[8].Add(SymbolStatus.digit, 0); - states[8].Add(SymbolStatus.underscore, 0); - states[8].Add(SymbolStatus.eof, 0); - states[8].Add(SymbolStatus.newline, 0); - states[8].Add(SymbolStatus.space, 0); - states[8].Add(SymbolStatus.anotherSymbol, 0); - - states[9].Add(SymbolStatus.text, 9); + states[7].Add(SymbolStatus.space, 10); + states[7].Add(SymbolStatus.anotherSymbol, 10); + + states[8].Add(SymbolStatus.text, 11); + states[8].Add(SymbolStatus.digit, 11); + states[8].Add(SymbolStatus.underscore, 2); + states[8].Add(SymbolStatus.eof, 11); + states[8].Add(SymbolStatus.newline, 11); + states[8].Add(SymbolStatus.space, 11); + states[8].Add(SymbolStatus.anotherSymbol, 11); + + // Maybe Bold in Italic + states[9].Add(SymbolStatus.text, 0); states[9].Add(SymbolStatus.digit, 0); - states[9].Add(SymbolStatus.underscore, 10); + states[9].Add(SymbolStatus.underscore, 1); states[9].Add(SymbolStatus.eof, 0); states[9].Add(SymbolStatus.newline, 0); - states[9].Add(SymbolStatus.space, 9); - states[9].Add(SymbolStatus.anotherSymbol, 9); + states[9].Add(SymbolStatus.space, 0); + states[9].Add(SymbolStatus.anotherSymbol, 0); - states[10].Add(SymbolStatus.text, 0); + // Maybe Italic in Bold + states[10].Add(SymbolStatus.text, 6); states[10].Add(SymbolStatus.digit, 0); - states[10].Add(SymbolStatus.underscore, 11); + states[10].Add(SymbolStatus.underscore, 7); states[10].Add(SymbolStatus.eof, 0); states[10].Add(SymbolStatus.newline, 0); - states[10].Add(SymbolStatus.space, 0); - states[10].Add(SymbolStatus.anotherSymbol, 0); + states[10].Add(SymbolStatus.space, 5); + states[10].Add(SymbolStatus.anotherSymbol, 6); - // TagSubOpen - states[11].Add(SymbolStatus.text, 12); + // TagClose + states[11].Add(SymbolStatus.text, 0); states[11].Add(SymbolStatus.digit, 0); - states[11].Add(SymbolStatus.underscore, 22); + states[11].Add(SymbolStatus.underscore, 0); states[11].Add(SymbolStatus.eof, 0); states[11].Add(SymbolStatus.newline, 0); - states[11].Add(SymbolStatus.space, 13); - states[11].Add(SymbolStatus.anotherSymbol, 12); + states[11].Add(SymbolStatus.space, 0); + states[11].Add(SymbolStatus.anotherSymbol, 0); - states[12].Add(SymbolStatus.text, 12); + // Maybe Italic in Bold + states[12].Add(SymbolStatus.text, 4); states[12].Add(SymbolStatus.digit, 0); - states[12].Add(SymbolStatus.underscore, 15); + states[12].Add(SymbolStatus.underscore, 12); states[12].Add(SymbolStatus.eof, 0); states[12].Add(SymbolStatus.newline, 0); - states[12].Add(SymbolStatus.space, 13); - states[12].Add(SymbolStatus.anotherSymbol, 12); - - states[13].Add(SymbolStatus.text, 14); - states[13].Add(SymbolStatus.digit, 0); - states[13].Add(SymbolStatus.underscore, 9); - states[13].Add(SymbolStatus.eof, 0); - states[13].Add(SymbolStatus.newline, 0); - states[13].Add(SymbolStatus.space, 13); - states[13].Add(SymbolStatus.anotherSymbol, 14); - - states[14].Add(SymbolStatus.text, 14); - states[14].Add(SymbolStatus.digit, 0); - states[14].Add(SymbolStatus.underscore, 15); - states[14].Add(SymbolStatus.eof, 0); - states[14].Add(SymbolStatus.newline, 0); - states[14].Add(SymbolStatus.space, 13); - states[14].Add(SymbolStatus.anotherSymbol, 14); - - states[15].Add(SymbolStatus.text, 0); - states[15].Add(SymbolStatus.digit, 0); - states[15].Add(SymbolStatus.underscore, 16); - states[15].Add(SymbolStatus.eof, 0); - states[15].Add(SymbolStatus.newline, 0); - states[15].Add(SymbolStatus.space, 0); - states[15].Add(SymbolStatus.anotherSymbol, 0); - - // TagSubClose - states[16].Add(SymbolStatus.text, 9); - states[16].Add(SymbolStatus.digit, 0); - states[16].Add(SymbolStatus.underscore, 16); - states[16].Add(SymbolStatus.eof, 21); - states[16].Add(SymbolStatus.newline, 21); - states[16].Add(SymbolStatus.space, 9); - states[16].Add(SymbolStatus.anotherSymbol, 9); - - states[17].Add(SymbolStatus.text, 17); - states[17].Add(SymbolStatus.digit, 0); - states[17].Add(SymbolStatus.underscore, 20); - states[17].Add(SymbolStatus.eof, 0); - states[17].Add(SymbolStatus.newline, 0); - states[17].Add(SymbolStatus.space, 18); - states[17].Add(SymbolStatus.anotherSymbol, 17); - - states[18].Add(SymbolStatus.text, 19); - states[18].Add(SymbolStatus.digit, 0); - states[18].Add(SymbolStatus.underscore, 20); - states[18].Add(SymbolStatus.eof, 0); - states[18].Add(SymbolStatus.newline, 0); - states[18].Add(SymbolStatus.space, 18); - states[18].Add(SymbolStatus.anotherSymbol, 19); - - states[19].Add(SymbolStatus.text, 19); - states[19].Add(SymbolStatus.digit, 0); - states[19].Add(SymbolStatus.underscore, 20); - states[19].Add(SymbolStatus.eof, 0); - states[19].Add(SymbolStatus.newline, 0); - states[19].Add(SymbolStatus.space, 18); - states[19].Add(SymbolStatus.anotherSymbol, 19); - - states[20].Add(SymbolStatus.text, 3); - states[20].Add(SymbolStatus.digit, 0); - states[20].Add(SymbolStatus.underscore, 24); - states[20].Add(SymbolStatus.eof, 0); - states[20].Add(SymbolStatus.newline, 0); - states[20].Add(SymbolStatus.space, 4); - states[20].Add(SymbolStatus.anotherSymbol, 3); - - // TagClose - states[21].Add(SymbolStatus.text, 0); - states[21].Add(SymbolStatus.digit, 0); - states[21].Add(SymbolStatus.underscore, 1); - states[21].Add(SymbolStatus.eof, 0); - states[21].Add(SymbolStatus.newline, 0); - states[21].Add(SymbolStatus.space, 0); - states[21].Add(SymbolStatus.anotherSymbol, 0); - - states[22].Add(SymbolStatus.text, 9); - states[22].Add(SymbolStatus.digit, 0); - states[22].Add(SymbolStatus.underscore, 9); - states[22].Add(SymbolStatus.eof, 0); - states[22].Add(SymbolStatus.newline, 0); - states[22].Add(SymbolStatus.space, 9); - states[22].Add(SymbolStatus.anotherSymbol, 9); - - states[23].Add(SymbolStatus.text, 11); - states[23].Add(SymbolStatus.digit, 0); - states[23].Add(SymbolStatus.underscore, 11); - states[23].Add(SymbolStatus.eof, 0); - states[23].Add(SymbolStatus.newline, 0); - states[23].Add(SymbolStatus.space, 11); - states[23].Add(SymbolStatus.anotherSymbol, 11); - - states[24].Add(SymbolStatus.text, 26); - states[24].Add(SymbolStatus.digit, 0); - states[24].Add(SymbolStatus.underscore, 25); - states[24].Add(SymbolStatus.eof, 0); - states[24].Add(SymbolStatus.newline, 0); - states[24].Add(SymbolStatus.space, 27); - states[24].Add(SymbolStatus.anotherSymbol, 26); - - states[25].Add(SymbolStatus.text, 17); - states[25].Add(SymbolStatus.digit, 0); - states[25].Add(SymbolStatus.underscore, 17); - states[25].Add(SymbolStatus.eof, 0); - states[25].Add(SymbolStatus.newline, 0); - states[25].Add(SymbolStatus.space, 17); - states[25].Add(SymbolStatus.anotherSymbol, 17); - - states[26].Add(SymbolStatus.text, 26); - states[26].Add(SymbolStatus.digit, 0); - states[26].Add(SymbolStatus.underscore, 29); - states[26].Add(SymbolStatus.eof, 0); - states[26].Add(SymbolStatus.newline, 0); - states[26].Add(SymbolStatus.space, 27); - states[26].Add(SymbolStatus.anotherSymbol, 26); - - states[27].Add(SymbolStatus.text, 28); - states[27].Add(SymbolStatus.digit, 0); - states[27].Add(SymbolStatus.underscore, 24); - states[27].Add(SymbolStatus.eof, 0); - states[27].Add(SymbolStatus.newline, 0); - states[27].Add(SymbolStatus.space, 27); - states[27].Add(SymbolStatus.anotherSymbol, 28); - - states[28].Add(SymbolStatus.text, 28); - states[28].Add(SymbolStatus.digit, 0); - states[28].Add(SymbolStatus.underscore, 29); - states[28].Add(SymbolStatus.eof, 0); - states[28].Add(SymbolStatus.newline, 0); - states[28].Add(SymbolStatus.space, 27); - states[28].Add(SymbolStatus.anotherSymbol, 28); - - states[29].Add(SymbolStatus.text, 0); - states[29].Add(SymbolStatus.digit, 0); - states[29].Add(SymbolStatus.underscore, 30); - states[29].Add(SymbolStatus.eof, 0); - states[29].Add(SymbolStatus.newline, 0); - states[29].Add(SymbolStatus.space, 0); - states[29].Add(SymbolStatus.anotherSymbol, 0); - - states[30].Add(SymbolStatus.text, 17); - states[30].Add(SymbolStatus.digit, 0); - states[30].Add(SymbolStatus.underscore, 31); - states[30].Add(SymbolStatus.eof, 0); - states[30].Add(SymbolStatus.newline, 0); - states[30].Add(SymbolStatus.space, 18); - states[30].Add(SymbolStatus.anotherSymbol, 17); - - states[31].Add(SymbolStatus.text, 26); - states[31].Add(SymbolStatus.digit, 0); - states[31].Add(SymbolStatus.underscore, 31); - states[31].Add(SymbolStatus.eof, 0); - states[31].Add(SymbolStatus.newline, 0); - states[31].Add(SymbolStatus.space, 27); - states[31].Add(SymbolStatus.anotherSymbol, 26); + states[12].Add(SymbolStatus.space, 5); + states[12].Add(SymbolStatus.anotherSymbol, 4); return states; } diff --git a/cs/Markdown/Tags/EscapeTag.cs b/cs/Markdown/Tags/EscapeTag.cs index 81c48511a..a15496c56 100644 --- a/cs/Markdown/Tags/EscapeTag.cs +++ b/cs/Markdown/Tags/EscapeTag.cs @@ -15,7 +15,7 @@ public class EscapeTag : ITag public int[] SubOutputStateNumbers { get; } = Array.Empty(); public int OutputStateNumber { get; } = 2; - private static Dictionary> states = new(); + //private static Dictionary> states = new(); public Dictionary> States { get; } = InitialzeStates(); @@ -26,6 +26,8 @@ public class EscapeTag : ITag public static Dictionary> InitialzeStates() { + var states = new Dictionary>(); + states.Add(0, new Dictionary()); states.Add(1, new Dictionary()); states.Add(2, new Dictionary()); diff --git a/cs/Markdown/Tags/H1Tag.cs b/cs/Markdown/Tags/H1Tag.cs index e88f6a902..597a8fbe5 100644 --- a/cs/Markdown/Tags/H1Tag.cs +++ b/cs/Markdown/Tags/H1Tag.cs @@ -15,7 +15,7 @@ public class H1Tag : ITag public int[] SubOutputStateNumbers { get; } = Array.Empty(); public int OutputStateNumber { get; } = 5; - private static Dictionary> states = new(); + //private static Dictionary> states = new(); public Dictionary> States { get; } = InitialzeStates(); @@ -27,6 +27,8 @@ public class H1Tag : ITag public static Dictionary> InitialzeStates() { + var states = new Dictionary>(); + states.Add(0, new Dictionary()); states.Add(1, new Dictionary()); states.Add(2, new Dictionary()); diff --git a/cs/Markdown/Tags/ItalicTextTag.cs b/cs/Markdown/Tags/ItalicTextTag.cs index 4f72292fd..0ce9f6086 100644 --- a/cs/Markdown/Tags/ItalicTextTag.cs +++ b/cs/Markdown/Tags/ItalicTextTag.cs @@ -12,72 +12,186 @@ public class ItalicTextTag : ITag public int InputStateNumber { get; } = 1; public int[] SubOutputStateNumbers { get; } = Array.Empty(); - public int OutputStateNumber { get; } = 4; + public int OutputStateNumber { get; } = 12; //private bool state; //private Stack currentStack; //private int startPosition; //public int TokenPosition { get; set; } - private static Dictionary> states = new(); + //private static Dictionary> states = new(); public Dictionary> States { get; } = InitialzeStates(); public SymbolStatus[] UsedSymbols { get; } = { SymbolStatus.text, SymbolStatus.digit, SymbolStatus.underscore - , SymbolStatus.eof, SymbolStatus.newline, SymbolStatus.space + , SymbolStatus.eof, SymbolStatus.newline, SymbolStatus.space, + SymbolStatus.anotherSymbol }; public static Dictionary> InitialzeStates() { + var states = new Dictionary>(); + states.Add(0, new Dictionary()); states.Add(1, new Dictionary()); states.Add(2, new Dictionary()); states.Add(3, new Dictionary()); states.Add(4, new Dictionary()); - - states[0].Add(SymbolStatus.text, 0); + states.Add(5, new Dictionary()); + states.Add(6, new Dictionary()); + states.Add(7, new Dictionary()); + states.Add(8, new Dictionary()); + states.Add(9, new Dictionary()); + states.Add(10, new Dictionary()); + states.Add(11, new Dictionary()); + states.Add(12, new Dictionary()); + states.Add(13, new Dictionary()); + states.Add(14, new Dictionary()); + states.Add(15, new Dictionary()); + states.Add(16, new Dictionary()); + + states[0].Add(SymbolStatus.text, 13); // 0 states[0].Add(SymbolStatus.digit, 0); states[0].Add(SymbolStatus.underscore, 1); - states[0].Add(SymbolStatus.backslash, 0); states[0].Add(SymbolStatus.eof, 0); states[0].Add(SymbolStatus.newline, 0); states[0].Add(SymbolStatus.space, 0); + states[0].Add(SymbolStatus.anotherSymbol, 13); // 0 - // Начало + // Tag Open states[1].Add(SymbolStatus.text, 2); states[1].Add(SymbolStatus.digit, 0); - states[1].Add(SymbolStatus.underscore, 0); - states[1].Add(SymbolStatus.backslash, 2); + states[1].Add(SymbolStatus.underscore, 9); states[1].Add(SymbolStatus.eof, 0); states[1].Add(SymbolStatus.newline, 0); states[1].Add(SymbolStatus.space, 0); + states[1].Add(SymbolStatus.anotherSymbol, 2); states[2].Add(SymbolStatus.text, 2); states[2].Add(SymbolStatus.digit, 0); - states[2].Add(SymbolStatus.underscore, 3); - states[2].Add(SymbolStatus.backslash, 2); + states[2].Add(SymbolStatus.underscore, 5); states[2].Add(SymbolStatus.eof, 0); states[2].Add(SymbolStatus.newline, 0); - states[2].Add(SymbolStatus.space, 0); + states[2].Add(SymbolStatus.space, 3); + states[2].Add(SymbolStatus.anotherSymbol, 2); states[3].Add(SymbolStatus.text, 4); states[3].Add(SymbolStatus.digit, 0); - states[3].Add(SymbolStatus.underscore, 0); - states[3].Add(SymbolStatus.backslash, 5); - states[3].Add(SymbolStatus.eof, 4); - states[3].Add(SymbolStatus.newline, 4); - states[3].Add(SymbolStatus.space, 4); - - // 4 состояние выхода - states[4].Add(SymbolStatus.text, 0); + states[3].Add(SymbolStatus.underscore, 8); + states[3].Add(SymbolStatus.eof, 0); + states[3].Add(SymbolStatus.newline, 0); + states[3].Add(SymbolStatus.space, 3); + states[3].Add(SymbolStatus.anotherSymbol, 4); + + states[4].Add(SymbolStatus.text, 4); states[4].Add(SymbolStatus.digit, 0); - states[4].Add(SymbolStatus.underscore, 0); - states[4].Add(SymbolStatus.backslash, 0); + states[4].Add(SymbolStatus.underscore, 5); states[4].Add(SymbolStatus.eof, 0); states[4].Add(SymbolStatus.newline, 0); - states[4].Add(SymbolStatus.space, 0); + states[4].Add(SymbolStatus.space, 3); + states[4].Add(SymbolStatus.anotherSymbol, 4); + + states[5].Add(SymbolStatus.text, 12); + states[5].Add(SymbolStatus.digit, 12); + states[5].Add(SymbolStatus.underscore, 6); + states[5].Add(SymbolStatus.eof, 12); + states[5].Add(SymbolStatus.newline, 12); + states[5].Add(SymbolStatus.space, 12); + states[5].Add(SymbolStatus.anotherSymbol, 12); + + states[6].Add(SymbolStatus.text, 7); + states[6].Add(SymbolStatus.digit, 0); + states[6].Add(SymbolStatus.underscore, 8); + states[6].Add(SymbolStatus.eof, 0); + states[6].Add(SymbolStatus.newline, 0); + states[6].Add(SymbolStatus.space, 7); + states[6].Add(SymbolStatus.anotherSymbol, 7); + + // Maybe Bold in Italic + states[7].Add(SymbolStatus.text, 2); // 0 + states[7].Add(SymbolStatus.digit, 0); + states[7].Add(SymbolStatus.underscore, 5); // 1 + states[7].Add(SymbolStatus.eof, 0); + states[7].Add(SymbolStatus.newline, 0); + states[7].Add(SymbolStatus.space, 3); // 0 + states[7].Add(SymbolStatus.anotherSymbol, 2); // 0 + + states[8].Add(SymbolStatus.text, 2); + states[8].Add(SymbolStatus.digit, 0); + states[8].Add(SymbolStatus.underscore, 8); + states[8].Add(SymbolStatus.eof, 0); + states[8].Add(SymbolStatus.newline, 0); + states[8].Add(SymbolStatus.space, 3); + states[8].Add(SymbolStatus.anotherSymbol, 2); + + states[9].Add(SymbolStatus.text, 10); + states[9].Add(SymbolStatus.digit, 0); + states[9].Add(SymbolStatus.underscore, 11); + states[9].Add(SymbolStatus.eof, 0); + states[9].Add(SymbolStatus.newline, 0); + states[9].Add(SymbolStatus.space, 0); + states[9].Add(SymbolStatus.anotherSymbol, 10); + + // Maybe Italic in Bold + states[10].Add(SymbolStatus.text, 0); + states[10].Add(SymbolStatus.digit, 0); + states[10].Add(SymbolStatus.underscore, 0); + states[10].Add(SymbolStatus.eof, 0); + states[10].Add(SymbolStatus.newline, 0); + states[10].Add(SymbolStatus.space, 0); + states[10].Add(SymbolStatus.anotherSymbol, 0); + + states[11].Add(SymbolStatus.text, 0); + states[11].Add(SymbolStatus.digit, 0); + states[11].Add(SymbolStatus.underscore, 11); + states[11].Add(SymbolStatus.eof, 0); + states[11].Add(SymbolStatus.newline, 0); + states[11].Add(SymbolStatus.space, 0); + states[11].Add(SymbolStatus.anotherSymbol, 11); + + // Tag Close + states[12].Add(SymbolStatus.text, 0); + states[12].Add(SymbolStatus.digit, 0); + states[12].Add(SymbolStatus.underscore, 0); + states[12].Add(SymbolStatus.eof, 0); + states[12].Add(SymbolStatus.newline, 0); + states[12].Add(SymbolStatus.space, 0); + states[12].Add(SymbolStatus.anotherSymbol, 0); + + states[13].Add(SymbolStatus.text, 13); + states[13].Add(SymbolStatus.digit, 0); + states[13].Add(SymbolStatus.underscore, 14); + states[13].Add(SymbolStatus.eof, 0); + states[13].Add(SymbolStatus.newline, 0); + states[13].Add(SymbolStatus.space, 0); + states[13].Add(SymbolStatus.anotherSymbol, 13); + + // Tag Open + states[14].Add(SymbolStatus.text, 15); + states[14].Add(SymbolStatus.digit, 0); + states[14].Add(SymbolStatus.underscore, 0); + states[14].Add(SymbolStatus.eof, 0); + states[14].Add(SymbolStatus.newline, 0); + states[14].Add(SymbolStatus.space, 0); + states[14].Add(SymbolStatus.anotherSymbol, 15); + + states[15].Add(SymbolStatus.text, 15); + states[15].Add(SymbolStatus.digit, 0); + states[15].Add(SymbolStatus.underscore, 16); + states[15].Add(SymbolStatus.eof, 0); + states[15].Add(SymbolStatus.newline, 0); + states[15].Add(SymbolStatus.space, 0); + states[15].Add(SymbolStatus.anotherSymbol, 15); + + states[16].Add(SymbolStatus.text, 12); + states[16].Add(SymbolStatus.digit, 12); + states[16].Add(SymbolStatus.underscore, 14); + states[16].Add(SymbolStatus.eof, 12); + states[16].Add(SymbolStatus.newline, 12); + states[16].Add(SymbolStatus.space, 12); + states[16].Add(SymbolStatus.anotherSymbol, 12); return states; } diff --git a/cs/MarkdownTests/MarkdownTest.cs b/cs/MarkdownTests/MarkdownTest.cs index bcde4ae83..49a874ccd 100644 --- a/cs/MarkdownTests/MarkdownTest.cs +++ b/cs/MarkdownTests/MarkdownTest.cs @@ -1,16 +1,58 @@ -namespace MarkdownTests +using System.Collections; +using FluentAssertions; +using Markdown; + +namespace MarkdownTests; + +[TestFixture] +public class MarkdownTest { - public class Tests + [Test] + public void MarkdownRender_ReturnTextWhenNoTags() { - [SetUp] - public void Setup() - { - } + var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis feugiat placerat sagittis."; + + var generatedText = Md.Render(text); + + generatedText.Should().Be(text); + } - [Test] - public void Test1() + [TestCaseSource(nameof(ItalicAndBoldTestCases))] + public void MarkdownRender_CorrectlyWork_WithItalicAndBoldTags(string text, string expected) + { + var generatedText = Md.Render(text); + + generatedText.Should().Be(expected); + } + + public static IEnumerable ItalicAndBoldTestCases + { + get { - Assert.Pass(); + yield return new TestCaseData("__openBold word _openItalic word closeItalic word_ closeBold__", + "openBold word openItalic word closeItalic word closeBold") + .SetName("Italic tags in Bold are allowed"); + yield return new TestCaseData("_a", "_a").SetName("italic is not closed"); + yield return new TestCaseData("_a_", "a").SetName("italic closed within the word"); + yield return new TestCaseData("__a__", "a").SetName("italic closed within the word"); + yield return new TestCaseData("__BoldItalic_Italic_ItalicBold__", + "BoldItalicItalicItalicBold") + .SetName("bold and italic closed within the word"); + yield return new TestCaseData("a_a a_a", "a_a a_a").SetName("italics in different words in the middle"); + yield return new TestCaseData("__asd_das__", "asd_das").SetName("not closed italics in words"); + yield return new TestCaseData("____", "____").SetName("underscore without letters"); + yield return new TestCaseData("_bold__", "_bold__").SetName("not paired tags"); + yield return new TestCaseData("__intersection _bold__ and italic_", "__intersection _bold__ and italic_") + .SetName("intersection of bold and italic"); + yield return new TestCaseData("_ab__cd_", "ab__cd").SetName("bold inside italics within a word"); + yield return new TestCaseData("__a _b_ _c_ d__", "a b c d") + .SetName("multiple closing tags inside the bold"); + yield return new TestCaseData("_a __c__ d_", "a __c__ d").SetName("bold inside italics"); + yield return new TestCaseData("_ab_ad", "abad").SetName("italics opens at the beginning closes in the middle"); + yield return new TestCaseData("a_bad_", "abad").SetName("italics opens in the middle closes at the end"); + yield return new TestCaseData("__bold _ab_ad bold__", "bold abad bold") + .SetName("italic opens at the beginning closes in the middle inside bold"); + } } } \ No newline at end of file diff --git a/cs/MarkdownTests/MarkdownTests.csproj b/cs/MarkdownTests/MarkdownTests.csproj index ad8b21329..9e6c35fd8 100644 --- a/cs/MarkdownTests/MarkdownTests.csproj +++ b/cs/MarkdownTests/MarkdownTests.csproj @@ -11,6 +11,7 @@ + From 8dc7f24323b37a7de7fa261456a2b7e964cdfe4e Mon Sep 17 00:00:00 2001 From: Leonid Date: Mon, 2 Dec 2024 00:55:34 +0500 Subject: [PATCH 10/15] Add tests --- cs/Markdown/Md.cs | 7 ++ cs/Markdown/Program.cs | 9 ++- cs/Markdown/Rules/BoldRule.cs | 10 ++- cs/Markdown/Rules/EscapeRule.cs | 4 +- cs/Markdown/Rules/H1Rule.cs | 11 ++- cs/Markdown/Rules/ItalicRule.cs | 1 + cs/Markdown/TagParser.cs | 96 +++++++++++++++++++-------- cs/MarkdownTests/MarkdownSpeedTest.cs | 46 +++++++++++++ cs/MarkdownTests/MarkdownTest.cs | 46 +++++++++++++ 9 files changed, 195 insertions(+), 35 deletions(-) create mode 100644 cs/MarkdownTests/MarkdownSpeedTest.cs diff --git a/cs/Markdown/Md.cs b/cs/Markdown/Md.cs index 5a1b1b516..3f89b28d2 100644 --- a/cs/Markdown/Md.cs +++ b/cs/Markdown/Md.cs @@ -28,6 +28,13 @@ private static string GenerateHtml(string text, List tokens) var sb = new StringBuilder(); foreach (var token in currentTokens) { + if (token.Position == 748) + { + var t = text[746..750]; + var te = text[748]; + Console.WriteLine(); + } + sb.Append(text[position..token.Position]); sb.Append(token.ConvertedText); position = token.Position + token.SourceText.Length > text.Length ? text.Length : token.Position + token.SourceText.Length; diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs index 6b18889f8..a8558dfc4 100644 --- a/cs/Markdown/Program.cs +++ b/cs/Markdown/Program.cs @@ -1,5 +1,8 @@ -using Markdown; +using System.Threading.Channels; +using Markdown; -Console.WriteLine(Md.Render("__a _b_ _c_ d__")); +//Console.WriteLine(Md.Render("\\\\_a_")); //__test \_ _markdown_ text__ another text -// _Markdown123_ \ No newline at end of file +// _Markdown123_ + +Console.WriteLine(Md.Render("_ \r\n _\r\n_\r\n_ E \r\n __ E_ ___\r\nE _\r\n\r\n\r\nE_ EEE \r\n _____ \r\nE____E E____ \r\n__\r\nE_EE__E\r\n______\r\n__ __E E _ \r\n\r\n__\r\n__\r\n ____\r\n _ EE__E_\r\n ___ ______ ___ E E_\r\n\r\n__\r\n \r\n \r\n__ __\r\nE E ___ __ EE_ __ \r\n__ E_ \r\nE E\r\n__ ___ \r\n E\r\n\r\n____\r\n___ \r\n\r\n__ \r\n E \r\n__ E __E __ \r\n____\r\n\r\n\r\n\r\n\r\nE \r\n\r\n __ _ _ \r\n _ \r\n E\r\n____ \r\n_ __E___ _\r\n __\r\n E E_ \r\n \r\nE_E__ _\r\n _\r\n \r\n \r\n_ E __E E \r\n _ E _________EE__E E__ E\r\n _ E _\r\n__\r\n___\r\nE _____\r\nE\r\n\r\nE_ ______ __ __E ___ E__ E _\r\n _ _E_ E__\r\n__ ______\r\n\r\n _ E __E \r\n\r\n\r\n__ __ _________ __ E__ E\r\n\r\n E \r\nE_\r\n\r\n EEE\r\n_ __\r\n\r\n__\r\n \r\n__ E__ E \r\nE_E_____ \r\nE____ _ _E \r\n__\r\nE EE__\r\n _ ___ E ___\r\n __ ____\r\n____ E \r\n\r\n E_ \r\n__\r\n__ \r\n _ __ \r\n___\r\n EE\r\n E________ E\r\n__\r\n_______\r\n E___E E E____E_EEE_\r\n __\r\nE E __ \r\n___\r\n__ ___ __ \r\nE ___ _E __ __ \r\n___E \r\n-----------------------------\r\nG _\r\n__ _\r\n _ G _\r\n G \r\n G _\r\n \r\n __\r\n\r\n \r\n \r\n\r\n\r\n ____ ___ _G _G ___ _ __\r\n \r\n G___ _GG G G_ \r\n_\r\n\r\nG_\r\nGG \r\n\r\n__G\r\n___ G\r\n\r\n__ __ \r\nG GG GG\r\n__\r\n__ ___\r\n_\r\n_____G \r\n \r\n\r\n___G\r\n\r\n ___ G\r\nG G\r\n___ _G G_ G G G ____\r\n_ \r\n\r\n_ _____ G\r\n \r\n\r\n G\r\n \r\n __ \r\n__\r\nG____\r\n__ _\r\nG __ _ G _____ _ \r\nG__\r\n_\r\n \r\n____G\r\n __ _ __\r\n_ \r\n _ _ \r\n\r\n\r\n _\r\n GG \r\n G\r\n_ \r\n_ ________GG \r\nG__G__G__ \r\nGG __ __\r\nG____ \r\nG__G_ G \r\n___\r\n _ __\r\nG__\r\n _\r\n_ G__\r\nG__G \r\n G G\r\n G___\r\n__ \r\n \r\n _ ______ __G _\r\nG\r\nG_GG____\r\n\r\n __ __G G__\r\nG__\r\n _G\r\n\r\n __ __\r\n__G_G\r\n __G\r\n\r\nG____G\r\n G__ __G ___G ____G GG \r\n \r\n G__ \r\n G\r\n\r\n\r\n__G __\r\n\r\nG GG__GGG\r\n__G GG\r\n___ G_ G____\r\nG___G\r\n \r\n \r\n __ ___ ____ GG\r\n GG_ _\r\n\r\n G G GG_____G\r\nG____ \r\n_____\r\n\r\n G _G ___\r\nG_\r\n__ G__G \r\n __ \r\n ___ \r\n \r\nG __\r\n \r\n\r\n__ G____\r\n ___ _ __ __G____ __ __\r\n G\r\n GG \r\n _\r\nGG G _ G ______GG___\r\n__\r\n\r\nG GG _\r\n __ G \r\nG_ G G_ G__G_ G G\r\n \r\n__G__\r\nG_G G \r\n ___ __ \r\n\r\n \r\n\r\nG __ G__G\r\n \r\n G\r\n ________ _\r\n_______\r\n _ _ _______G__ __\r\n __G\r\n G__ \r\n ___\r\nG\r\n\r\n\r\nG__ ___G___ G\r\n __ \r\n __G ____G\r\n __ __ ____ \r\n____ _\r\nGG\r\n\r\n\r\n\r\n ____ __\r\n _G\r\n \r\nG___ _G\r\n_ __ _ G__ __GG\r\n _\r\nG____ GG\r\n_\r\n \r\n_\r\nG _ \r\n ____G G \r\n G G___ \r\n_\r\n__ \r\n__G__\r\n__ ___ \r\n__ G__ G ___\r\n GG __\r\n__G__ \r\n\r\n_ __ GG__GG\r\n_______ G\r\n _\r\nG____ ___ _ G ____ G___ G__G __G__ G G__\r\n _______\r\nGG___ __\r\n \r\n G __GG\r\n\r\n_G __ __ \r\n \r\n __ \r\n_G \r\n_ _ ____ \r\n\r\n__ \r\n_G __ G\r\n\r\nG\r\n__\r\n \r\n_\r\n G ____ ___G\r\n\r\nG \r\n_G _\r\n __ _\r\n_\r\nG\r\n _G __ ___ \r\nG_\r\n____G\r\n___ _G \r\n__ G\r\n__G\r\n __ __ ____ G_________ \r\n __G\r\n__G_ G___\r\n\r\n __G \r\n_ G___ __ _____\r\n\r\n_______\r\n-----------------------------\r\n \r\n__\r\n____\r\nL_\r\n_____L_\r\nL L\r\n__ \r\n___L_ __ _L_\r\nLL___ L \r\n _ ____\r\n \r\n__\r\nL L\r\n L\r\n \r\nLL L__ \r\n __LL___ L _ \r\nL \r\n_\r\n\r\n _L\r\n__ \r\n___ ____ L__ \r\nL_L_ ________ _ __\r\n _\r\n __ __L \r\n_ __ L\r\n_ \r\n___L_L_\r\n_L__ _L\r\n__L___\r\n___L\r\n_L _ \r\n_\r\nL___\r\nL L _ _ _\r\n____ ___\r\n__L\r\n___ \r\nL\r\n __\r\n__L L ____L \r\n\r\n _ __ __L___L_L__ \r\n __ _\r\nL___ \r\nL LLL_L\r\n____L __L \r\n _ __\r\n___\r\n___L__ L__\r\nLL _\r\nL\r\nL__ \r\nL L __ \r\nL\r\n__ L__\r\n L__ __L__ __\r\nL ____\r\nL _ ___\r\n ____\r\n\r\n_ L_L L ___ L _ \r\n\r\n__ \r\nL_ L_L \r\n \r\n_ \r\nL______LL\r\n__ \r\n\r\nL __ L_ _______L\r\n\r\n L ___ ___L___ _\r\n L \r\n __L\r\nL\r\nL___ __L_\r\n__ _LL ______ __L\r\n__ __\r\nL ____ ____ \r\n_ _ L\r\n\r\n \r\n\r\n L_ _ _ _____ _\r\nL __\r\n___\r\n\r\n__ \r\n \r\n _ \r\n L_\r\n L L____ _ L\r\nL__ L \r\n L \r\n____L L_ \r\n_LL_____\r\n \r\n L__LLLLL LL____ _____ _\r\n _L \r\n __ ___ _ LL __ \r\n L___ L __ _____ L__ __\r\nL____ _\r\n\r\n__ L_ ___ L _\r\nL___\r\nL ___L____L__ _ LLL__ __ __ LLL____\r\n\r\n _ \r\n _L____L___ \r\n__ _ \r\n L__\r\n\r\n\r\n L__\r\n\r\n L___________\r\n_L\r\n\r\n LLL___ \r\n ___\r\n_\r\n\r\n\r\n ____\r\n __ _ __ \r\n\r\nL \r\n___L__ _ _LL_ _L _ __ \r\n\r\n ________L\r\n__L __L__ __L_____\r\n__ \r\n__ L \r\n__ __\r\n__LL \r\n____ \r\n\r\n_ ______\r\n __L\r\n_ _____ _ L\r\n_________\r\n\r\n_ L\r\n _ \r\n\r\n L \r\n _L _L___ __\r\nL__ _ LLL L __ \r\n__ ___L_\r\n\r\n _ __\r\nL_ _L \r\n L\r\nLL__\r\n __ __ \r\n_____\r\n _ \r\n \r\n_\r\n__ __\r\n _ ____ __\r\nL__ \r\nL L___L __ ____L __ __\r\n LL_ ____L\r\n \r\n\r\n __ _\r\n L__\r\n_ L\r\n__ L__\r\n\r\n L \r\nL \r\n\r\n______\r\n _ LL __\r\n__ ____\r\n_______ __L \r\n_\r\n_ ___ _ _L \r\n\r\n____ LL_ LL\r\n___ \r\n ____L L__ L\r\nL____\r\n\r\n \r\n\r\nL L L ___ L__ \r\n__ L_____\r\n__ __ _L __ __L_L_L \r\n L __ __L L__\r\nL L _LL _ \r\n\r\n L __ \r\n __ \r\n ___ \r\n_____ _____ _L LLL_ \r\n _ _\r\n_LL __\r\n \r\n_\r\n__L\r\n_ __ _\r\n_ ___ _____ _\r\n L L____ L_____L\r\n__L _ __\r\n___ ____\r\n L\r\n ____\r\n \r\n__ \r\n __ L __ ____ \r\nL_\r\n____\r\n__\r\n ___ _L \r\nL__\r\nL \r\n_L _ _ \r\n L ________\r\n _ _\r\nL__L_ __\r\n _L\r\n___\r\nL _ LL__LLL\r\n_ \r\n \r\n__ L____\r\nL __\r\n_\r\n LL_\r\n__ ___\r\n_____L_ L__\r\n__ L\r\n_L \r\n LL __\r\n \r\nLL L_ \r\n\r\n\r\n__\r\n ____ \r\n L____\r\nL_ __LL ___\r\n __ ______ __ _______\r\n L ____ L_ \r\n_ __ \r\nL\r\n__LL\r\n L\r\n __ \r\n\r\nL__L_ L __\r\nLL___ \r\nL\r\n ____L__ L\r\n __L_\r\n_ ___ L_ L\r\n L_\r\n \r\n L____ \r\nL\r\n\r\n\r\n __L__L\r\n__ \r\n \r\n\r\n_____\r\n\r\nL _\r\n_L \r\nL_ \r\n L _ __\r\n_______LL___L___\r\n L ___ _ __L L\r\nL__ __\r\nL \r\n_ \r\nL__\r\n__L\r\n _L\r\nL\r\nLL__\r\n L\r\n\r\n_ __LL L__LL_ __\r\n __LL___\r\nL \r\nL\r\nL\r\n__ L \r\n \r\n__ __L __ __ L__\r\n LL \r\n __ _ ______ __\r\nL__LL_ __L__L_L_\r\n ______ L \r\n_\r\n\r\n__L______ __L_\r\nLL\r\n L \r\n\r\n __ \r\n \r\n \r\nL__ \r\n\r\n\r\n L _L__ \r\n_____L__ L__ \r\nLL ___ \r\n\r\n _\r\n \r\n___\r\n__ LL\r\n\r\n L \r\n__L__L_L__ _ _\r\n__\r\n\r\n_ L_ ______ \r\nL __ _____ _________L \r\n__ _ L___L__ __ _L__ \r\n\r\n __\r\nL L L \r\n__L __L LL_______\r\nL \r\n __ L ____ _____ _ \r\n __ \r\n __ __ L L ____ _LL\r\nLL _ __ _LL _ __\r\n\r\nL____L__ _________________\r\n L__L__ __ \r\n__ __\r\n\r\n_ \r\n__\r\n_ LL __ L\r\n__ __ ___ __L_ \r\nL L\r\n_ L\r\n_\r\n __L __\r\n L\r\n_ \r\n_ ___\r\n\r\nLL_\r\n\r\n L_\r\n __ \r\n__ L_\r\n \r\nL_L\r\n L \r\n \r\n\r\nL \r\nL\r\n_____ \r\nL _\r\n L__\r\nLL__ __\r\n_ _ \r\n______\r\n_\r\n_ __ \r\n L__\r\n______\r\n L L_\r\nL _ _ _ __L_ \r\n______ L \r\n \r\nL \r\n_ L \r\n \r\n\r\n __ L LL__ ___ _ L__\r\nL __L__ \r\n___ LLL\r\n ___\r\n \r\n __ \r\n __ ___ __\r\n__\r\n _L__ __ L___LL \r\nL L__\r\nL_L____\r\n_L __\r\n__ _____ \r\n_____\r\n_______ L__\r\nL__ \r\n__L__\r\n__L _ LL \r\n_____ \r\n \r\n \r\nLL_L \r\nL\r\nL __LL__\r\n L ___L_\r\n\r\n \r\n L __\r\n___ \r\n_\r\n\r\n L ____ __ L___\r\n __ __\r\n\r\n __ \r\n")); diff --git a/cs/Markdown/Rules/BoldRule.cs b/cs/Markdown/Rules/BoldRule.cs index 432d125d8..f9398109f 100644 --- a/cs/Markdown/Rules/BoldRule.cs +++ b/cs/Markdown/Rules/BoldRule.cs @@ -36,7 +36,15 @@ public TagKind MoveByRule(char ch, int position) } else if (currentState == tag.OutputStateNumber) { - tokens.Add(new Token.Token(tag.MdView, tag.Tail, position - (tag.MdView.Length - 1))); + if (symbol == SymbolStatus.eof) + { + tokens.Add(new Token.Token(tag.MdView, tag.Tail, position - (tag.MdView.Length - 1))); + } + else + { + tokens.Add(new Token.Token(tag.MdView, tag.Tail, position - tag.MdView.Length)); + } + isTagClosed = true; } else if (currentState == 9) diff --git a/cs/Markdown/Rules/EscapeRule.cs b/cs/Markdown/Rules/EscapeRule.cs index 39f78ef33..3d6386228 100644 --- a/cs/Markdown/Rules/EscapeRule.cs +++ b/cs/Markdown/Rules/EscapeRule.cs @@ -22,10 +22,12 @@ public TagKind MoveByRule(char ch, int position) if (currentState == tag.InputStateNumber) { tokens.Add(new Token.Token(tag.MdView, tag.Head, position - (tag.MdView.Length - 1))); + return TagKind.Open; } else if (currentState == tag.OutputStateNumber) { - tokens.Add(new Token.Token(tag.MdView, ch.ToString(), position - (tag.MdView.Length - 1))); + tokens.Add(new Token.Token(ch.ToString(), ch.ToString(), position - (tag.MdView.Length - 1))); + currentState = 0; return TagKind.Close; } diff --git a/cs/Markdown/Rules/H1Rule.cs b/cs/Markdown/Rules/H1Rule.cs index ee88f3120..61e77a45c 100644 --- a/cs/Markdown/Rules/H1Rule.cs +++ b/cs/Markdown/Rules/H1Rule.cs @@ -25,7 +25,16 @@ public TagKind MoveByRule(char ch, int position) } else if (currentState == tag.OutputStateNumber) { - tokens.Add(new Token.Token(tag.MdView, tag.Tail, position - (tag.MdView.Length - 1))); + if (symbol == SymbolStatus.eof) + { + tokens.Add(new Token.Token("", tag.Tail, position + 1)); + } + else + { + tokens.Add(new Token.Token("", tag.Tail, position)); + } + + currentState = 0; return TagKind.Close; } diff --git a/cs/Markdown/Rules/ItalicRule.cs b/cs/Markdown/Rules/ItalicRule.cs index 8a87a03c4..96d84ed75 100644 --- a/cs/Markdown/Rules/ItalicRule.cs +++ b/cs/Markdown/Rules/ItalicRule.cs @@ -17,6 +17,7 @@ public class ItalicRule : IRule public TagKind MoveByRule(char ch, int position) { + var symbol = SymbolStatusParser.ParseSymbolStatus(ch); if (!tag.UsedSymbols.Contains(symbol)) diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index 1f4f2da11..5847ef4eb 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Data; using Markdown.Rule; using Markdown.Tags; using Markdown.Token; @@ -34,24 +35,71 @@ public class TagParser new BoldRule(), new ItalicRule(), //new EscapeRule(), - //new H1Rule() + new H1Rule() ]; + private IRule EscapeRule = new EscapeRule(); + + public bool TryGoNextSymbol(int textPointer, string text) + { + if (textPointer + 1 < text.Length) + { + return true; + } + return false; + } + public List GetTokens(string text) { var tokens = new List {}; var textPointer = 0; + var isPointerTeleported = false; + var isStateNotChanged = true; while (textPointer != text.Length) { - //foreach (var rule in Rules) - //{ - // var result = rule.Item1(text[textPointer], textPointer); - // if (result == TagKind.Close) - // { - // tokens.Add(new Token.Token(rule.Item2.MdView, rule.Item2.Head, rule.Item2.Positions[0])); - // tokens.Add(new Token.Token(rule.Item2.MdView, rule.Item2.Tail, rule.Item2.Positions[1])); - // } - //} + if (textPointer == 5824) + { + var p = text[5820..5830]; + //var pe = text[741..750]; + var z4 = text[5823]; + var z = text[5824]; + var z1 = text[5825]; + var z2 = text[5826]; + var z3 = text[5827]; + Console.WriteLine(); + } + + var res = EscapeRule.MoveByRule(text[textPointer], textPointer); + + if (res == TagKind.Open) + { + if (TryGoNextSymbol(textPointer, text)) + { + textPointer++; + res = EscapeRule.MoveByRule(text[textPointer], textPointer); + + if (res == TagKind.Close) + { + tokens.AddRange(EscapeRule.GetTokens()); + EscapeRule.ClearTokens(); + textPointer++; + isPointerTeleported = true; + isStateNotChanged = false; + } + + if (!TryGoNextSymbol(textPointer, text)) + { + break; + } + } + } + + if (isPointerTeleported && isStateNotChanged) + { + textPointer++; + isPointerTeleported = false; + } + foreach (var rule in Rules) { @@ -63,7 +111,15 @@ public List GetTokens(string text) } } - textPointer++; + if (!isPointerTeleported) + { + textPointer++; + } + else + { + isStateNotChanged = true; + } + } foreach (var rule in Rules) @@ -75,24 +131,6 @@ public List GetTokens(string text) } } - //foreach (var rule in Rules) - //{ - // var result = rule.Item1('\0', textPointer - 1); - // if (result == TagKind.Close) - // { - // tokens.Add(new Token.Token(rule.Item2.MdView, rule.Item2.Head, rule.Item2.Positions[0])); - // tokens.Add(new Token.Token(rule.Item2.MdView, rule.Item2.Tail, rule.Item2.Positions[1])); - // } - //} - return tokens; } - - //private void ResetAllRules() - //{ - // foreach (var rule in Rules) - // { - // rule.Item2.ResetRule(); - // } - //} } \ No newline at end of file diff --git a/cs/MarkdownTests/MarkdownSpeedTest.cs b/cs/MarkdownTests/MarkdownSpeedTest.cs new file mode 100644 index 000000000..60095d43e --- /dev/null +++ b/cs/MarkdownTests/MarkdownSpeedTest.cs @@ -0,0 +1,46 @@ +using FluentAssertions; +using Markdown; +using System.Diagnostics; +using System.Text; + +namespace MarkdownTests; + +[TestFixture] +public class MarkdownSpeedTest +{ + [Test] + public void Render_ShouldWorkFast() + { + var sw = new Stopwatch(); + var results = new List(); + + for (var length = 640; length <= 512 * 10; length *= 2) // 64000 512 * 1000 + { + var text = GetRandomString(length); + sw.Start(); + Console.WriteLine("-----------------------------"); + Console.WriteLine(text); + Md.Render(text); + sw.Stop(); + results.Add(sw.Elapsed); + sw.Reset(); + } + + for (var i = 1; i < results.Count; i++) + (results[i].Ticks / results[i - 1].Ticks).Should().BeLessThan(4); + } + + private string GetRandomString(int length) + { + Random rand = new Random(); + + var variants = new List + { + " ", "_", "__", " ", Environment.NewLine, ((char)rand.Next('A', 'Z' + 1)).ToString() + }; + var text = new StringBuilder(); + var rnd = new Random(); + for (var i = 0; i < length; i++) text.Append(variants[rnd.Next(variants.Count)]); + return text.ToString(); + } +} \ No newline at end of file diff --git a/cs/MarkdownTests/MarkdownTest.cs b/cs/MarkdownTests/MarkdownTest.cs index 49a874ccd..1a32be41e 100644 --- a/cs/MarkdownTests/MarkdownTest.cs +++ b/cs/MarkdownTests/MarkdownTest.cs @@ -55,4 +55,50 @@ public static IEnumerable ItalicAndBoldTestCases } } + + [TestCaseSource(nameof(ShieldingTestCases))] + public void MarkdownRender_CorrectlyWork_WithShielding(string text, string expected) + { + var generatedText = Md.Render(text); + + generatedText.Should().Be(expected); + } + + public static IEnumerable ShieldingTestCases + { + get + { + yield return new TestCaseData("\\_a_", "_a_").SetName("shielded opening tag"); + yield return new TestCaseData("\\\\_a_", "\\a").SetName("ignore shield backslash"); + yield return new TestCaseData("_\\a_", @"\a").SetName("does not escape the letter"); + yield return new TestCaseData("_a\\_", "_a_").SetName("shielded closing tag"); + yield return new TestCaseData("\\__a_", "_a").SetName("shields the bold turning into italic"); + yield return new TestCaseData("__test \\_ _markdown_ text__ another text", "test _ markdown text another text") + .SetName("shielding does not interfere with the work of other tags"); + } + } + + [TestCaseSource(nameof(HeaderTestCases))] + public void CorrectlyWork_WithHeader(string text, string expected) + { + var generatedText = Md.Render(text); + + generatedText.Should().Be(expected); + } + + public static IEnumerable HeaderTestCases + { + get + { + yield return new TestCaseData("# aba", "

aba

").SetName("correctly header"); + yield return new TestCaseData("#aba", "#aba").SetName("sharp with word"); + yield return new TestCaseData("# __a _b_ _c_ d__", + "

a b c d

") + .SetName("header works correctly with other tags"); + yield return new TestCaseData("ab #", "ab #").SetName("sharp in end"); + yield return new TestCaseData("ab # ab", "ab # ab").SetName("sharp in middle of string"); + yield return new TestCaseData("# abc\n# abc", "

abc

\n

abc

") + .SetName("correct work with multiple paragraphs"); + } + } } \ No newline at end of file From 71a7e221ea42a4b2d19ca2ad6126cb725a4266e5 Mon Sep 17 00:00:00 2001 From: Leonid Date: Mon, 2 Dec 2024 01:26:19 +0500 Subject: [PATCH 11/15] big refactor --- cs/Markdown/Program.cs | 4 +- cs/Markdown/Rules/BoldRule.cs | 3 +- cs/Markdown/Rules/ItalicRule.cs | 11 +-- cs/Markdown/Rules/Rule.cs | 66 ------------------ cs/Markdown/TagParser.cs | 98 +++++++++++++-------------- cs/Markdown/Tags/BoldTag.cs | 30 -------- cs/Markdown/Tags/EscapeTag.cs | 33 --------- cs/Markdown/Tags/H1Tag.cs | 28 -------- cs/Markdown/Tags/ITag.cs | 13 ---- cs/Markdown/Tags/ItalicTextTag.cs | 88 ++++++++---------------- cs/MarkdownTests/MarkdownSpeedTest.cs | 2 - cs/MarkdownTests/MarkdownTest.cs | 2 +- 12 files changed, 82 insertions(+), 296 deletions(-) delete mode 100644 cs/Markdown/Rules/Rule.cs diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs index a8558dfc4..ac589b707 100644 --- a/cs/Markdown/Program.cs +++ b/cs/Markdown/Program.cs @@ -1,8 +1,8 @@ using System.Threading.Channels; using Markdown; -//Console.WriteLine(Md.Render("\\\\_a_")); +Console.WriteLine(Md.Render("\\\\_a_")); //__test \_ _markdown_ text__ another text // _Markdown123_ -Console.WriteLine(Md.Render("_ \r\n _\r\n_\r\n_ E \r\n __ E_ ___\r\nE _\r\n\r\n\r\nE_ EEE \r\n _____ \r\nE____E E____ \r\n__\r\nE_EE__E\r\n______\r\n__ __E E _ \r\n\r\n__\r\n__\r\n ____\r\n _ EE__E_\r\n ___ ______ ___ E E_\r\n\r\n__\r\n \r\n \r\n__ __\r\nE E ___ __ EE_ __ \r\n__ E_ \r\nE E\r\n__ ___ \r\n E\r\n\r\n____\r\n___ \r\n\r\n__ \r\n E \r\n__ E __E __ \r\n____\r\n\r\n\r\n\r\n\r\nE \r\n\r\n __ _ _ \r\n _ \r\n E\r\n____ \r\n_ __E___ _\r\n __\r\n E E_ \r\n \r\nE_E__ _\r\n _\r\n \r\n \r\n_ E __E E \r\n _ E _________EE__E E__ E\r\n _ E _\r\n__\r\n___\r\nE _____\r\nE\r\n\r\nE_ ______ __ __E ___ E__ E _\r\n _ _E_ E__\r\n__ ______\r\n\r\n _ E __E \r\n\r\n\r\n__ __ _________ __ E__ E\r\n\r\n E \r\nE_\r\n\r\n EEE\r\n_ __\r\n\r\n__\r\n \r\n__ E__ E \r\nE_E_____ \r\nE____ _ _E \r\n__\r\nE EE__\r\n _ ___ E ___\r\n __ ____\r\n____ E \r\n\r\n E_ \r\n__\r\n__ \r\n _ __ \r\n___\r\n EE\r\n E________ E\r\n__\r\n_______\r\n E___E E E____E_EEE_\r\n __\r\nE E __ \r\n___\r\n__ ___ __ \r\nE ___ _E __ __ \r\n___E \r\n-----------------------------\r\nG _\r\n__ _\r\n _ G _\r\n G \r\n G _\r\n \r\n __\r\n\r\n \r\n \r\n\r\n\r\n ____ ___ _G _G ___ _ __\r\n \r\n G___ _GG G G_ \r\n_\r\n\r\nG_\r\nGG \r\n\r\n__G\r\n___ G\r\n\r\n__ __ \r\nG GG GG\r\n__\r\n__ ___\r\n_\r\n_____G \r\n \r\n\r\n___G\r\n\r\n ___ G\r\nG G\r\n___ _G G_ G G G ____\r\n_ \r\n\r\n_ _____ G\r\n \r\n\r\n G\r\n \r\n __ \r\n__\r\nG____\r\n__ _\r\nG __ _ G _____ _ \r\nG__\r\n_\r\n \r\n____G\r\n __ _ __\r\n_ \r\n _ _ \r\n\r\n\r\n _\r\n GG \r\n G\r\n_ \r\n_ ________GG \r\nG__G__G__ \r\nGG __ __\r\nG____ \r\nG__G_ G \r\n___\r\n _ __\r\nG__\r\n _\r\n_ G__\r\nG__G \r\n G G\r\n G___\r\n__ \r\n \r\n _ ______ __G _\r\nG\r\nG_GG____\r\n\r\n __ __G G__\r\nG__\r\n _G\r\n\r\n __ __\r\n__G_G\r\n __G\r\n\r\nG____G\r\n G__ __G ___G ____G GG \r\n \r\n G__ \r\n G\r\n\r\n\r\n__G __\r\n\r\nG GG__GGG\r\n__G GG\r\n___ G_ G____\r\nG___G\r\n \r\n \r\n __ ___ ____ GG\r\n GG_ _\r\n\r\n G G GG_____G\r\nG____ \r\n_____\r\n\r\n G _G ___\r\nG_\r\n__ G__G \r\n __ \r\n ___ \r\n \r\nG __\r\n \r\n\r\n__ G____\r\n ___ _ __ __G____ __ __\r\n G\r\n GG \r\n _\r\nGG G _ G ______GG___\r\n__\r\n\r\nG GG _\r\n __ G \r\nG_ G G_ G__G_ G G\r\n \r\n__G__\r\nG_G G \r\n ___ __ \r\n\r\n \r\n\r\nG __ G__G\r\n \r\n G\r\n ________ _\r\n_______\r\n _ _ _______G__ __\r\n __G\r\n G__ \r\n ___\r\nG\r\n\r\n\r\nG__ ___G___ G\r\n __ \r\n __G ____G\r\n __ __ ____ \r\n____ _\r\nGG\r\n\r\n\r\n\r\n ____ __\r\n _G\r\n \r\nG___ _G\r\n_ __ _ G__ __GG\r\n _\r\nG____ GG\r\n_\r\n \r\n_\r\nG _ \r\n ____G G \r\n G G___ \r\n_\r\n__ \r\n__G__\r\n__ ___ \r\n__ G__ G ___\r\n GG __\r\n__G__ \r\n\r\n_ __ GG__GG\r\n_______ G\r\n _\r\nG____ ___ _ G ____ G___ G__G __G__ G G__\r\n _______\r\nGG___ __\r\n \r\n G __GG\r\n\r\n_G __ __ \r\n \r\n __ \r\n_G \r\n_ _ ____ \r\n\r\n__ \r\n_G __ G\r\n\r\nG\r\n__\r\n \r\n_\r\n G ____ ___G\r\n\r\nG \r\n_G _\r\n __ _\r\n_\r\nG\r\n _G __ ___ \r\nG_\r\n____G\r\n___ _G \r\n__ G\r\n__G\r\n __ __ ____ G_________ \r\n __G\r\n__G_ G___\r\n\r\n __G \r\n_ G___ __ _____\r\n\r\n_______\r\n-----------------------------\r\n \r\n__\r\n____\r\nL_\r\n_____L_\r\nL L\r\n__ \r\n___L_ __ _L_\r\nLL___ L \r\n _ ____\r\n \r\n__\r\nL L\r\n L\r\n \r\nLL L__ \r\n __LL___ L _ \r\nL \r\n_\r\n\r\n _L\r\n__ \r\n___ ____ L__ \r\nL_L_ ________ _ __\r\n _\r\n __ __L \r\n_ __ L\r\n_ \r\n___L_L_\r\n_L__ _L\r\n__L___\r\n___L\r\n_L _ \r\n_\r\nL___\r\nL L _ _ _\r\n____ ___\r\n__L\r\n___ \r\nL\r\n __\r\n__L L ____L \r\n\r\n _ __ __L___L_L__ \r\n __ _\r\nL___ \r\nL LLL_L\r\n____L __L \r\n _ __\r\n___\r\n___L__ L__\r\nLL _\r\nL\r\nL__ \r\nL L __ \r\nL\r\n__ L__\r\n L__ __L__ __\r\nL ____\r\nL _ ___\r\n ____\r\n\r\n_ L_L L ___ L _ \r\n\r\n__ \r\nL_ L_L \r\n \r\n_ \r\nL______LL\r\n__ \r\n\r\nL __ L_ _______L\r\n\r\n L ___ ___L___ _\r\n L \r\n __L\r\nL\r\nL___ __L_\r\n__ _LL ______ __L\r\n__ __\r\nL ____ ____ \r\n_ _ L\r\n\r\n \r\n\r\n L_ _ _ _____ _\r\nL __\r\n___\r\n\r\n__ \r\n \r\n _ \r\n L_\r\n L L____ _ L\r\nL__ L \r\n L \r\n____L L_ \r\n_LL_____\r\n \r\n L__LLLLL LL____ _____ _\r\n _L \r\n __ ___ _ LL __ \r\n L___ L __ _____ L__ __\r\nL____ _\r\n\r\n__ L_ ___ L _\r\nL___\r\nL ___L____L__ _ LLL__ __ __ LLL____\r\n\r\n _ \r\n _L____L___ \r\n__ _ \r\n L__\r\n\r\n\r\n L__\r\n\r\n L___________\r\n_L\r\n\r\n LLL___ \r\n ___\r\n_\r\n\r\n\r\n ____\r\n __ _ __ \r\n\r\nL \r\n___L__ _ _LL_ _L _ __ \r\n\r\n ________L\r\n__L __L__ __L_____\r\n__ \r\n__ L \r\n__ __\r\n__LL \r\n____ \r\n\r\n_ ______\r\n __L\r\n_ _____ _ L\r\n_________\r\n\r\n_ L\r\n _ \r\n\r\n L \r\n _L _L___ __\r\nL__ _ LLL L __ \r\n__ ___L_\r\n\r\n _ __\r\nL_ _L \r\n L\r\nLL__\r\n __ __ \r\n_____\r\n _ \r\n \r\n_\r\n__ __\r\n _ ____ __\r\nL__ \r\nL L___L __ ____L __ __\r\n LL_ ____L\r\n \r\n\r\n __ _\r\n L__\r\n_ L\r\n__ L__\r\n\r\n L \r\nL \r\n\r\n______\r\n _ LL __\r\n__ ____\r\n_______ __L \r\n_\r\n_ ___ _ _L \r\n\r\n____ LL_ LL\r\n___ \r\n ____L L__ L\r\nL____\r\n\r\n \r\n\r\nL L L ___ L__ \r\n__ L_____\r\n__ __ _L __ __L_L_L \r\n L __ __L L__\r\nL L _LL _ \r\n\r\n L __ \r\n __ \r\n ___ \r\n_____ _____ _L LLL_ \r\n _ _\r\n_LL __\r\n \r\n_\r\n__L\r\n_ __ _\r\n_ ___ _____ _\r\n L L____ L_____L\r\n__L _ __\r\n___ ____\r\n L\r\n ____\r\n \r\n__ \r\n __ L __ ____ \r\nL_\r\n____\r\n__\r\n ___ _L \r\nL__\r\nL \r\n_L _ _ \r\n L ________\r\n _ _\r\nL__L_ __\r\n _L\r\n___\r\nL _ LL__LLL\r\n_ \r\n \r\n__ L____\r\nL __\r\n_\r\n LL_\r\n__ ___\r\n_____L_ L__\r\n__ L\r\n_L \r\n LL __\r\n \r\nLL L_ \r\n\r\n\r\n__\r\n ____ \r\n L____\r\nL_ __LL ___\r\n __ ______ __ _______\r\n L ____ L_ \r\n_ __ \r\nL\r\n__LL\r\n L\r\n __ \r\n\r\nL__L_ L __\r\nLL___ \r\nL\r\n ____L__ L\r\n __L_\r\n_ ___ L_ L\r\n L_\r\n \r\n L____ \r\nL\r\n\r\n\r\n __L__L\r\n__ \r\n \r\n\r\n_____\r\n\r\nL _\r\n_L \r\nL_ \r\n L _ __\r\n_______LL___L___\r\n L ___ _ __L L\r\nL__ __\r\nL \r\n_ \r\nL__\r\n__L\r\n _L\r\nL\r\nLL__\r\n L\r\n\r\n_ __LL L__LL_ __\r\n __LL___\r\nL \r\nL\r\nL\r\n__ L \r\n \r\n__ __L __ __ L__\r\n LL \r\n __ _ ______ __\r\nL__LL_ __L__L_L_\r\n ______ L \r\n_\r\n\r\n__L______ __L_\r\nLL\r\n L \r\n\r\n __ \r\n \r\n \r\nL__ \r\n\r\n\r\n L _L__ \r\n_____L__ L__ \r\nLL ___ \r\n\r\n _\r\n \r\n___\r\n__ LL\r\n\r\n L \r\n__L__L_L__ _ _\r\n__\r\n\r\n_ L_ ______ \r\nL __ _____ _________L \r\n__ _ L___L__ __ _L__ \r\n\r\n __\r\nL L L \r\n__L __L LL_______\r\nL \r\n __ L ____ _____ _ \r\n __ \r\n __ __ L L ____ _LL\r\nLL _ __ _LL _ __\r\n\r\nL____L__ _________________\r\n L__L__ __ \r\n__ __\r\n\r\n_ \r\n__\r\n_ LL __ L\r\n__ __ ___ __L_ \r\nL L\r\n_ L\r\n_\r\n __L __\r\n L\r\n_ \r\n_ ___\r\n\r\nLL_\r\n\r\n L_\r\n __ \r\n__ L_\r\n \r\nL_L\r\n L \r\n \r\n\r\nL \r\nL\r\n_____ \r\nL _\r\n L__\r\nLL__ __\r\n_ _ \r\n______\r\n_\r\n_ __ \r\n L__\r\n______\r\n L L_\r\nL _ _ _ __L_ \r\n______ L \r\n \r\nL \r\n_ L \r\n \r\n\r\n __ L LL__ ___ _ L__\r\nL __L__ \r\n___ LLL\r\n ___\r\n \r\n __ \r\n __ ___ __\r\n__\r\n _L__ __ L___LL \r\nL L__\r\nL_L____\r\n_L __\r\n__ _____ \r\n_____\r\n_______ L__\r\nL__ \r\n__L__\r\n__L _ LL \r\n_____ \r\n \r\n \r\nLL_L \r\nL\r\nL __LL__\r\n L ___L_\r\n\r\n \r\n L __\r\n___ \r\n_\r\n\r\n L ____ __ L___\r\n __ __\r\n\r\n __ \r\n")); +//Console.WriteLine(Md.Render("_ \r\n _\r\n_\r\n_ E \r\n __ E_ ___\r\nE _\r\n\r\n\r\nE_ EEE \r\n _____ \r\nE____E E____ \r\n__\r\nE_EE__E\r\n______\r\n__ __E E _ \r\n\r\n__\r\n__\r\n ____\r\n _ EE__E_\r\n ___ ______ ___ E E_\r\n\r\n__\r\n \r\n \r\n__ __\r\nE E ___ __ EE_ __ \r\n__ E_ \r\nE E\r\n__ ___ \r\n E\r\n\r\n____\r\n___ \r\n\r\n__ \r\n E \r\n__ E __E __ \r\n____\r\n\r\n\r\n\r\n\r\nE \r\n\r\n __ _ _ \r\n _ \r\n E\r\n____ \r\n_ __E___ _\r\n __\r\n E E_ \r\n \r\nE_E__ _\r\n _\r\n \r\n \r\n_ E __E E \r\n _ E _________EE__E E__ E\r\n _ E _\r\n__\r\n___\r\nE _____\r\nE\r\n\r\nE_ ______ __ __E ___ E__ E _\r\n _ _E_ E__\r\n__ ______\r\n\r\n _ E __E \r\n\r\n\r\n__ __ _________ __ E__ E\r\n\r\n E \r\nE_\r\n\r\n EEE\r\n_ __\r\n\r\n__\r\n \r\n__ E__ E \r\nE_E_____ \r\nE____ _ _E \r\n__\r\nE EE__\r\n _ ___ E ___\r\n __ ____\r\n____ E \r\n\r\n E_ \r\n__\r\n__ \r\n _ __ \r\n___\r\n EE\r\n E________ E\r\n__\r\n_______\r\n E___E E E____E_EEE_\r\n __\r\nE E __ \r\n___\r\n__ ___ __ \r\nE ___ _E __ __ \r\n___E \r\n-----------------------------\r\nG _\r\n__ _\r\n _ G _\r\n G \r\n G _\r\n \r\n __\r\n\r\n \r\n \r\n\r\n\r\n ____ ___ _G _G ___ _ __\r\n \r\n G___ _GG G G_ \r\n_\r\n\r\nG_\r\nGG \r\n\r\n__G\r\n___ G\r\n\r\n__ __ \r\nG GG GG\r\n__\r\n__ ___\r\n_\r\n_____G \r\n \r\n\r\n___G\r\n\r\n ___ G\r\nG G\r\n___ _G G_ G G G ____\r\n_ \r\n\r\n_ _____ G\r\n \r\n\r\n G\r\n \r\n __ \r\n__\r\nG____\r\n__ _\r\nG __ _ G _____ _ \r\nG__\r\n_\r\n \r\n____G\r\n __ _ __\r\n_ \r\n _ _ \r\n\r\n\r\n _\r\n GG \r\n G\r\n_ \r\n_ ________GG \r\nG__G__G__ \r\nGG __ __\r\nG____ \r\nG__G_ G \r\n___\r\n _ __\r\nG__\r\n _\r\n_ G__\r\nG__G \r\n G G\r\n G___\r\n__ \r\n \r\n _ ______ __G _\r\nG\r\nG_GG____\r\n\r\n __ __G G__\r\nG__\r\n _G\r\n\r\n __ __\r\n__G_G\r\n __G\r\n\r\nG____G\r\n G__ __G ___G ____G GG \r\n \r\n G__ \r\n G\r\n\r\n\r\n__G __\r\n\r\nG GG__GGG\r\n__G GG\r\n___ G_ G____\r\nG___G\r\n \r\n \r\n __ ___ ____ GG\r\n GG_ _\r\n\r\n G G GG_____G\r\nG____ \r\n_____\r\n\r\n G _G ___\r\nG_\r\n__ G__G \r\n __ \r\n ___ \r\n \r\nG __\r\n \r\n\r\n__ G____\r\n ___ _ __ __G____ __ __\r\n G\r\n GG \r\n _\r\nGG G _ G ______GG___\r\n__\r\n\r\nG GG _\r\n __ G \r\nG_ G G_ G__G_ G G\r\n \r\n__G__\r\nG_G G \r\n ___ __ \r\n\r\n \r\n\r\nG __ G__G\r\n \r\n G\r\n ________ _\r\n_______\r\n _ _ _______G__ __\r\n __G\r\n G__ \r\n ___\r\nG\r\n\r\n\r\nG__ ___G___ G\r\n __ \r\n __G ____G\r\n __ __ ____ \r\n____ _\r\nGG\r\n\r\n\r\n\r\n ____ __\r\n _G\r\n \r\nG___ _G\r\n_ __ _ G__ __GG\r\n _\r\nG____ GG\r\n_\r\n \r\n_\r\nG _ \r\n ____G G \r\n G G___ \r\n_\r\n__ \r\n__G__\r\n__ ___ \r\n__ G__ G ___\r\n GG __\r\n__G__ \r\n\r\n_ __ GG__GG\r\n_______ G\r\n _\r\nG____ ___ _ G ____ G___ G__G __G__ G G__\r\n _______\r\nGG___ __\r\n \r\n G __GG\r\n\r\n_G __ __ \r\n \r\n __ \r\n_G \r\n_ _ ____ \r\n\r\n__ \r\n_G __ G\r\n\r\nG\r\n__\r\n \r\n_\r\n G ____ ___G\r\n\r\nG \r\n_G _\r\n __ _\r\n_\r\nG\r\n _G __ ___ \r\nG_\r\n____G\r\n___ _G \r\n__ G\r\n__G\r\n __ __ ____ G_________ \r\n __G\r\n__G_ G___\r\n\r\n __G \r\n_ G___ __ _____\r\n\r\n_______\r\n-----------------------------\r\n \r\n__\r\n____\r\nL_\r\n_____L_\r\nL L\r\n__ \r\n___L_ __ _L_\r\nLL___ L \r\n _ ____\r\n \r\n__\r\nL L\r\n L\r\n \r\nLL L__ \r\n __LL___ L _ \r\nL \r\n_\r\n\r\n _L\r\n__ \r\n___ ____ L__ \r\nL_L_ ________ _ __\r\n _\r\n __ __L \r\n_ __ L\r\n_ \r\n___L_L_\r\n_L__ _L\r\n__L___\r\n___L\r\n_L _ \r\n_\r\nL___\r\nL L _ _ _\r\n____ ___\r\n__L\r\n___ \r\nL\r\n __\r\n__L L ____L \r\n\r\n _ __ __L___L_L__ \r\n __ _\r\nL___ \r\nL LLL_L\r\n____L __L \r\n _ __\r\n___\r\n___L__ L__\r\nLL _\r\nL\r\nL__ \r\nL L __ \r\nL\r\n__ L__\r\n L__ __L__ __\r\nL ____\r\nL _ ___\r\n ____\r\n\r\n_ L_L L ___ L _ \r\n\r\n__ \r\nL_ L_L \r\n \r\n_ \r\nL______LL\r\n__ \r\n\r\nL __ L_ _______L\r\n\r\n L ___ ___L___ _\r\n L \r\n __L\r\nL\r\nL___ __L_\r\n__ _LL ______ __L\r\n__ __\r\nL ____ ____ \r\n_ _ L\r\n\r\n \r\n\r\n L_ _ _ _____ _\r\nL __\r\n___\r\n\r\n__ \r\n \r\n _ \r\n L_\r\n L L____ _ L\r\nL__ L \r\n L \r\n____L L_ \r\n_LL_____\r\n \r\n L__LLLLL LL____ _____ _\r\n _L \r\n __ ___ _ LL __ \r\n L___ L __ _____ L__ __\r\nL____ _\r\n\r\n__ L_ ___ L _\r\nL___\r\nL ___L____L__ _ LLL__ __ __ LLL____\r\n\r\n _ \r\n _L____L___ \r\n__ _ \r\n L__\r\n\r\n\r\n L__\r\n\r\n L___________\r\n_L\r\n\r\n LLL___ \r\n ___\r\n_\r\n\r\n\r\n ____\r\n __ _ __ \r\n\r\nL \r\n___L__ _ _LL_ _L _ __ \r\n\r\n ________L\r\n__L __L__ __L_____\r\n__ \r\n__ L \r\n__ __\r\n__LL \r\n____ \r\n\r\n_ ______\r\n __L\r\n_ _____ _ L\r\n_________\r\n\r\n_ L\r\n _ \r\n\r\n L \r\n _L _L___ __\r\nL__ _ LLL L __ \r\n__ ___L_\r\n\r\n _ __\r\nL_ _L \r\n L\r\nLL__\r\n __ __ \r\n_____\r\n _ \r\n \r\n_\r\n__ __\r\n _ ____ __\r\nL__ \r\nL L___L __ ____L __ __\r\n LL_ ____L\r\n \r\n\r\n __ _\r\n L__\r\n_ L\r\n__ L__\r\n\r\n L \r\nL \r\n\r\n______\r\n _ LL __\r\n__ ____\r\n_______ __L \r\n_\r\n_ ___ _ _L \r\n\r\n____ LL_ LL\r\n___ \r\n ____L L__ L\r\nL____\r\n\r\n \r\n\r\nL L L ___ L__ \r\n__ L_____\r\n__ __ _L __ __L_L_L \r\n L __ __L L__\r\nL L _LL _ \r\n\r\n L __ \r\n __ \r\n ___ \r\n_____ _____ _L LLL_ \r\n _ _\r\n_LL __\r\n \r\n_\r\n__L\r\n_ __ _\r\n_ ___ _____ _\r\n L L____ L_____L\r\n__L _ __\r\n___ ____\r\n L\r\n ____\r\n \r\n__ \r\n __ L __ ____ \r\nL_\r\n____\r\n__\r\n ___ _L \r\nL__\r\nL \r\n_L _ _ \r\n L ________\r\n _ _\r\nL__L_ __\r\n _L\r\n___\r\nL _ LL__LLL\r\n_ \r\n \r\n__ L____\r\nL __\r\n_\r\n LL_\r\n__ ___\r\n_____L_ L__\r\n__ L\r\n_L \r\n LL __\r\n \r\nLL L_ \r\n\r\n\r\n__\r\n ____ \r\n L____\r\nL_ __LL ___\r\n __ ______ __ _______\r\n L ____ L_ \r\n_ __ \r\nL\r\n__LL\r\n L\r\n __ \r\n\r\nL__L_ L __\r\nLL___ \r\nL\r\n ____L__ L\r\n __L_\r\n_ ___ L_ L\r\n L_\r\n \r\n L____ \r\nL\r\n\r\n\r\n __L__L\r\n__ \r\n \r\n\r\n_____\r\n\r\nL _\r\n_L \r\nL_ \r\n L _ __\r\n_______LL___L___\r\n L ___ _ __L L\r\nL__ __\r\nL \r\n_ \r\nL__\r\n__L\r\n _L\r\nL\r\nLL__\r\n L\r\n\r\n_ __LL L__LL_ __\r\n __LL___\r\nL \r\nL\r\nL\r\n__ L \r\n \r\n__ __L __ __ L__\r\n LL \r\n __ _ ______ __\r\nL__LL_ __L__L_L_\r\n ______ L \r\n_\r\n\r\n__L______ __L_\r\nLL\r\n L \r\n\r\n __ \r\n \r\n \r\nL__ \r\n\r\n\r\n L _L__ \r\n_____L__ L__ \r\nLL ___ \r\n\r\n _\r\n \r\n___\r\n__ LL\r\n\r\n L \r\n__L__L_L__ _ _\r\n__\r\n\r\n_ L_ ______ \r\nL __ _____ _________L \r\n__ _ L___L__ __ _L__ \r\n\r\n __\r\nL L L \r\n__L __L LL_______\r\nL \r\n __ L ____ _____ _ \r\n __ \r\n __ __ L L ____ _LL\r\nLL _ __ _LL _ __\r\n\r\nL____L__ _________________\r\n L__L__ __ \r\n__ __\r\n\r\n_ \r\n__\r\n_ LL __ L\r\n__ __ ___ __L_ \r\nL L\r\n_ L\r\n_\r\n __L __\r\n L\r\n_ \r\n_ ___\r\n\r\nLL_\r\n\r\n L_\r\n __ \r\n__ L_\r\n \r\nL_L\r\n L \r\n \r\n\r\nL \r\nL\r\n_____ \r\nL _\r\n L__\r\nLL__ __\r\n_ _ \r\n______\r\n_\r\n_ __ \r\n L__\r\n______\r\n L L_\r\nL _ _ _ __L_ \r\n______ L \r\n \r\nL \r\n_ L \r\n \r\n\r\n __ L LL__ ___ _ L__\r\nL __L__ \r\n___ LLL\r\n ___\r\n \r\n __ \r\n __ ___ __\r\n__\r\n _L__ __ L___LL \r\nL L__\r\nL_L____\r\n_L __\r\n__ _____ \r\n_____\r\n_______ L__\r\nL__ \r\n__L__\r\n__L _ LL \r\n_____ \r\n \r\n \r\nLL_L \r\nL\r\nL __LL__\r\n L ___L_\r\n\r\n \r\n L __\r\n___ \r\n_\r\n\r\n L ____ __ L___\r\n __ __\r\n\r\n __ \r\n")); diff --git a/cs/Markdown/Rules/BoldRule.cs b/cs/Markdown/Rules/BoldRule.cs index f9398109f..713472e21 100644 --- a/cs/Markdown/Rules/BoldRule.cs +++ b/cs/Markdown/Rules/BoldRule.cs @@ -79,8 +79,7 @@ public TagKind MoveByRule(char ch, int position) } - // (!isItalicInStart || symbol == SymbolStatus.eof) - if (isTagClosed && ((!isItalicInMiddle && !isItalicInStart) || symbol == SymbolStatus.eof)) // (!isItalicInMiddle && !isItalicInStart) + if (isTagClosed && ((!isItalicInMiddle && !isItalicInStart) || symbol == SymbolStatus.eof)) { isTagClosed = false; currentState = 0; diff --git a/cs/Markdown/Rules/ItalicRule.cs b/cs/Markdown/Rules/ItalicRule.cs index 96d84ed75..425e64cd7 100644 --- a/cs/Markdown/Rules/ItalicRule.cs +++ b/cs/Markdown/Rules/ItalicRule.cs @@ -4,10 +4,6 @@ namespace Markdown.Rule; public class ItalicRule : IRule { - // TODO List - // 1. проверка обрыва строки (✓) - // 2. старт тэга в странном месте, возможно проблема (✕) - private readonly ITag tag = new ItalicTextTag(); private List tokens = new(); private bool isBoldInMiddle; @@ -32,9 +28,9 @@ public TagKind MoveByRule(char ch, int position) ClearTokens(); } - if (currentState == tag.InputStateNumber || currentState == 14) + if (currentState == 17 || currentState == 18) { - tokens.Add(new Token.Token(tag.MdView, tag.Head, position - (tag.MdView.Length - 1))); + tokens.Add(new Token.Token(tag.MdView, tag.Head, position - tag.MdView.Length)); } else if (currentState == tag.OutputStateNumber) { @@ -47,11 +43,9 @@ public TagKind MoveByRule(char ch, int position) tokens.Add(new Token.Token(tag.MdView, tag.Tail, position - tag.MdView.Length)); } isTagClosed = true; - //return TagKind.Close; } else if (currentState == 10) { - //isBoldInStart = !isBoldInStart; if (isBoldInMiddle) { isBoldInMiddle = false; @@ -67,7 +61,6 @@ public TagKind MoveByRule(char ch, int position) } else if (currentState == 7) { - //isBoldInMiddle = !isBoldInMiddle; if (isBoldInStart) { isBoldInMiddle = false; diff --git a/cs/Markdown/Rules/Rule.cs b/cs/Markdown/Rules/Rule.cs deleted file mode 100644 index 88d385988..000000000 --- a/cs/Markdown/Rules/Rule.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using Markdown.Tags; - -namespace Markdown.Rule; - -public class Rule -{ - private readonly SymbolStatus[] usedSymbols; - private Dictionary> states; - private List tokens = new(); - private readonly int inputStateNumber; - private readonly int[] subOutputStateNumbers; - private readonly int outputStateNumber; - private int currentState; - private readonly ITag currentTag; - - public Rule(ITag tag) - { - usedSymbols = tag.UsedSymbols; - states = tag.States; - currentTag = tag; - inputStateNumber = tag.InputStateNumber; - subOutputStateNumbers = tag.SubOutputStateNumbers; - outputStateNumber = tag.OutputStateNumber; - } - - public TagKind MoveByRule(char ch, int position) - { - var symbol = SymbolStatusParser.ParseSymbolStatus(ch); - - if (!usedSymbols.Contains(symbol)) - { - symbol = SymbolStatus.anotherSymbol; - } - - currentState = states[currentState][symbol]; - - if (symbol == SymbolStatus.eof && (currentState == outputStateNumber || subOutputStateNumbers.Contains(currentState))) - { - tokens.Add(new Token.Token(currentTag.MdView, currentTag.Tail, position + 1)); - return TagKind.Close; - } - - if (currentState == inputStateNumber) - { - tokens.Add(new Token.Token(currentTag.MdView, currentTag.Head, position - (currentTag.MdView.Length - 1))); - } - else if (subOutputStateNumbers.Contains(currentState)) - { - tokens.Add(new Token.Token(currentTag.MdView, currentTag.Tail, position - (currentTag.MdView.Length - 1))); // ? - } - else if (currentState == outputStateNumber) - { - tokens.Add(new Token.Token(currentTag.MdView, currentTag.Tail, position - (currentTag.MdView.Length - 1))); // ? - return TagKind.Close; - } - else if (currentState == 0) - { - tokens.Clear(); - } - - return TagKind.None; - } - - public List GetTokens() { return tokens; } -} \ No newline at end of file diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index 5847ef4eb..420f301bb 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.ComponentModel.Design; using System.Data; using Markdown.Rule; using Markdown.Tags; @@ -8,33 +9,10 @@ namespace Markdown; public class TagParser { - //private readonly Dictionary > TagsOrder = new(); - //private readonly Dictionary> TokensOrder = new(); - //private readonly List<(Func, ITag)> Rules = new(); - - // - //private readonly List Rules = new(); - - //public TagParser(List tags) - //{ - // foreach (var tag in tags) - // { - // //Rules.Add((tag.TagRule, tag)); - // //TagsOrder.Add(tag.Type, new Stack()); - // //TokensOrder.Add(tag.Type, new Stack()); - // //tag.GetCurrentStack(TagsOrder[tag.Type]); - // //tag.InitialzeStates(); - - // Rules.Add(new Rule.Rule(tag)); - // } - //} - // - private List Rules = [ new BoldRule(), new ItalicRule(), - //new EscapeRule(), new H1Rule() ]; @@ -55,41 +33,61 @@ public List GetTokens(string text) var textPointer = 0; var isPointerTeleported = false; var isStateNotChanged = true; + var skip = 0; while (textPointer != text.Length) { - if (textPointer == 5824) + //if (textPointer == 5824) + //{ + // var p = text[5820..5830]; + // //var pe = text[741..750]; + // var z4 = text[5823]; + // var z = text[5824]; + // var z1 = text[5825]; + // var z2 = text[5826]; + // var z3 = text[5827]; + // Console.WriteLine(); + //} + + if (skip != 0) { - var p = text[5820..5830]; - //var pe = text[741..750]; - var z4 = text[5823]; - var z = text[5824]; - var z1 = text[5825]; - var z2 = text[5826]; - var z3 = text[5827]; - Console.WriteLine(); + skip--; } - - var res = EscapeRule.MoveByRule(text[textPointer], textPointer); - - if (res == TagKind.Open) + else { - if (TryGoNextSymbol(textPointer, text)) - { - textPointer++; - res = EscapeRule.MoveByRule(text[textPointer], textPointer); + var res = EscapeRule.MoveByRule(text[textPointer], textPointer); - if (res == TagKind.Close) + if (res == TagKind.Open) + { + if (TryGoNextSymbol(textPointer, text)) { - tokens.AddRange(EscapeRule.GetTokens()); - EscapeRule.ClearTokens(); textPointer++; - isPointerTeleported = true; - isStateNotChanged = false; - } - - if (!TryGoNextSymbol(textPointer, text)) - { - break; + res = EscapeRule.MoveByRule(text[textPointer], textPointer); + + if (res == TagKind.Close) + { + tokens.AddRange(EscapeRule.GetTokens()); + EscapeRule.ClearTokens(); + if (text[textPointer] == '\\') + { + textPointer--; + skip += 1; + } + else + { + textPointer++; + isPointerTeleported = true; + isStateNotChanged = false; + } + } + else + { + textPointer--; + } + + if (!TryGoNextSymbol(textPointer, text)) + { + break; + } } } } diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs index 8b7023e09..8134ed945 100644 --- a/cs/Markdown/Tags/BoldTag.cs +++ b/cs/Markdown/Tags/BoldTag.cs @@ -7,17 +7,10 @@ public class BoldTag : ITag public string Head => ""; public string Tail => ""; public string MdView => "__"; - public TagType Type => TagType.BoldText; - //private int state; - //private Stack currentStack; - //public int TokenPosition { get; set; } public int InputStateNumber { get; } = 2; // 4 - public int[] SubOutputStateNumbers { get; } = {11, 16}; public int OutputStateNumber { get; } = 11; - //private static Dictionary> states = new(); - public Dictionary> States { get; } = InitialzeStates(); public SymbolStatus[] UsedSymbols { get; } = @@ -156,27 +149,4 @@ public static Dictionary> InitialzeStates() return states; } - //public int[] Positions { get; set; } = { 0, 0 }; - //public int[] MdLen { get; set; } = { 0, 0 }; - //public char[] PrevSymbols { get; set; } = { ' ', ' ' }; - - //public TagKind TagRule(char ch, int position) - //{ - // return TagKind.None; - //} - - //public ITag CreateNewTag() - //{ - // return new BoldTag(); - //} - - //public void GetCurrentStack(in Stack stack) - //{ - // currentStack = stack; - //} - - //public void ResetRule() - //{ - // state = 0; - //} } \ No newline at end of file diff --git a/cs/Markdown/Tags/EscapeTag.cs b/cs/Markdown/Tags/EscapeTag.cs index a15496c56..b17d9cd7b 100644 --- a/cs/Markdown/Tags/EscapeTag.cs +++ b/cs/Markdown/Tags/EscapeTag.cs @@ -6,17 +6,10 @@ public class EscapeTag : ITag private string symbol; public string Tail => symbol; public string MdView => """\"""; - public TagType Type => TagType.Escape; - //private Stack currentStack; - //public int TokenPosition { get; set; } - //private char previousCharecter; public int InputStateNumber { get; } = 1; - public int[] SubOutputStateNumbers { get; } = Array.Empty(); public int OutputStateNumber { get; } = 2; - //private static Dictionary> states = new(); - public Dictionary> States { get; } = InitialzeStates(); public SymbolStatus[] UsedSymbols { get; } = @@ -48,30 +41,4 @@ public static Dictionary> InitialzeStates() return states; } - - //public void InitialzeStates() - //{ - - //} - //public int[] Positions { get; set; } = { 0, 0 }; - //public int[] MdLen { get; set; } = { 0, 0 }; - //public char[] PrevSymbols { get; set; } = { ' ', ' ' }; - - //public TagKind TagRule(char ch, int position) - //{ - // return TagKind.None; - //} - - //public ITag CreateNewTag() - //{ - // return new EscapeTag(); - //} - //public void GetCurrentStack(in Stack stack) - //{ - // currentStack = stack; - //} - - //public void ResetRule() - //{ - //} } \ No newline at end of file diff --git a/cs/Markdown/Tags/H1Tag.cs b/cs/Markdown/Tags/H1Tag.cs index 597a8fbe5..9bf10f61a 100644 --- a/cs/Markdown/Tags/H1Tag.cs +++ b/cs/Markdown/Tags/H1Tag.cs @@ -7,16 +7,10 @@ public class H1Tag : ITag public string Head => "

"; public string Tail => "

"; public string MdView => "# "; - public TagType Type => TagType.Header; - //private Stack currentStack; - //public int TokenPosition { get; set; } public int InputStateNumber { get; } = 3; - public int[] SubOutputStateNumbers { get; } = Array.Empty(); public int OutputStateNumber { get; } = 5; - //private static Dictionary> states = new(); - public Dictionary> States { get; } = InitialzeStates(); public SymbolStatus[] UsedSymbols { get; } = @@ -76,26 +70,4 @@ public static Dictionary> InitialzeStates() return states; } - //public int[] Positions { get; set; } = { 0, 0 }; - //public int[] MdLen { get; set; } = { 0, 0 }; - //public char[] PrevSymbols { get; set; } = { ' ', ' ' }; - - //public TagKind TagRule(char ch, int position) - //{ - // return TagKind.None; - //} - - //public ITag CreateNewTag() - //{ - // return new H1Tag(); - //} - - //public void GetCurrentStack(in Stack stack) - //{ - // currentStack = stack; - //} - - //public void ResetRule() - //{ - //} } \ No newline at end of file diff --git a/cs/Markdown/Tags/ITag.cs b/cs/Markdown/Tags/ITag.cs index 390799ca3..93dfa5218 100644 --- a/cs/Markdown/Tags/ITag.cs +++ b/cs/Markdown/Tags/ITag.cs @@ -5,23 +5,10 @@ public interface ITag public string MdView { get; } public string Head { get;} public string Tail { get;} - public TagType Type { get; } public SymbolStatus[] UsedSymbols { get; } public Dictionary> States { get; } public int InputStateNumber { get; } - public int[] SubOutputStateNumbers { get; } public int OutputStateNumber { get; } - - // public int TokenPosition { get; set; } - - //public TagKind TagRule(char ch, int position); - // public ITag CreateNewTag(); - // public void GetCurrentStack(in Stack stack); - // public void ResetRule(); - - // public void InitialzeStates(); - // public int[] Positions { get; set; } - // public char[] PrevSymbols { get; set; } } \ No newline at end of file diff --git a/cs/Markdown/Tags/ItalicTextTag.cs b/cs/Markdown/Tags/ItalicTextTag.cs index 0ce9f6086..376e3e0c7 100644 --- a/cs/Markdown/Tags/ItalicTextTag.cs +++ b/cs/Markdown/Tags/ItalicTextTag.cs @@ -8,19 +8,10 @@ public class ItalicTextTag : ITag public string Head => ""; public string Tail => ""; public string MdView => "_"; - public TagType Type => TagType.ItalicText; public int InputStateNumber { get; } = 1; - public int[] SubOutputStateNumbers { get; } = Array.Empty(); public int OutputStateNumber { get; } = 12; - //private bool state; - //private Stack currentStack; - //private int startPosition; - //public int TokenPosition { get; set; } - - //private static Dictionary> states = new(); - public Dictionary> States { get; } = InitialzeStates(); public SymbolStatus[] UsedSymbols { get; } = @@ -51,6 +42,8 @@ public static Dictionary> InitialzeStates() states.Add(14, new Dictionary()); states.Add(15, new Dictionary()); states.Add(16, new Dictionary()); + states.Add(17, new Dictionary()); + states.Add(18, new Dictionary()); states[0].Add(SymbolStatus.text, 13); // 0 states[0].Add(SymbolStatus.digit, 0); @@ -60,14 +53,13 @@ public static Dictionary> InitialzeStates() states[0].Add(SymbolStatus.space, 0); states[0].Add(SymbolStatus.anotherSymbol, 13); // 0 - // Tag Open - states[1].Add(SymbolStatus.text, 2); + states[1].Add(SymbolStatus.text, 17); states[1].Add(SymbolStatus.digit, 0); states[1].Add(SymbolStatus.underscore, 9); states[1].Add(SymbolStatus.eof, 0); states[1].Add(SymbolStatus.newline, 0); states[1].Add(SymbolStatus.space, 0); - states[1].Add(SymbolStatus.anotherSymbol, 2); + states[1].Add(SymbolStatus.anotherSymbol, 17); states[2].Add(SymbolStatus.text, 2); states[2].Add(SymbolStatus.digit, 0); @@ -110,13 +102,13 @@ public static Dictionary> InitialzeStates() states[6].Add(SymbolStatus.anotherSymbol, 7); // Maybe Bold in Italic - states[7].Add(SymbolStatus.text, 2); // 0 + states[7].Add(SymbolStatus.text, 2); states[7].Add(SymbolStatus.digit, 0); - states[7].Add(SymbolStatus.underscore, 5); // 1 + states[7].Add(SymbolStatus.underscore, 5); states[7].Add(SymbolStatus.eof, 0); states[7].Add(SymbolStatus.newline, 0); - states[7].Add(SymbolStatus.space, 3); // 0 - states[7].Add(SymbolStatus.anotherSymbol, 2); // 0 + states[7].Add(SymbolStatus.space, 3); + states[7].Add(SymbolStatus.anotherSymbol, 2); states[8].Add(SymbolStatus.text, 2); states[8].Add(SymbolStatus.digit, 0); @@ -168,14 +160,13 @@ public static Dictionary> InitialzeStates() states[13].Add(SymbolStatus.space, 0); states[13].Add(SymbolStatus.anotherSymbol, 13); - // Tag Open - states[14].Add(SymbolStatus.text, 15); + states[14].Add(SymbolStatus.text, 18); states[14].Add(SymbolStatus.digit, 0); states[14].Add(SymbolStatus.underscore, 0); states[14].Add(SymbolStatus.eof, 0); states[14].Add(SymbolStatus.newline, 0); states[14].Add(SymbolStatus.space, 0); - states[14].Add(SymbolStatus.anotherSymbol, 15); + states[14].Add(SymbolStatus.anotherSymbol, 18); states[15].Add(SymbolStatus.text, 15); states[15].Add(SymbolStatus.digit, 0); @@ -193,47 +184,24 @@ public static Dictionary> InitialzeStates() states[16].Add(SymbolStatus.space, 12); states[16].Add(SymbolStatus.anotherSymbol, 12); + // Tag Open + states[17].Add(SymbolStatus.text, 2); + states[17].Add(SymbolStatus.digit, 0); + states[17].Add(SymbolStatus.underscore, 5); + states[17].Add(SymbolStatus.eof, 0); + states[17].Add(SymbolStatus.newline, 0); + states[17].Add(SymbolStatus.space, 3); + states[17].Add(SymbolStatus.anotherSymbol, 2); + + // Tag Open + states[18].Add(SymbolStatus.text, 15); + states[18].Add(SymbolStatus.digit, 0); + states[18].Add(SymbolStatus.underscore, 16); + states[18].Add(SymbolStatus.eof, 0); + states[18].Add(SymbolStatus.newline, 0); + states[18].Add(SymbolStatus.space, 0); + states[18].Add(SymbolStatus.anotherSymbol, 15); + return states; } - - //private int gloabalState; - //public int[] Positions { get; set; } = { 0, 0 }; - //public int[] MdLen { get; set; } = { 0, 0 }; - //public char[] PrevSymbols { get; set; } = { ' ', ' ' }; - - //public TagKind TagRule(char ch, int position) - //{ - // gloabalState = states[gloabalState][SymbolStatusParser.ParseSymbolStatus(ch)]; - // if (gloabalState == 1) - // { - // Positions[0] = position; - // MdLen[0] = 1; - // PrevSymbols[0] = ch; - // return TagKind.Open; - // } - - // if (gloabalState == 4) - // { - // Positions[1] = position; - // MdLen[1] = 1; - // PrevSymbols[1] = ch; - // return TagKind.Close; - // } - // return TagKind.None; - //} - - //public ITag CreateNewTag() - //{ - // return new ItalicTextTag(); - //} - - //public void GetCurrentStack(in Stack stack) - //{ - // currentStack = stack; - //} - - //public void ResetRule() - //{ - // state = false; - //} } \ No newline at end of file diff --git a/cs/MarkdownTests/MarkdownSpeedTest.cs b/cs/MarkdownTests/MarkdownSpeedTest.cs index 60095d43e..5332cbd5b 100644 --- a/cs/MarkdownTests/MarkdownSpeedTest.cs +++ b/cs/MarkdownTests/MarkdownSpeedTest.cs @@ -18,8 +18,6 @@ public void Render_ShouldWorkFast() { var text = GetRandomString(length); sw.Start(); - Console.WriteLine("-----------------------------"); - Console.WriteLine(text); Md.Render(text); sw.Stop(); results.Add(sw.Elapsed); diff --git a/cs/MarkdownTests/MarkdownTest.cs b/cs/MarkdownTests/MarkdownTest.cs index 1a32be41e..ecba77d66 100644 --- a/cs/MarkdownTests/MarkdownTest.cs +++ b/cs/MarkdownTests/MarkdownTest.cs @@ -70,7 +70,7 @@ public static IEnumerable ShieldingTestCases { yield return new TestCaseData("\\_a_", "_a_").SetName("shielded opening tag"); yield return new TestCaseData("\\\\_a_", "\\a").SetName("ignore shield backslash"); - yield return new TestCaseData("_\\a_", @"\a").SetName("does not escape the letter"); + yield return new TestCaseData("_\\a_", "\\a").SetName("does not escape the letter"); yield return new TestCaseData("_a\\_", "_a_").SetName("shielded closing tag"); yield return new TestCaseData("\\__a_", "_a").SetName("shields the bold turning into italic"); yield return new TestCaseData("__test \\_ _markdown_ text__ another text", "test _ markdown text another text") From 7b4d9db616e0dcac095fbe6d0e87e29af0b1104a Mon Sep 17 00:00:00 2001 From: Leonid Date: Mon, 2 Dec 2024 10:50:32 +0500 Subject: [PATCH 12/15] all tags work stable --- cs/Markdown/Program.cs | 4 ++-- cs/Markdown/Rules/BoldRule.cs | 3 --- cs/Markdown/TagParser.cs | 14 +++++++------- cs/Markdown/Tags/BoldTag.cs | 2 +- cs/Markdown/Tags/ItalicTextTag.cs | 4 ++-- cs/MarkdownTests/MarkdownSpeedTest.cs | 4 +++- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs index ac589b707..5d32922a9 100644 --- a/cs/Markdown/Program.cs +++ b/cs/Markdown/Program.cs @@ -1,8 +1,8 @@ using System.Threading.Channels; using Markdown; -Console.WriteLine(Md.Render("\\\\_a_")); +//Console.WriteLine(Md.Render("\\\\_a_")); //__test \_ _markdown_ text__ another text // _Markdown123_ -//Console.WriteLine(Md.Render("_ \r\n _\r\n_\r\n_ E \r\n __ E_ ___\r\nE _\r\n\r\n\r\nE_ EEE \r\n _____ \r\nE____E E____ \r\n__\r\nE_EE__E\r\n______\r\n__ __E E _ \r\n\r\n__\r\n__\r\n ____\r\n _ EE__E_\r\n ___ ______ ___ E E_\r\n\r\n__\r\n \r\n \r\n__ __\r\nE E ___ __ EE_ __ \r\n__ E_ \r\nE E\r\n__ ___ \r\n E\r\n\r\n____\r\n___ \r\n\r\n__ \r\n E \r\n__ E __E __ \r\n____\r\n\r\n\r\n\r\n\r\nE \r\n\r\n __ _ _ \r\n _ \r\n E\r\n____ \r\n_ __E___ _\r\n __\r\n E E_ \r\n \r\nE_E__ _\r\n _\r\n \r\n \r\n_ E __E E \r\n _ E _________EE__E E__ E\r\n _ E _\r\n__\r\n___\r\nE _____\r\nE\r\n\r\nE_ ______ __ __E ___ E__ E _\r\n _ _E_ E__\r\n__ ______\r\n\r\n _ E __E \r\n\r\n\r\n__ __ _________ __ E__ E\r\n\r\n E \r\nE_\r\n\r\n EEE\r\n_ __\r\n\r\n__\r\n \r\n__ E__ E \r\nE_E_____ \r\nE____ _ _E \r\n__\r\nE EE__\r\n _ ___ E ___\r\n __ ____\r\n____ E \r\n\r\n E_ \r\n__\r\n__ \r\n _ __ \r\n___\r\n EE\r\n E________ E\r\n__\r\n_______\r\n E___E E E____E_EEE_\r\n __\r\nE E __ \r\n___\r\n__ ___ __ \r\nE ___ _E __ __ \r\n___E \r\n-----------------------------\r\nG _\r\n__ _\r\n _ G _\r\n G \r\n G _\r\n \r\n __\r\n\r\n \r\n \r\n\r\n\r\n ____ ___ _G _G ___ _ __\r\n \r\n G___ _GG G G_ \r\n_\r\n\r\nG_\r\nGG \r\n\r\n__G\r\n___ G\r\n\r\n__ __ \r\nG GG GG\r\n__\r\n__ ___\r\n_\r\n_____G \r\n \r\n\r\n___G\r\n\r\n ___ G\r\nG G\r\n___ _G G_ G G G ____\r\n_ \r\n\r\n_ _____ G\r\n \r\n\r\n G\r\n \r\n __ \r\n__\r\nG____\r\n__ _\r\nG __ _ G _____ _ \r\nG__\r\n_\r\n \r\n____G\r\n __ _ __\r\n_ \r\n _ _ \r\n\r\n\r\n _\r\n GG \r\n G\r\n_ \r\n_ ________GG \r\nG__G__G__ \r\nGG __ __\r\nG____ \r\nG__G_ G \r\n___\r\n _ __\r\nG__\r\n _\r\n_ G__\r\nG__G \r\n G G\r\n G___\r\n__ \r\n \r\n _ ______ __G _\r\nG\r\nG_GG____\r\n\r\n __ __G G__\r\nG__\r\n _G\r\n\r\n __ __\r\n__G_G\r\n __G\r\n\r\nG____G\r\n G__ __G ___G ____G GG \r\n \r\n G__ \r\n G\r\n\r\n\r\n__G __\r\n\r\nG GG__GGG\r\n__G GG\r\n___ G_ G____\r\nG___G\r\n \r\n \r\n __ ___ ____ GG\r\n GG_ _\r\n\r\n G G GG_____G\r\nG____ \r\n_____\r\n\r\n G _G ___\r\nG_\r\n__ G__G \r\n __ \r\n ___ \r\n \r\nG __\r\n \r\n\r\n__ G____\r\n ___ _ __ __G____ __ __\r\n G\r\n GG \r\n _\r\nGG G _ G ______GG___\r\n__\r\n\r\nG GG _\r\n __ G \r\nG_ G G_ G__G_ G G\r\n \r\n__G__\r\nG_G G \r\n ___ __ \r\n\r\n \r\n\r\nG __ G__G\r\n \r\n G\r\n ________ _\r\n_______\r\n _ _ _______G__ __\r\n __G\r\n G__ \r\n ___\r\nG\r\n\r\n\r\nG__ ___G___ G\r\n __ \r\n __G ____G\r\n __ __ ____ \r\n____ _\r\nGG\r\n\r\n\r\n\r\n ____ __\r\n _G\r\n \r\nG___ _G\r\n_ __ _ G__ __GG\r\n _\r\nG____ GG\r\n_\r\n \r\n_\r\nG _ \r\n ____G G \r\n G G___ \r\n_\r\n__ \r\n__G__\r\n__ ___ \r\n__ G__ G ___\r\n GG __\r\n__G__ \r\n\r\n_ __ GG__GG\r\n_______ G\r\n _\r\nG____ ___ _ G ____ G___ G__G __G__ G G__\r\n _______\r\nGG___ __\r\n \r\n G __GG\r\n\r\n_G __ __ \r\n \r\n __ \r\n_G \r\n_ _ ____ \r\n\r\n__ \r\n_G __ G\r\n\r\nG\r\n__\r\n \r\n_\r\n G ____ ___G\r\n\r\nG \r\n_G _\r\n __ _\r\n_\r\nG\r\n _G __ ___ \r\nG_\r\n____G\r\n___ _G \r\n__ G\r\n__G\r\n __ __ ____ G_________ \r\n __G\r\n__G_ G___\r\n\r\n __G \r\n_ G___ __ _____\r\n\r\n_______\r\n-----------------------------\r\n \r\n__\r\n____\r\nL_\r\n_____L_\r\nL L\r\n__ \r\n___L_ __ _L_\r\nLL___ L \r\n _ ____\r\n \r\n__\r\nL L\r\n L\r\n \r\nLL L__ \r\n __LL___ L _ \r\nL \r\n_\r\n\r\n _L\r\n__ \r\n___ ____ L__ \r\nL_L_ ________ _ __\r\n _\r\n __ __L \r\n_ __ L\r\n_ \r\n___L_L_\r\n_L__ _L\r\n__L___\r\n___L\r\n_L _ \r\n_\r\nL___\r\nL L _ _ _\r\n____ ___\r\n__L\r\n___ \r\nL\r\n __\r\n__L L ____L \r\n\r\n _ __ __L___L_L__ \r\n __ _\r\nL___ \r\nL LLL_L\r\n____L __L \r\n _ __\r\n___\r\n___L__ L__\r\nLL _\r\nL\r\nL__ \r\nL L __ \r\nL\r\n__ L__\r\n L__ __L__ __\r\nL ____\r\nL _ ___\r\n ____\r\n\r\n_ L_L L ___ L _ \r\n\r\n__ \r\nL_ L_L \r\n \r\n_ \r\nL______LL\r\n__ \r\n\r\nL __ L_ _______L\r\n\r\n L ___ ___L___ _\r\n L \r\n __L\r\nL\r\nL___ __L_\r\n__ _LL ______ __L\r\n__ __\r\nL ____ ____ \r\n_ _ L\r\n\r\n \r\n\r\n L_ _ _ _____ _\r\nL __\r\n___\r\n\r\n__ \r\n \r\n _ \r\n L_\r\n L L____ _ L\r\nL__ L \r\n L \r\n____L L_ \r\n_LL_____\r\n \r\n L__LLLLL LL____ _____ _\r\n _L \r\n __ ___ _ LL __ \r\n L___ L __ _____ L__ __\r\nL____ _\r\n\r\n__ L_ ___ L _\r\nL___\r\nL ___L____L__ _ LLL__ __ __ LLL____\r\n\r\n _ \r\n _L____L___ \r\n__ _ \r\n L__\r\n\r\n\r\n L__\r\n\r\n L___________\r\n_L\r\n\r\n LLL___ \r\n ___\r\n_\r\n\r\n\r\n ____\r\n __ _ __ \r\n\r\nL \r\n___L__ _ _LL_ _L _ __ \r\n\r\n ________L\r\n__L __L__ __L_____\r\n__ \r\n__ L \r\n__ __\r\n__LL \r\n____ \r\n\r\n_ ______\r\n __L\r\n_ _____ _ L\r\n_________\r\n\r\n_ L\r\n _ \r\n\r\n L \r\n _L _L___ __\r\nL__ _ LLL L __ \r\n__ ___L_\r\n\r\n _ __\r\nL_ _L \r\n L\r\nLL__\r\n __ __ \r\n_____\r\n _ \r\n \r\n_\r\n__ __\r\n _ ____ __\r\nL__ \r\nL L___L __ ____L __ __\r\n LL_ ____L\r\n \r\n\r\n __ _\r\n L__\r\n_ L\r\n__ L__\r\n\r\n L \r\nL \r\n\r\n______\r\n _ LL __\r\n__ ____\r\n_______ __L \r\n_\r\n_ ___ _ _L \r\n\r\n____ LL_ LL\r\n___ \r\n ____L L__ L\r\nL____\r\n\r\n \r\n\r\nL L L ___ L__ \r\n__ L_____\r\n__ __ _L __ __L_L_L \r\n L __ __L L__\r\nL L _LL _ \r\n\r\n L __ \r\n __ \r\n ___ \r\n_____ _____ _L LLL_ \r\n _ _\r\n_LL __\r\n \r\n_\r\n__L\r\n_ __ _\r\n_ ___ _____ _\r\n L L____ L_____L\r\n__L _ __\r\n___ ____\r\n L\r\n ____\r\n \r\n__ \r\n __ L __ ____ \r\nL_\r\n____\r\n__\r\n ___ _L \r\nL__\r\nL \r\n_L _ _ \r\n L ________\r\n _ _\r\nL__L_ __\r\n _L\r\n___\r\nL _ LL__LLL\r\n_ \r\n \r\n__ L____\r\nL __\r\n_\r\n LL_\r\n__ ___\r\n_____L_ L__\r\n__ L\r\n_L \r\n LL __\r\n \r\nLL L_ \r\n\r\n\r\n__\r\n ____ \r\n L____\r\nL_ __LL ___\r\n __ ______ __ _______\r\n L ____ L_ \r\n_ __ \r\nL\r\n__LL\r\n L\r\n __ \r\n\r\nL__L_ L __\r\nLL___ \r\nL\r\n ____L__ L\r\n __L_\r\n_ ___ L_ L\r\n L_\r\n \r\n L____ \r\nL\r\n\r\n\r\n __L__L\r\n__ \r\n \r\n\r\n_____\r\n\r\nL _\r\n_L \r\nL_ \r\n L _ __\r\n_______LL___L___\r\n L ___ _ __L L\r\nL__ __\r\nL \r\n_ \r\nL__\r\n__L\r\n _L\r\nL\r\nLL__\r\n L\r\n\r\n_ __LL L__LL_ __\r\n __LL___\r\nL \r\nL\r\nL\r\n__ L \r\n \r\n__ __L __ __ L__\r\n LL \r\n __ _ ______ __\r\nL__LL_ __L__L_L_\r\n ______ L \r\n_\r\n\r\n__L______ __L_\r\nLL\r\n L \r\n\r\n __ \r\n \r\n \r\nL__ \r\n\r\n\r\n L _L__ \r\n_____L__ L__ \r\nLL ___ \r\n\r\n _\r\n \r\n___\r\n__ LL\r\n\r\n L \r\n__L__L_L__ _ _\r\n__\r\n\r\n_ L_ ______ \r\nL __ _____ _________L \r\n__ _ L___L__ __ _L__ \r\n\r\n __\r\nL L L \r\n__L __L LL_______\r\nL \r\n __ L ____ _____ _ \r\n __ \r\n __ __ L L ____ _LL\r\nLL _ __ _LL _ __\r\n\r\nL____L__ _________________\r\n L__L__ __ \r\n__ __\r\n\r\n_ \r\n__\r\n_ LL __ L\r\n__ __ ___ __L_ \r\nL L\r\n_ L\r\n_\r\n __L __\r\n L\r\n_ \r\n_ ___\r\n\r\nLL_\r\n\r\n L_\r\n __ \r\n__ L_\r\n \r\nL_L\r\n L \r\n \r\n\r\nL \r\nL\r\n_____ \r\nL _\r\n L__\r\nLL__ __\r\n_ _ \r\n______\r\n_\r\n_ __ \r\n L__\r\n______\r\n L L_\r\nL _ _ _ __L_ \r\n______ L \r\n \r\nL \r\n_ L \r\n \r\n\r\n __ L LL__ ___ _ L__\r\nL __L__ \r\n___ LLL\r\n ___\r\n \r\n __ \r\n __ ___ __\r\n__\r\n _L__ __ L___LL \r\nL L__\r\nL_L____\r\n_L __\r\n__ _____ \r\n_____\r\n_______ L__\r\nL__ \r\n__L__\r\n__L _ LL \r\n_____ \r\n \r\n \r\nLL_L \r\nL\r\nL __LL__\r\n L ___L_\r\n\r\n \r\n L __\r\n___ \r\n_\r\n\r\n L ____ __ L___\r\n __ __\r\n\r\n __ \r\n")); +Console.WriteLine(Md.Render(" ____AA\r\n _ A A A \r\n__ \r\nAA___A__A\r\n ____A __\r\n __ A \r\n__ \r\n\r\n A \r\nA __\r\n______ _ A\r\nA\r\n \r\n __\r\n____ _ _\r\n\r\n A\r\n\r\n__\r\nAA__ A\r\n__ _ __ \r\n__ __A_ A\r\n ____\r\n\r\n A\r\nA\r\nAA__\r\n__A A \r\n____ _ _ AA \r\n A__A\r\nA \r\nA\r\nA __ _\r\n __\r\n_A \r\n_AA____ ________\r\n _\r\n _\r\nA \r\n_\r\n __ A __\r\nA A __ \r\n A _\r\n \r\nA \r\nA __\r\n\r\nA\r\n\r\n____\r\n_ A____\r\n___\r\n_A\r\nA__ __ \r\n_ A __\r\n \r\n_A _ _\r\n_ A __A __ \r\n __ __ \r\n\r\n_ \r\nA _____ ___ \r\n __ A _____A AA\r\nA____\r\n ____ A_ A __ \r\n___\r\nA__\r\n__ \r\n A __ \r\n _A__A \r\n\r\n\r\nA \r\n___ \r\n____A _ \r\n_ _\r\nA_____\r\n__ \r\n __\r\nA __AA \r\n\r\n__A A _ A__ AA__\r\n__ ___A_ AA_ \r\n_ _ A____A\r\n_ A AA __AA _\r\n\r\n __ _A __A\r\nA__\r\n___ _ A\r\n_\r\n_A________ \r\n___ __\r\n__\r\n __\r\n _____\r\n\r\nA__A \r\n ___A_____ \r\n\r\n ___\r\nA_\r\n \r\n___ \r\nAAA______ \r\n __ _A__ __A_\r\nA __ A\r\n ___ ___ _ __A_______A\r\nA _ _A____\r\n_ _A__A__\r\n___ __A A\r\n_\r\n __ _\r\n----------------------------\r\n__\r\n____\r\n __ \r\n__\r\n_ ___\r\n__\r\n___ VV___V_ V _ __ __V\r\nV_\r\n \r\n__V_ _ ___\r\n__ \r\nV____\r\n\r\n_V__ __\r\n_\r\n \r\n __ \r\n V VV__ \r\n __ \r\nV\r\n\r\n \r\n __V____ \r\n__ _V \r\n\r\n ___ \r\nV \r\n\r\n__V \r\n _______ __VV ___ __\r\n\r\n ___ V\r\n __ \r\n__\r\n\r\n V ___\r\n\r\nV __ ___ \r\n____ __\r\n\r\n ___ __ \r\n ___V __ _ _ __ __V__ ____ \r\n\r\n V\r\n_V_____V____ ______V____ _ \r\n _ V__V __ \r\n V\r\nV\r\n\r\n______ ___\r\n____ ___ \r\n _\r\n\r\nV V_V____ ___V\r\n__V\r\n V ___ V\r\nVV_\r\n __ V\r\nV __ \r\n __\r\n ___V \r\n\r\n V V___V_ __ __ _____ \r\n__V_ \r\n __ \r\nV \r\n_\r\n__\r\n _ \r\n\r\n _V ___ \r\n____\r\n___ V\r\n__\r\n\r\n___\r\n _V __ \r\nVV____ V\r\nV__ __V_ __\r\n __\r\n\r\n\r\n\r\n\r\n_ \r\n \r\n\r\n\r\n V_ __\r\n___\r\nV __\r\n \r\n _ \r\n_ V__V __\r\n\r\n_ \r\n _ V__\r\nV\r\n__V____\r\n__ _\r\n\r\n_ \r\n \r\n __ __V___\r\nV\r\n__\r\n___ _________ \r\nV__ V _V \r\nV\r\nV___ VVV_ V\r\n\r\n V _ __VVV V ___\r\nV_\r\n_V __ ____ \r\nVV__V ___ _ ___ ___ __V__V _ __ __ \r\n___ V_V V\r\n \r\nV _____\r\n\r\n ____ __V_ \r\n\r\n\r\n __V_ ___V \r\n\r\n \r\n__\r\n\r\n\r\n VV__\r\n _V\r\nV__\r\n \r\n__ V__ ___V____V__ _V\r\n_VV V____ _\r\n\r\n_____V__\r\n \r\n \r\n __\r\n V V\r\n\r\n\r\n \r\nV_V___V__\r\n\r\n__\r\n __ V_ __V __V\r\n _____\r\n_ _ V__V __V _\r\n____ __V____ V _V \r\n\r\n___\r\nV__ \r\n__\r\n\r\n VV_ \r\n V_____ \r\n\r\n_V____ _____V __\r\n\r\n V __ _ _ \r\nV\r\n___\r\n __ V __\r\n\r\n_\r\n \r\n_\r\n\r\nV __\r\n________ \r\n_ V_ \r\n__V \r\n \r\n_\r\nVV__ \r\n\r\n _\r\n __ V V V __\r\n VV _V\r\n \r\n VVV_ \r\n V_ _____ V_\r\n\r\n_ \r\n___\r\n_ __ \r\n\r\n V\r\nV_______ ___ __\r\n\r\n\r\n_ V\r\n_V_ VV _ __ \r\n _____\r\n\r\nVV \r\n_V___\r\n__ VV V__ ___V\r\n\r\nV_ __ __ VV \r\n\r\n \r\n_V\r\n V\r\n \r\n__ _ V _______V_ _\r\n \r\n______\r\n __V__VVV_ __\r\n__ __V________ V __ V_\r\n\r\n V\r\n_______V__\r\n__\r\nV\r\n_VV___\r\n __ \r\n\r\n_V____\r\n\r\n\r\n\r\n__\r\n__ V _ __ \r\n\r\n V \r\n_ _VV\r\nV __ \r\nV___ \r\n \r\n\r\n \r\n\r\n___V _V V V \r\nV_ __ __ _\r\n V__\r\n_____V \r\n\r\n\r\n___ V___V __ ______ ___V V V____ \r\n----------------------------\r\n __ \r\nS \r\n_______ \r\n__\r\n _ S_\r\n__S ___S\r\n S _ ___S__\r\nS ___ _S\r\n __\r\n_\r\n__ SS \r\n __ \r\n\r\n_ ___ S __\r\nS __ S__\r\n__________\r\n_ \r\nS__ __\r\n__S\r\n S_____ __SS_ \r\n _ _SS\r\nS __ \r\n____ S\r\n__\r\nS\r\n\r\n___S\r\n S\r\n \r\n____ _ S__ S __SS _ _____\r\n S\r\n_ \r\n__S\r\n \r\n\r\n__\r\n \r\n____ __ __\r\n \r\n_________\r\n__S \r\n_____ SS_S___S\r\n\r\nSS \r\nS \r\n_\r\n _\r\n _S___S _ S__ __\r\n___ ___ _ ___ SSS S __ SS\r\nS __SS \r\n__ ____SSS_ S_ ___S\r\n S\r\nS\r\n \r\n \r\n_S\r\n_S__ __ _\r\n_SS __S___ \r\n \r\n S____ \r\n\r\nS \r\n ____S____\r\n ____ _S___ ___ S___S_S ____\r\nSS_ _____ __S _S __S __\r\n ____ \r\n___\r\n__SS__________ ____ _ __S __\r\n S\r\n___ \r\n\r\nSS__S \r\n \r\nS__\r\n\r\n__ __ _S S\r\n___\r\nS __\r\n\r\nS\r\nS __S\r\n _____ ___ \r\n \r\n____\r\nS\r\n\r\n_\r\n_\r\n__\r\n S \r\n_\r\n S__ _ _\r\nS _\r\n__ SS_ ____ __ _S______ ___SS\r\n__\r\n\r\n __S__\r\n\r\n__ \r\n____ __ __S _\r\n__S__ __ __ __ S __ S___ __ S__ S\r\nS___\r\nSS_S\r\nS __ S ___\r\n__SS__ ____S\r\n __ _ \r\n _ __ \r\n_\r\n ___S\r\n\r\n \r\n \r\n___ S__\r\nS _ S \r\n\r\n_\r\n__ ___ S_ S S__\r\n \r\nS ___ __S\r\n\r\n\r\nS_______SS S__ __ _ _S\r\nS_\r\n\r\n \r\n___ ____ S\r\n SS_ S _ S \r\nS\r\n______\r\n_ _ S __S__S__S_S\r\n ___\r\n __ _ SSS__\r\nS __ _ S\r\n __S S ___ _SS_ \r\n \r\nS ___ __ _ S__ __ SS \r\n____S \r\n _S_ S _ S __ S\r\n_ _SS___\r\n S __ S_SSS_\r\n___ \r\nS __\r\n__\r\n_\r\nSS___ S__SS S\r\n __ \r\n\r\n\r\n__\r\n\r\n _\r\nS\r\n__ _ \r\n_S__ ____\r\n\r\n _ \r\nS\r\nS\r\nS__ S__ ___\r\n __\r\n __ \r\n \r\n \r\nS __ _ _\r\nSS S S____SS__\r\n__ ____ S_________S__ S _\r\n\r\n_ SSS_______\r\n ___S_\r\n_ _ \r\n____ SS\r\n_ \r\n_______ __\r\n__ _\r\nS____S _____ __\r\n__SS\r\n\r\n \r\n \r\n \r\n __ \r\n ________ S__S _ __S\r\nS__\r\n\r\nS_____ \r\n S __\r\n\r\n ___ __ \r\nS__ \r\n _\r\n S__ __S_ __ ______ S___ S____ \r\n\r\n__ \r\n _ __ _\r\n__ S__S SS_\r\n__S\r\n\r\n S\r\n __SS_ _\r\n \r\n ____\r\n_ \r\n\r\n_ S\r\n \r\n\r\n \r\n _______S\r\n_\r\n SS\r\n__SS\r\nSSS\r\n S _S__ S\r\nS\r\n___S_ ____\r\n\r\n__ __S_ _ ___\r\n _\r\n__\r\n__S\r\n\r\n___S__ _ ___ __S\r\n \r\n \r\n__S S \r\n\r\n __ _S_S \r\n \r\n__\r\nS _ \r\n_____ S __ ____\r\n \r\n SS_ __ \r\n S__S S __ ___ \r\n _\r\n \r\n__ \r\nS __S__\r\n __\r\n __\r\n\r\nS\r\n_\r\n\r\n __ SS\r\nSS \r\n __SS _SS\r\n__ \r\n S S__\r\n\r\nS\r\n\r\n _ S S_S_ S_______\r\n\r\nSS__\r\n SS_____\r\n_ S __ S\r\n_SSS\r\n \r\nS__ S__ SS \r\n_S__ \r\n__S _\r\n__\r\n \r\n S\r\n SSSS_ SS ___\r\n__ _ \r\n S\r\nS_____\r\nS__ S\r\n__ S S___\r\n\r\n_ ____ S__\r\n S ____S__S ___\r\nS__ S\r\n _ __SS\r\n S_ \r\n_____SSS\r\n__ ____ __S_______ ____S _ SS\r\n____SS _\r\n__S _ S__ _S_\r\n__ _S\r\n __\r\n\r\nS\r\n __ _ S\r\nS __ __ ___ __ _ \r\n_ ___\r\n ______ S__S__S\r\n_ S __ S\r\n____ S\r\n__ _\r\n \r\n \r\n_ ___S___\r\nS _ \r\n___\r\n__ __\r\n _S_ _SS__ S_ _ ____\r\n _S_ _S _______ _ ____S_ S_ S__ S_____ \r\n__ S__\r\n_ SS S__S S S___S__ S__ \r\n__ \r\n \r\n____\r\n__\r\n _ \r\n \r\n__\r\n_\r\n SS _S\r\n____ __S_______ \r\n\r\nS\r\n __\r\nS S \r\n ___SS_ _ _ S __\r\n SS S ____ S _S \r\n \r\n____S\r\n\r\n S___ S _ S S__ __\r\n__S ___SSS_______ ____ S S S \r\n S \r\n _S S_ S\r\n \r\n__S \r\n _\r\n ___ __S___ _ S _\r\n _S____ S____\r\n S_ \r\n\r\nS__ S __ \r\n _ \r\nS\r\nS __S\r\n___S_S __S ___SS_S__ _ __ \r\n\r\n__ _ _SS\r\nS_S__\r\n __ \r\n_\r\nS__ SSSS ___ __\r\n__ SS_____ S\r\nS_\r\nS__\r\n \r\n________\r\n __ _ ___SS __S_\r\n \r\n ____S __ __ \r\n _____ \r\n_ S S___ S__ \r\n ___\r\n\r\n_\r\n__ \r\n S\r\n __S _ \r\n_\r\n \r\n ___ ___S _ \r\n__ S__ S\r\n\r\nS\r\nS\r\n \r\n__ S\r\n __S\r\n ___ \r\n__ \r\n \r\n __S_____\r\n\r\n \r\n___SS \r\n__ \r\nS___ \r\n___\r\nS______\r\n___\r\nS_ \r\nS__S_SSS _ _\r\n _SS_\r\n \r\nS \r\n \r\n\r\n____\r\n_S_ S_\r\n \r\n____ _ __ _\r\n_\r\n______ __\r\n_____ __\r\n__ S _S__ \r\nS __ S \r\n\r\n__\r\n_\r\n\r\n S \r\nS\r\n_ \r\n _____ _SS __S__ \r\n\r\n \r\n___ \r\n")); diff --git a/cs/Markdown/Rules/BoldRule.cs b/cs/Markdown/Rules/BoldRule.cs index 713472e21..8d35dcd31 100644 --- a/cs/Markdown/Rules/BoldRule.cs +++ b/cs/Markdown/Rules/BoldRule.cs @@ -11,9 +11,6 @@ public class BoldRule : IRule private bool isTagClosed; private int currentState; - // TODO List - // 1. Жирный начался в одном слове но кончился в другом - public TagKind MoveByRule(char ch, int position) { var symbol = SymbolStatusParser.ParseSymbolStatus(ch); diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index 420f301bb..fee4663a3 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -36,15 +36,15 @@ public List GetTokens(string text) var skip = 0; while (textPointer != text.Length) { - //if (textPointer == 5824) + //if (textPointer == 5837) //{ - // var p = text[5820..5830]; + // var p = text[5835..5840]; // //var pe = text[741..750]; - // var z4 = text[5823]; - // var z = text[5824]; - // var z1 = text[5825]; - // var z2 = text[5826]; - // var z3 = text[5827]; + // var z4 = text[5836]; + // var z = text[5837]; + // var z1 = text[5838]; + // var z2 = text[5839]; + // var z3 = text[5840]; // Console.WriteLine(); //} diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs index 8134ed945..04de4e247 100644 --- a/cs/Markdown/Tags/BoldTag.cs +++ b/cs/Markdown/Tags/BoldTag.cs @@ -8,7 +8,7 @@ public class BoldTag : ITag public string Tail => ""; public string MdView => "__"; - public int InputStateNumber { get; } = 2; // 4 + public int InputStateNumber { get; } = 2; public int OutputStateNumber { get; } = 11; public Dictionary> States { get; } = InitialzeStates(); diff --git a/cs/Markdown/Tags/ItalicTextTag.cs b/cs/Markdown/Tags/ItalicTextTag.cs index 376e3e0c7..e95014348 100644 --- a/cs/Markdown/Tags/ItalicTextTag.cs +++ b/cs/Markdown/Tags/ItalicTextTag.cs @@ -129,7 +129,7 @@ public static Dictionary> InitialzeStates() // Maybe Italic in Bold states[10].Add(SymbolStatus.text, 0); states[10].Add(SymbolStatus.digit, 0); - states[10].Add(SymbolStatus.underscore, 0); + states[10].Add(SymbolStatus.underscore, 1); states[10].Add(SymbolStatus.eof, 0); states[10].Add(SymbolStatus.newline, 0); states[10].Add(SymbolStatus.space, 0); @@ -162,7 +162,7 @@ public static Dictionary> InitialzeStates() states[14].Add(SymbolStatus.text, 18); states[14].Add(SymbolStatus.digit, 0); - states[14].Add(SymbolStatus.underscore, 0); + states[14].Add(SymbolStatus.underscore, 9); states[14].Add(SymbolStatus.eof, 0); states[14].Add(SymbolStatus.newline, 0); states[14].Add(SymbolStatus.space, 0); diff --git a/cs/MarkdownTests/MarkdownSpeedTest.cs b/cs/MarkdownTests/MarkdownSpeedTest.cs index 5332cbd5b..f17045531 100644 --- a/cs/MarkdownTests/MarkdownSpeedTest.cs +++ b/cs/MarkdownTests/MarkdownSpeedTest.cs @@ -14,10 +14,12 @@ public void Render_ShouldWorkFast() var sw = new Stopwatch(); var results = new List(); - for (var length = 640; length <= 512 * 10; length *= 2) // 64000 512 * 1000 + for (var length = 640; length <= 512 * 10; length *= 2) { var text = GetRandomString(length); sw.Start(); + Console.WriteLine("----------------------------"); + Console.WriteLine(text); Md.Render(text); sw.Stop(); results.Add(sw.Elapsed); From e92b5fce53cc21a49e563cd1dca9bc55d22c8d0d Mon Sep 17 00:00:00 2001 From: Leonid Date: Mon, 2 Dec 2024 11:21:09 +0500 Subject: [PATCH 13/15] big refactor --- cs/Markdown/Md.cs | 17 ----------------- cs/Markdown/Program.cs | 9 ++------- cs/Markdown/Rules/BoldRule.cs | 6 ++++-- cs/Markdown/Rules/ItalicRule.cs | 9 ++++++--- cs/Markdown/TagParser.cs | 17 +---------------- cs/Markdown/Tags/BoldTag.cs | 2 +- cs/Markdown/Tags/ItalicTextTag.cs | 6 +++--- cs/Markdown/Tags/TagType.cs | 10 ---------- cs/MarkdownTests/MarkdownSpeedTest.cs | 4 +--- cs/MarkdownTests/MarkdownTest.cs | 3 ++- 10 files changed, 20 insertions(+), 63 deletions(-) delete mode 100644 cs/Markdown/Tags/TagType.cs diff --git a/cs/Markdown/Md.cs b/cs/Markdown/Md.cs index 3f89b28d2..f8542ae68 100644 --- a/cs/Markdown/Md.cs +++ b/cs/Markdown/Md.cs @@ -1,22 +1,12 @@ using System.Text; -using Markdown.Tags; using Markdown.Token; namespace Markdown; public static class Md { - private static List availableTags = - [ - //new BoldTag(), - new H1Tag(), - //new ItalicTextTag(), - //new EscapeTag() - ]; - public static string Render(string text) { - //var parser = new TagParser(availableTags); var parser = new TagParser(); return GenerateHtml(text, parser.GetTokens(text)); } @@ -28,13 +18,6 @@ private static string GenerateHtml(string text, List tokens) var sb = new StringBuilder(); foreach (var token in currentTokens) { - if (token.Position == 748) - { - var t = text[746..750]; - var te = text[748]; - Console.WriteLine(); - } - sb.Append(text[position..token.Position]); sb.Append(token.ConvertedText); position = token.Position + token.SourceText.Length > text.Length ? text.Length : token.Position + token.SourceText.Length; diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs index 5d32922a9..7c04bd2a6 100644 --- a/cs/Markdown/Program.cs +++ b/cs/Markdown/Program.cs @@ -1,8 +1,3 @@ -using System.Threading.Channels; -using Markdown; +using Markdown; -//Console.WriteLine(Md.Render("\\\\_a_")); -//__test \_ _markdown_ text__ another text -// _Markdown123_ - -Console.WriteLine(Md.Render(" ____AA\r\n _ A A A \r\n__ \r\nAA___A__A\r\n ____A __\r\n __ A \r\n__ \r\n\r\n A \r\nA __\r\n______ _ A\r\nA\r\n \r\n __\r\n____ _ _\r\n\r\n A\r\n\r\n__\r\nAA__ A\r\n__ _ __ \r\n__ __A_ A\r\n ____\r\n\r\n A\r\nA\r\nAA__\r\n__A A \r\n____ _ _ AA \r\n A__A\r\nA \r\nA\r\nA __ _\r\n __\r\n_A \r\n_AA____ ________\r\n _\r\n _\r\nA \r\n_\r\n __ A __\r\nA A __ \r\n A _\r\n \r\nA \r\nA __\r\n\r\nA\r\n\r\n____\r\n_ A____\r\n___\r\n_A\r\nA__ __ \r\n_ A __\r\n \r\n_A _ _\r\n_ A __A __ \r\n __ __ \r\n\r\n_ \r\nA _____ ___ \r\n __ A _____A AA\r\nA____\r\n ____ A_ A __ \r\n___\r\nA__\r\n__ \r\n A __ \r\n _A__A \r\n\r\n\r\nA \r\n___ \r\n____A _ \r\n_ _\r\nA_____\r\n__ \r\n __\r\nA __AA \r\n\r\n__A A _ A__ AA__\r\n__ ___A_ AA_ \r\n_ _ A____A\r\n_ A AA __AA _\r\n\r\n __ _A __A\r\nA__\r\n___ _ A\r\n_\r\n_A________ \r\n___ __\r\n__\r\n __\r\n _____\r\n\r\nA__A \r\n ___A_____ \r\n\r\n ___\r\nA_\r\n \r\n___ \r\nAAA______ \r\n __ _A__ __A_\r\nA __ A\r\n ___ ___ _ __A_______A\r\nA _ _A____\r\n_ _A__A__\r\n___ __A A\r\n_\r\n __ _\r\n----------------------------\r\n__\r\n____\r\n __ \r\n__\r\n_ ___\r\n__\r\n___ VV___V_ V _ __ __V\r\nV_\r\n \r\n__V_ _ ___\r\n__ \r\nV____\r\n\r\n_V__ __\r\n_\r\n \r\n __ \r\n V VV__ \r\n __ \r\nV\r\n\r\n \r\n __V____ \r\n__ _V \r\n\r\n ___ \r\nV \r\n\r\n__V \r\n _______ __VV ___ __\r\n\r\n ___ V\r\n __ \r\n__\r\n\r\n V ___\r\n\r\nV __ ___ \r\n____ __\r\n\r\n ___ __ \r\n ___V __ _ _ __ __V__ ____ \r\n\r\n V\r\n_V_____V____ ______V____ _ \r\n _ V__V __ \r\n V\r\nV\r\n\r\n______ ___\r\n____ ___ \r\n _\r\n\r\nV V_V____ ___V\r\n__V\r\n V ___ V\r\nVV_\r\n __ V\r\nV __ \r\n __\r\n ___V \r\n\r\n V V___V_ __ __ _____ \r\n__V_ \r\n __ \r\nV \r\n_\r\n__\r\n _ \r\n\r\n _V ___ \r\n____\r\n___ V\r\n__\r\n\r\n___\r\n _V __ \r\nVV____ V\r\nV__ __V_ __\r\n __\r\n\r\n\r\n\r\n\r\n_ \r\n \r\n\r\n\r\n V_ __\r\n___\r\nV __\r\n \r\n _ \r\n_ V__V __\r\n\r\n_ \r\n _ V__\r\nV\r\n__V____\r\n__ _\r\n\r\n_ \r\n \r\n __ __V___\r\nV\r\n__\r\n___ _________ \r\nV__ V _V \r\nV\r\nV___ VVV_ V\r\n\r\n V _ __VVV V ___\r\nV_\r\n_V __ ____ \r\nVV__V ___ _ ___ ___ __V__V _ __ __ \r\n___ V_V V\r\n \r\nV _____\r\n\r\n ____ __V_ \r\n\r\n\r\n __V_ ___V \r\n\r\n \r\n__\r\n\r\n\r\n VV__\r\n _V\r\nV__\r\n \r\n__ V__ ___V____V__ _V\r\n_VV V____ _\r\n\r\n_____V__\r\n \r\n \r\n __\r\n V V\r\n\r\n\r\n \r\nV_V___V__\r\n\r\n__\r\n __ V_ __V __V\r\n _____\r\n_ _ V__V __V _\r\n____ __V____ V _V \r\n\r\n___\r\nV__ \r\n__\r\n\r\n VV_ \r\n V_____ \r\n\r\n_V____ _____V __\r\n\r\n V __ _ _ \r\nV\r\n___\r\n __ V __\r\n\r\n_\r\n \r\n_\r\n\r\nV __\r\n________ \r\n_ V_ \r\n__V \r\n \r\n_\r\nVV__ \r\n\r\n _\r\n __ V V V __\r\n VV _V\r\n \r\n VVV_ \r\n V_ _____ V_\r\n\r\n_ \r\n___\r\n_ __ \r\n\r\n V\r\nV_______ ___ __\r\n\r\n\r\n_ V\r\n_V_ VV _ __ \r\n _____\r\n\r\nVV \r\n_V___\r\n__ VV V__ ___V\r\n\r\nV_ __ __ VV \r\n\r\n \r\n_V\r\n V\r\n \r\n__ _ V _______V_ _\r\n \r\n______\r\n __V__VVV_ __\r\n__ __V________ V __ V_\r\n\r\n V\r\n_______V__\r\n__\r\nV\r\n_VV___\r\n __ \r\n\r\n_V____\r\n\r\n\r\n\r\n__\r\n__ V _ __ \r\n\r\n V \r\n_ _VV\r\nV __ \r\nV___ \r\n \r\n\r\n \r\n\r\n___V _V V V \r\nV_ __ __ _\r\n V__\r\n_____V \r\n\r\n\r\n___ V___V __ ______ ___V V V____ \r\n----------------------------\r\n __ \r\nS \r\n_______ \r\n__\r\n _ S_\r\n__S ___S\r\n S _ ___S__\r\nS ___ _S\r\n __\r\n_\r\n__ SS \r\n __ \r\n\r\n_ ___ S __\r\nS __ S__\r\n__________\r\n_ \r\nS__ __\r\n__S\r\n S_____ __SS_ \r\n _ _SS\r\nS __ \r\n____ S\r\n__\r\nS\r\n\r\n___S\r\n S\r\n \r\n____ _ S__ S __SS _ _____\r\n S\r\n_ \r\n__S\r\n \r\n\r\n__\r\n \r\n____ __ __\r\n \r\n_________\r\n__S \r\n_____ SS_S___S\r\n\r\nSS \r\nS \r\n_\r\n _\r\n _S___S _ S__ __\r\n___ ___ _ ___ SSS S __ SS\r\nS __SS \r\n__ ____SSS_ S_ ___S\r\n S\r\nS\r\n \r\n \r\n_S\r\n_S__ __ _\r\n_SS __S___ \r\n \r\n S____ \r\n\r\nS \r\n ____S____\r\n ____ _S___ ___ S___S_S ____\r\nSS_ _____ __S _S __S __\r\n ____ \r\n___\r\n__SS__________ ____ _ __S __\r\n S\r\n___ \r\n\r\nSS__S \r\n \r\nS__\r\n\r\n__ __ _S S\r\n___\r\nS __\r\n\r\nS\r\nS __S\r\n _____ ___ \r\n \r\n____\r\nS\r\n\r\n_\r\n_\r\n__\r\n S \r\n_\r\n S__ _ _\r\nS _\r\n__ SS_ ____ __ _S______ ___SS\r\n__\r\n\r\n __S__\r\n\r\n__ \r\n____ __ __S _\r\n__S__ __ __ __ S __ S___ __ S__ S\r\nS___\r\nSS_S\r\nS __ S ___\r\n__SS__ ____S\r\n __ _ \r\n _ __ \r\n_\r\n ___S\r\n\r\n \r\n \r\n___ S__\r\nS _ S \r\n\r\n_\r\n__ ___ S_ S S__\r\n \r\nS ___ __S\r\n\r\n\r\nS_______SS S__ __ _ _S\r\nS_\r\n\r\n \r\n___ ____ S\r\n SS_ S _ S \r\nS\r\n______\r\n_ _ S __S__S__S_S\r\n ___\r\n __ _ SSS__\r\nS __ _ S\r\n __S S ___ _SS_ \r\n \r\nS ___ __ _ S__ __ SS \r\n____S \r\n _S_ S _ S __ S\r\n_ _SS___\r\n S __ S_SSS_\r\n___ \r\nS __\r\n__\r\n_\r\nSS___ S__SS S\r\n __ \r\n\r\n\r\n__\r\n\r\n _\r\nS\r\n__ _ \r\n_S__ ____\r\n\r\n _ \r\nS\r\nS\r\nS__ S__ ___\r\n __\r\n __ \r\n \r\n \r\nS __ _ _\r\nSS S S____SS__\r\n__ ____ S_________S__ S _\r\n\r\n_ SSS_______\r\n ___S_\r\n_ _ \r\n____ SS\r\n_ \r\n_______ __\r\n__ _\r\nS____S _____ __\r\n__SS\r\n\r\n \r\n \r\n \r\n __ \r\n ________ S__S _ __S\r\nS__\r\n\r\nS_____ \r\n S __\r\n\r\n ___ __ \r\nS__ \r\n _\r\n S__ __S_ __ ______ S___ S____ \r\n\r\n__ \r\n _ __ _\r\n__ S__S SS_\r\n__S\r\n\r\n S\r\n __SS_ _\r\n \r\n ____\r\n_ \r\n\r\n_ S\r\n \r\n\r\n \r\n _______S\r\n_\r\n SS\r\n__SS\r\nSSS\r\n S _S__ S\r\nS\r\n___S_ ____\r\n\r\n__ __S_ _ ___\r\n _\r\n__\r\n__S\r\n\r\n___S__ _ ___ __S\r\n \r\n \r\n__S S \r\n\r\n __ _S_S \r\n \r\n__\r\nS _ \r\n_____ S __ ____\r\n \r\n SS_ __ \r\n S__S S __ ___ \r\n _\r\n \r\n__ \r\nS __S__\r\n __\r\n __\r\n\r\nS\r\n_\r\n\r\n __ SS\r\nSS \r\n __SS _SS\r\n__ \r\n S S__\r\n\r\nS\r\n\r\n _ S S_S_ S_______\r\n\r\nSS__\r\n SS_____\r\n_ S __ S\r\n_SSS\r\n \r\nS__ S__ SS \r\n_S__ \r\n__S _\r\n__\r\n \r\n S\r\n SSSS_ SS ___\r\n__ _ \r\n S\r\nS_____\r\nS__ S\r\n__ S S___\r\n\r\n_ ____ S__\r\n S ____S__S ___\r\nS__ S\r\n _ __SS\r\n S_ \r\n_____SSS\r\n__ ____ __S_______ ____S _ SS\r\n____SS _\r\n__S _ S__ _S_\r\n__ _S\r\n __\r\n\r\nS\r\n __ _ S\r\nS __ __ ___ __ _ \r\n_ ___\r\n ______ S__S__S\r\n_ S __ S\r\n____ S\r\n__ _\r\n \r\n \r\n_ ___S___\r\nS _ \r\n___\r\n__ __\r\n _S_ _SS__ S_ _ ____\r\n _S_ _S _______ _ ____S_ S_ S__ S_____ \r\n__ S__\r\n_ SS S__S S S___S__ S__ \r\n__ \r\n \r\n____\r\n__\r\n _ \r\n \r\n__\r\n_\r\n SS _S\r\n____ __S_______ \r\n\r\nS\r\n __\r\nS S \r\n ___SS_ _ _ S __\r\n SS S ____ S _S \r\n \r\n____S\r\n\r\n S___ S _ S S__ __\r\n__S ___SSS_______ ____ S S S \r\n S \r\n _S S_ S\r\n \r\n__S \r\n _\r\n ___ __S___ _ S _\r\n _S____ S____\r\n S_ \r\n\r\nS__ S __ \r\n _ \r\nS\r\nS __S\r\n___S_S __S ___SS_S__ _ __ \r\n\r\n__ _ _SS\r\nS_S__\r\n __ \r\n_\r\nS__ SSSS ___ __\r\n__ SS_____ S\r\nS_\r\nS__\r\n \r\n________\r\n __ _ ___SS __S_\r\n \r\n ____S __ __ \r\n _____ \r\n_ S S___ S__ \r\n ___\r\n\r\n_\r\n__ \r\n S\r\n __S _ \r\n_\r\n \r\n ___ ___S _ \r\n__ S__ S\r\n\r\nS\r\nS\r\n \r\n__ S\r\n __S\r\n ___ \r\n__ \r\n \r\n __S_____\r\n\r\n \r\n___SS \r\n__ \r\nS___ \r\n___\r\nS______\r\n___\r\nS_ \r\nS__S_SSS _ _\r\n _SS_\r\n \r\nS \r\n \r\n\r\n____\r\n_S_ S_\r\n \r\n____ _ __ _\r\n_\r\n______ __\r\n_____ __\r\n__ S _S__ \r\nS __ S \r\n\r\n__\r\n_\r\n\r\n S \r\nS\r\n_ \r\n _____ _SS __S__ \r\n\r\n \r\n___ \r\n")); +Console.WriteLine(Md.Render("some text")); diff --git a/cs/Markdown/Rules/BoldRule.cs b/cs/Markdown/Rules/BoldRule.cs index 8d35dcd31..63604598d 100644 --- a/cs/Markdown/Rules/BoldRule.cs +++ b/cs/Markdown/Rules/BoldRule.cs @@ -9,6 +9,8 @@ public class BoldRule : IRule private bool isItalicInStart; private bool isItalicInMiddle; private bool isTagClosed; + private readonly int[] italicStartsInBoldState = [10, 12]; + private readonly int boldStartsInItalicState = 9; private int currentState; public TagKind MoveByRule(char ch, int position) @@ -44,7 +46,7 @@ public TagKind MoveByRule(char ch, int position) isTagClosed = true; } - else if (currentState == 9) + else if (currentState == boldStartsInItalicState) { if (isItalicInMiddle) { @@ -59,7 +61,7 @@ public TagKind MoveByRule(char ch, int position) isItalicInStart = !isItalicInStart; } } - else if (currentState == 10 || currentState == 12) + else if (italicStartsInBoldState.Contains(currentState)) { if (isItalicInStart) { diff --git a/cs/Markdown/Rules/ItalicRule.cs b/cs/Markdown/Rules/ItalicRule.cs index 425e64cd7..f81a9ad6e 100644 --- a/cs/Markdown/Rules/ItalicRule.cs +++ b/cs/Markdown/Rules/ItalicRule.cs @@ -9,6 +9,9 @@ public class ItalicRule : IRule private bool isBoldInMiddle; private bool isBoldInStart; private bool isTagClosed; + private readonly int anotherStartState = 18; + private readonly int italicStartsInBoldState = 7; + private readonly int boldStartsInItalicState = 10; private int currentState; public TagKind MoveByRule(char ch, int position) @@ -28,7 +31,7 @@ public TagKind MoveByRule(char ch, int position) ClearTokens(); } - if (currentState == 17 || currentState == 18) + if (currentState == tag.InputStateNumber || currentState == anotherStartState) { tokens.Add(new Token.Token(tag.MdView, tag.Head, position - tag.MdView.Length)); } @@ -44,7 +47,7 @@ public TagKind MoveByRule(char ch, int position) } isTagClosed = true; } - else if (currentState == 10) + else if (currentState == boldStartsInItalicState) { if (isBoldInMiddle) { @@ -59,7 +62,7 @@ public TagKind MoveByRule(char ch, int position) isBoldInStart = !isBoldInStart; } } - else if (currentState == 7) + else if (currentState == italicStartsInBoldState) { if (isBoldInStart) { diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index fee4663a3..1ee32339f 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -1,7 +1,4 @@ -using System.Collections; -using System.ComponentModel.Design; -using System.Data; -using Markdown.Rule; +using Markdown.Rule; using Markdown.Tags; using Markdown.Token; @@ -36,18 +33,6 @@ public List GetTokens(string text) var skip = 0; while (textPointer != text.Length) { - //if (textPointer == 5837) - //{ - // var p = text[5835..5840]; - // //var pe = text[741..750]; - // var z4 = text[5836]; - // var z = text[5837]; - // var z1 = text[5838]; - // var z2 = text[5839]; - // var z3 = text[5840]; - // Console.WriteLine(); - //} - if (skip != 0) { skip--; diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs index 04de4e247..3fb9fffac 100644 --- a/cs/Markdown/Tags/BoldTag.cs +++ b/cs/Markdown/Tags/BoldTag.cs @@ -51,7 +51,7 @@ public static Dictionary> InitialzeStates() states[1].Add(SymbolStatus.underscore, 2); states[1].Add(SymbolStatus.eof, 0); states[1].Add(SymbolStatus.newline, 0); - states[1].Add(SymbolStatus.space, 0); // ? + states[1].Add(SymbolStatus.space, 0); states[1].Add(SymbolStatus.anotherSymbol, 9); // Tag Open diff --git a/cs/Markdown/Tags/ItalicTextTag.cs b/cs/Markdown/Tags/ItalicTextTag.cs index e95014348..e7d80a54d 100644 --- a/cs/Markdown/Tags/ItalicTextTag.cs +++ b/cs/Markdown/Tags/ItalicTextTag.cs @@ -9,7 +9,7 @@ public class ItalicTextTag : ITag public string Tail => ""; public string MdView => "_"; - public int InputStateNumber { get; } = 1; + public int InputStateNumber { get; } = 17; public int OutputStateNumber { get; } = 12; public Dictionary> States { get; } = InitialzeStates(); @@ -45,13 +45,13 @@ public static Dictionary> InitialzeStates() states.Add(17, new Dictionary()); states.Add(18, new Dictionary()); - states[0].Add(SymbolStatus.text, 13); // 0 + states[0].Add(SymbolStatus.text, 13); states[0].Add(SymbolStatus.digit, 0); states[0].Add(SymbolStatus.underscore, 1); states[0].Add(SymbolStatus.eof, 0); states[0].Add(SymbolStatus.newline, 0); states[0].Add(SymbolStatus.space, 0); - states[0].Add(SymbolStatus.anotherSymbol, 13); // 0 + states[0].Add(SymbolStatus.anotherSymbol, 13); states[1].Add(SymbolStatus.text, 17); states[1].Add(SymbolStatus.digit, 0); diff --git a/cs/Markdown/Tags/TagType.cs b/cs/Markdown/Tags/TagType.cs deleted file mode 100644 index 62b32b39b..000000000 --- a/cs/Markdown/Tags/TagType.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Markdown.Tags; - -public enum TagType -{ - None, - Header, - ItalicText, - BoldText, - Escape -} \ No newline at end of file diff --git a/cs/MarkdownTests/MarkdownSpeedTest.cs b/cs/MarkdownTests/MarkdownSpeedTest.cs index f17045531..865fea906 100644 --- a/cs/MarkdownTests/MarkdownSpeedTest.cs +++ b/cs/MarkdownTests/MarkdownSpeedTest.cs @@ -14,12 +14,10 @@ public void Render_ShouldWorkFast() var sw = new Stopwatch(); var results = new List(); - for (var length = 640; length <= 512 * 10; length *= 2) + for (var length = 640; length <= 51200; length *= 2) { var text = GetRandomString(length); sw.Start(); - Console.WriteLine("----------------------------"); - Console.WriteLine(text); Md.Render(text); sw.Stop(); results.Add(sw.Elapsed); diff --git a/cs/MarkdownTests/MarkdownTest.cs b/cs/MarkdownTests/MarkdownTest.cs index ecba77d66..0204d5302 100644 --- a/cs/MarkdownTests/MarkdownTest.cs +++ b/cs/MarkdownTests/MarkdownTest.cs @@ -52,7 +52,8 @@ public static IEnumerable ItalicAndBoldTestCases yield return new TestCaseData("a_bad_", "abad").SetName("italics opens in the middle closes at the end"); yield return new TestCaseData("__bold _ab_ad bold__", "bold abad bold") .SetName("italic opens at the beginning closes in the middle inside bold"); - + yield return new TestCaseData("_a123_", "_a123_").SetName("italic not works with digit"); + yield return new TestCaseData("__a123__", "__a123__").SetName("bold not works with digit"); } } From d5ed0a0689e9e95ea799b6acd3ec040b206a8736 Mon Sep 17 00:00:00 2001 From: Leonid Date: Mon, 2 Dec 2024 11:27:10 +0500 Subject: [PATCH 14/15] small refactor --- cs/Markdown/Rules/BoldRule.cs | 6 +++--- cs/Markdown/Rules/EscapeRule.cs | 2 +- cs/Markdown/Rules/H1Rule.cs | 2 +- cs/Markdown/Rules/IRule.cs | 2 +- cs/Markdown/Rules/ItalicRule.cs | 4 ++-- cs/Markdown/TagParser.cs | 12 ++++++------ cs/Markdown/Tags/BoldTag.cs | 4 +--- cs/Markdown/Tags/H1Tag.cs | 4 +--- cs/Markdown/Tags/ItalicTextTag.cs | 5 +---- cs/Markdown/Token/IToken.cs | 4 +--- cs/MarkdownTests/MarkdownSpeedTest.cs | 2 +- 11 files changed, 19 insertions(+), 28 deletions(-) diff --git a/cs/Markdown/Rules/BoldRule.cs b/cs/Markdown/Rules/BoldRule.cs index 63604598d..7b8ed5f54 100644 --- a/cs/Markdown/Rules/BoldRule.cs +++ b/cs/Markdown/Rules/BoldRule.cs @@ -1,6 +1,6 @@ using Markdown.Tags; -namespace Markdown.Rule; +namespace Markdown.Rules; public class BoldRule : IRule { @@ -75,10 +75,10 @@ public TagKind MoveByRule(char ch, int position) { isItalicInMiddle = !isItalicInMiddle; } - + } - if (isTagClosed && ((!isItalicInMiddle && !isItalicInStart) || symbol == SymbolStatus.eof)) + if (isTagClosed && (!isItalicInMiddle && !isItalicInStart || symbol == SymbolStatus.eof)) { isTagClosed = false; currentState = 0; diff --git a/cs/Markdown/Rules/EscapeRule.cs b/cs/Markdown/Rules/EscapeRule.cs index 3d6386228..d7ea5dbf8 100644 --- a/cs/Markdown/Rules/EscapeRule.cs +++ b/cs/Markdown/Rules/EscapeRule.cs @@ -1,6 +1,6 @@ using Markdown.Tags; -namespace Markdown.Rule; +namespace Markdown.Rules; public class EscapeRule : IRule { diff --git a/cs/Markdown/Rules/H1Rule.cs b/cs/Markdown/Rules/H1Rule.cs index 61e77a45c..29b49f6c3 100644 --- a/cs/Markdown/Rules/H1Rule.cs +++ b/cs/Markdown/Rules/H1Rule.cs @@ -1,6 +1,6 @@ using Markdown.Tags; -namespace Markdown.Rule; +namespace Markdown.Rules; public class H1Rule : IRule { diff --git a/cs/Markdown/Rules/IRule.cs b/cs/Markdown/Rules/IRule.cs index fd844f832..2d10c51f6 100644 --- a/cs/Markdown/Rules/IRule.cs +++ b/cs/Markdown/Rules/IRule.cs @@ -1,6 +1,6 @@ using Markdown.Tags; -namespace Markdown.Rule; +namespace Markdown.Rules; public interface IRule { diff --git a/cs/Markdown/Rules/ItalicRule.cs b/cs/Markdown/Rules/ItalicRule.cs index f81a9ad6e..406a98d0c 100644 --- a/cs/Markdown/Rules/ItalicRule.cs +++ b/cs/Markdown/Rules/ItalicRule.cs @@ -1,6 +1,6 @@ using Markdown.Tags; -namespace Markdown.Rule; +namespace Markdown.Rules; public class ItalicRule : IRule { @@ -71,7 +71,7 @@ public TagKind MoveByRule(char ch, int position) isTagClosed = false; currentState = 0; tokens.Clear(); - + } else { diff --git a/cs/Markdown/TagParser.cs b/cs/Markdown/TagParser.cs index 1ee32339f..c5c971e76 100644 --- a/cs/Markdown/TagParser.cs +++ b/cs/Markdown/TagParser.cs @@ -1,4 +1,4 @@ -using Markdown.Rule; +using Markdown.Rules; using Markdown.Tags; using Markdown.Token; @@ -13,7 +13,7 @@ public class TagParser new H1Rule() ]; - private IRule EscapeRule = new EscapeRule(); + private EscapeRule escapeRule = new(); public bool TryGoNextSymbol(int textPointer, string text) { @@ -39,19 +39,19 @@ public List GetTokens(string text) } else { - var res = EscapeRule.MoveByRule(text[textPointer], textPointer); + var res = escapeRule.MoveByRule(text[textPointer], textPointer); if (res == TagKind.Open) { if (TryGoNextSymbol(textPointer, text)) { textPointer++; - res = EscapeRule.MoveByRule(text[textPointer], textPointer); + res = escapeRule.MoveByRule(text[textPointer], textPointer); if (res == TagKind.Close) { - tokens.AddRange(EscapeRule.GetTokens()); - EscapeRule.ClearTokens(); + tokens.AddRange(escapeRule.GetTokens()); + escapeRule.ClearTokens(); if (text[textPointer] == '\\') { textPointer--; diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs index 3fb9fffac..9da763d8a 100644 --- a/cs/Markdown/Tags/BoldTag.cs +++ b/cs/Markdown/Tags/BoldTag.cs @@ -1,6 +1,4 @@ -using Markdown.Tags; - -namespace Markdown.Tags; +namespace Markdown.Tags; public class BoldTag : ITag { diff --git a/cs/Markdown/Tags/H1Tag.cs b/cs/Markdown/Tags/H1Tag.cs index 9bf10f61a..405f08c28 100644 --- a/cs/Markdown/Tags/H1Tag.cs +++ b/cs/Markdown/Tags/H1Tag.cs @@ -1,6 +1,4 @@ -using Markdown.Tags; - -namespace Markdown.Tags; +namespace Markdown.Tags; public class H1Tag : ITag { diff --git a/cs/Markdown/Tags/ItalicTextTag.cs b/cs/Markdown/Tags/ItalicTextTag.cs index e7d80a54d..41c64f692 100644 --- a/cs/Markdown/Tags/ItalicTextTag.cs +++ b/cs/Markdown/Tags/ItalicTextTag.cs @@ -1,7 +1,4 @@ -using Markdown.Tags; -using Microsoft.VisualBasic; - -namespace Markdown.Tags; +namespace Markdown.Tags; public class ItalicTextTag : ITag { diff --git a/cs/Markdown/Token/IToken.cs b/cs/Markdown/Token/IToken.cs index 87e6e67da..65541815f 100644 --- a/cs/Markdown/Token/IToken.cs +++ b/cs/Markdown/Token/IToken.cs @@ -1,6 +1,4 @@ -using Markdown.Tags; - -namespace Markdown.Token; +namespace Markdown.Token; public interface IToken { diff --git a/cs/MarkdownTests/MarkdownSpeedTest.cs b/cs/MarkdownTests/MarkdownSpeedTest.cs index 865fea906..8a5392a1f 100644 --- a/cs/MarkdownTests/MarkdownSpeedTest.cs +++ b/cs/MarkdownTests/MarkdownSpeedTest.cs @@ -14,7 +14,7 @@ public void Render_ShouldWorkFast() var sw = new Stopwatch(); var results = new List(); - for (var length = 640; length <= 51200; length *= 2) + for (var length = 640; length <= 5120; length *= 2) { var text = GetRandomString(length); sw.Start(); From ea13850d47db8afdccac9733e8a8af90ef63f652 Mon Sep 17 00:00:00 2001 From: Leonid Date: Mon, 2 Dec 2024 19:53:00 +0500 Subject: [PATCH 15/15] small fix bold tag --- cs/Markdown/Program.cs | 2 +- cs/Markdown/Rules/BoldRule.cs | 5 +++++ cs/Markdown/Tags/BoldTag.cs | 11 ++++++++++- cs/MarkdownTests/MarkdownTest.cs | 2 ++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs index 7c04bd2a6..6e1c6f14c 100644 --- a/cs/Markdown/Program.cs +++ b/cs/Markdown/Program.cs @@ -1,3 +1,3 @@ using Markdown; -Console.WriteLine(Md.Render("some text")); +Console.WriteLine(Md.Render("__test _ _markdown_ text__ another text")); diff --git a/cs/Markdown/Rules/BoldRule.cs b/cs/Markdown/Rules/BoldRule.cs index 7b8ed5f54..d866406e5 100644 --- a/cs/Markdown/Rules/BoldRule.cs +++ b/cs/Markdown/Rules/BoldRule.cs @@ -11,6 +11,7 @@ public class BoldRule : IRule private bool isTagClosed; private readonly int[] italicStartsInBoldState = [10, 12]; private readonly int boldStartsInItalicState = 9; + private readonly int fakeItalicStartState = 13; private int currentState; public TagKind MoveByRule(char ch, int position) @@ -77,6 +78,10 @@ public TagKind MoveByRule(char ch, int position) } } + else if (currentState == fakeItalicStartState) + { + isItalicInMiddle = !isItalicInMiddle; + } if (isTagClosed && (!isItalicInMiddle && !isItalicInStart || symbol == SymbolStatus.eof)) { diff --git a/cs/Markdown/Tags/BoldTag.cs b/cs/Markdown/Tags/BoldTag.cs index 9da763d8a..97430c6af 100644 --- a/cs/Markdown/Tags/BoldTag.cs +++ b/cs/Markdown/Tags/BoldTag.cs @@ -35,6 +35,7 @@ public static Dictionary> InitialzeStates() states.Add(10, new Dictionary()); states.Add(11, new Dictionary()); states.Add(12, new Dictionary()); + states.Add(13, new Dictionary()); states[0].Add(SymbolStatus.text, 0); states[0].Add(SymbolStatus.digit, 0); @@ -142,9 +143,17 @@ public static Dictionary> InitialzeStates() states[12].Add(SymbolStatus.underscore, 12); states[12].Add(SymbolStatus.eof, 0); states[12].Add(SymbolStatus.newline, 0); - states[12].Add(SymbolStatus.space, 5); + states[12].Add(SymbolStatus.space, 13); states[12].Add(SymbolStatus.anotherSymbol, 4); + states[13].Add(SymbolStatus.text, 6); + states[13].Add(SymbolStatus.digit, 0); + states[13].Add(SymbolStatus.underscore, 12); + states[13].Add(SymbolStatus.eof, 0); + states[13].Add(SymbolStatus.newline, 0); + states[13].Add(SymbolStatus.space, 5); + states[13].Add(SymbolStatus.anotherSymbol, 6); + return states; } } \ No newline at end of file diff --git a/cs/MarkdownTests/MarkdownTest.cs b/cs/MarkdownTests/MarkdownTest.cs index 0204d5302..1b63ea59b 100644 --- a/cs/MarkdownTests/MarkdownTest.cs +++ b/cs/MarkdownTests/MarkdownTest.cs @@ -54,6 +54,8 @@ public static IEnumerable ItalicAndBoldTestCases .SetName("italic opens at the beginning closes in the middle inside bold"); yield return new TestCaseData("_a123_", "_a123_").SetName("italic not works with digit"); yield return new TestCaseData("__a123__", "__a123__").SetName("bold not works with digit"); + yield return new TestCaseData("__test _ _markdown_ text__ another text", "test _ markdown text another text") + .SetName("underscore and space is not opening tag"); } }