Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Вильданов Савелий #226

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions cs/Markdown/Converter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Text;

namespace Markdown;

public class Converter
{
public string ConvertWithTokens(List<Token> tokens)
{
StringBuilder result = new();

foreach (var token in tokens)
{
result.Append(token.Context);
}

return result.ToString();
}
}
10 changes: 10 additions & 0 deletions cs/Markdown/ListOfTokens.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Markdown;

public class ListOfTokens<T> : List<T>
{
public new void Add(T token)
{
if(!(token is null))
base.Add(token);
}
}
10 changes: 10 additions & 0 deletions cs/Markdown/Markdown.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
12 changes: 12 additions & 0 deletions cs/Markdown/Md.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Markdown;

public class Md
{
public static string Render(string markdown)
{
Preparator preparator = new Preparator();
Converter converter = new Converter();
preparator.Paragrapher(markdown);
return converter.ConvertWithTokens(preparator.GetTokens());
}
}
99 changes: 99 additions & 0 deletions cs/Markdown/Parsers/BoldParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System.Collections;
using Markdown.TagsType;

namespace Markdown.Parsers;

public class BoldParser
{
private readonly Stack<Token> tagsStack;
private readonly GeneralParser.IsValidTag isValidOpenBoldTag;
private readonly GeneralParser.IsValidTag isValidCloseBoldTag;
private readonly GeneralParser.AddInsert addBoldTag;
public bool IsHaveInsideBoldTag;
public static bool IsBoldClosed;
private int index;

public BoldParser()
{
IsBoldClosed = true;
IsHaveInsideBoldTag = false;
tagsStack = GeneralParser.tagsStack;
addBoldTag = GeneralParser.AddInsideTag;
isValidOpenBoldTag = GeneralParser.IsValidOpenTag;
isValidCloseBoldTag = GeneralParser.IsValidCloserTag;
index = 0;
}

public Token BoldParse(string text, int i)
{
index = i;
index++;

if (i != 0 && i != text.Length - 2)
IsHaveInsideBoldTag = true;
if (IsEmptyStringInsideBold(text, i))
{
index = text.Length;
return new Token("____");
}

if (IsBoldClosed)
{
if (!isValidOpenBoldTag(text, i+1))
{
return (new Token("__"));
}
}
else
{
if (!isValidCloseBoldTag(text, i))
{
return new Token("__");
}
}


if (tagsStack.Count > 1 &&
tagsStack.Any(p => p.Type is {MarkdownTag: "_"}) &&
tagsStack.Peek().Type is {MarkdownTag: "__"})
{
tagsStack.Pop();
}
if (!IsBoldClosed && i == text.Length - 1)
{
tagsStack.Pop();
}
var boldTag = addBoldTag(new BoldTag(), IsBoldClosed);
IsBoldClosed = !IsBoldClosed;


return boldTag;
}

public bool IsNextSymbolBold(string text, int i)
{
var nextIndex = i + 1;
if (nextIndex < text.Length)
{
if (text[nextIndex] == '_')
{
return true;
}
}

return false;
}

public int GetNewIndex() => index;

private bool IsEmptyStringInsideBold(string text, int i)
{
int nextIndex = i + 1;
if (nextIndex < text.Length - 2 && IsNextSymbolBold(text, nextIndex))
{
return true;
}

return false;
}
}
59 changes: 59 additions & 0 deletions cs/Markdown/Parsers/GeneralParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Markdown.TagsType;

namespace Markdown.Parsers;

public static class GeneralParser
{
public static Stack<Token> tagsStack = new();

public delegate Token AddInsert(ITagsType tags, bool isClose);

public delegate bool IsValidTag(string text, int index);

public static Token AddInsideTag(ITagsType tag, bool isClose)
{
var result = GenerateTagToken(tag, isClose);
if (!isClose && tagsStack.Count != 0 && tagsStack.Peek().Type?.MarkdownTag == tag.MarkdownTag)
ClosePairTag(tagsStack.Pop());
return result;
}

public static Token GenerateTagToken(ITagsType tag, bool isClose)
{
if (isClose)
{
var temp = new Token(tag.GetHtmlOpenTag(), tag);
tagsStack.Push(temp);
return temp;
}

if (tagsStack.Count != 0 && tagsStack.Peek().Type?.MarkdownTag == tag.MarkdownTag)
tag.HasPair = true;
return new Token(tag.GetHtmlCloseTag(), tag);
}

public static void ClosePairTag(Token token)
{
if (token.Type != null) token.Type.HasPair = true;
}

public static bool IsValidCloserTag(string text, int index)
{
if (index == 0)
return false;
if (index > 0 && text[index - 1] == ' ')
return false;

return true;
}

public static bool IsValidOpenTag(string text, int index)
{
if (index == text.Length - 1)
return false;
if (index < text.Length - 1 && text[index + 1] == ' ')
return false;

return true;
}
}
58 changes: 58 additions & 0 deletions cs/Markdown/Parsers/ItalicParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Markdown.TagsType;

namespace Markdown.Parsers;

public class ItalicParser
{
private readonly GeneralParser.IsValidTag isValidOpenItalicTag;
private readonly GeneralParser.IsValidTag isValidCloseItalicTag;
private readonly GeneralParser.AddInsert addItalicTag;
private bool isItalicClosed;
private readonly Stack<Token> tagsStack;
public bool IsHaveInsideItalicTag;


public ItalicParser()
{
isItalicClosed = true;
tagsStack = GeneralParser.tagsStack;
addItalicTag = GeneralParser.AddInsideTag;
isValidOpenItalicTag = GeneralParser.IsValidOpenTag;
isValidCloseItalicTag = GeneralParser.IsValidCloserTag;
IsHaveInsideItalicTag = false;
}

public Token ItalicParse(string text, int i)
{
if (i != 0 && i != text.Length - 1)
IsHaveInsideItalicTag = true;
if (isItalicClosed)
{
if (!isValidOpenItalicTag(text, i))
{
return new Token("_");
}
}
else
{
if (!isValidCloseItalicTag(text, i))
{
return new Token("_");
}
}

if (tagsStack.Count > 1 && !isItalicClosed && BoldParser.IsBoldClosed)
{
tagsStack.Pop();
}

var result = addItalicTag(new ItalicTag(), isItalicClosed);
isItalicClosed = !isItalicClosed;
if (!isItalicClosed && i == text.Length - 1)
{
tagsStack.Pop();
}

return result;
}
}
51 changes: 51 additions & 0 deletions cs/Markdown/Parsers/LinkParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System.Net.Mime;
using System.Text;
using Markdown.TagsType;

namespace Markdown.Parsers;

public class LinkParser
{
private LinkTag linkTag;
private StringBuilder nameOfLink;
private StringBuilder urlOfLink;
public bool IsThisLink;

public LinkParser()
{
linkTag = new LinkTag();
nameOfLink = new StringBuilder();
urlOfLink = new StringBuilder();
}

public Token LinkParse(string text)
{
IsThisLink = true;
for (int i = 0; i < text.Length; i++)
{
switch (text[i])
{
case '[':
break;
case ']':
linkTag.LinkName = nameOfLink.ToString();
linkTag.LinkUrl = text.Substring(i + 2, text.Length - i - 3);
return GenerateLinkToken();
default:
nameOfLink.Append(text[i]);
break;
}
}

nameOfLink.Append(' ');
return null!;
}

private Token GenerateLinkToken()
{
var context = linkTag.GetHtmlOpenTag() + linkTag.LinkUrl + "\">" + linkTag.LinkName + linkTag.GetHtmlCloseTag();
urlOfLink.Clear();
nameOfLink.Clear();
return new Token(context, linkTag);
}
}
40 changes: 40 additions & 0 deletions cs/Markdown/Parsers/SlashParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Markdown.TagsType;

namespace Markdown.Parsers;

public class SlashParser
{

private int Index;

public SlashParser()
{
Index = 0;
}
public Token QuotedToken(string text, int i, bool isNextSymbolBold)
{
i++;
Index = i;
if (Index < text.Length)
{
switch (text[Index])
{
case '_':
if (Index + 1 < text.Length && isNextSymbolBold)
{
Index++;
return new Token(new BoldTag().MarkdownTag);
}
return new Token(new ItalicTag().MarkdownTag);
case '#':
return new Token(new HeadingTag().MarkdownTag);
}
}

Index--;
return new Token("\\");
}

public int GetIndex() => Index;

}
Loading