Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
31 changes: 31 additions & 0 deletions cs/Markdown/Entities/Builders/HtmlBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Markdown.Models;
using Markdown.Models.SyntaxTreeModels;

namespace Markdown.Entities.Builders
{
/// <summary>
/// Преобразует абстрактное синтаксическое дерево (AST) в HTML-код.
/// Выполняет обход дерева в глубину и генерирует соответствующие HTML-теги для каждого узла.
/// </summary>
/// <param name="tree">Абстрактное синтаксическое дерево для преобразования</param>
/// <returns>HTML-код, соответствующий структуре исходного дерева</returns>
/// <remarks>
/// Для каждого типа узла AST генерирует соответствующий HTML-тег:
/// - Заголовки → h1, h2, etc.
/// - Жирный текст → strong
/// - Курсив → em
/// - Параграфы → p
/// </remarks>
public class HtmlBuilder : IBuilder
{
public string Build(ISyntaxTree tree)
{
throw new NotImplementedException();
}
}
}
20 changes: 20 additions & 0 deletions cs/Markdown/Entities/Builders/IBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Markdown.Models.SyntaxTree;
using Markdown.Models.SyntaxTreeModels;

namespace Markdown.Entities.Builders
{
/// <summary>
/// Преобразует абстрактное синтаксическое дерево (AST) в текст с новой разметкой.
/// </summary>
/// <param name="tree">Абстрактное синтаксическое дерево для преобразования</param>
/// <returns>Текст с измененной разметкой</returns>
public interface IBuilder
{
string Build(ISyntaxTree tree);
}
}
53 changes: 53 additions & 0 deletions cs/Markdown/Entities/Converters/Converter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Markdown.Entities.Builders;
using Markdown.Entities.Parsers;
using Markdown.Entities.Renderers;
using Markdown.Models;
using Markdown.Models.SyntaxTree;

namespace Markdown.Entities.Converters
{
/// <summary>
/// Выполняет полный цикл преобразования одного языка разметки в другой.
/// Координирует работу токенизатора и билдера.
/// Конструктор позволяет определить желаемый билдер и токенизатор под текущую задачу, например
/// в нашем случае токенизатор умеющий работать с markdown-разметкой а buidler который умеет строить
/// по синтаксическому дереву исходный текст с html-разметкой
/// </summary>
/// <param name="text">Исходный Markdown-текст</param>
/// <returns>Строка с HTML-разметкой</returns>
/// <remarks>
/// Последовательность преобразований:
/// 1. Токенизация исходного текста
/// 2. Построение абстрактного синтаксического дерева (AST)
/// 3. Рендеринг AST в HTML-формат
/// </remarks>
public class Converter : IConverter
{
public IBuilder Builder { get; }
public ITokenizer Tokenizer { get; }

public Converter(IBuilder builder, ITokenizer tokenizer)
{
Builder = builder;
Tokenizer = tokenizer;
}

public string Convert(string text)
{
if (Builder != null && Tokenizer != null)
{
var tokens = Tokenizer.Tokenize(text);
var ast = new SyntaxTree(tokens);
var convertedText = Builder.Build(ast);
return convertedText;
}

throw new NullReferenceException();
}
}
}
17 changes: 17 additions & 0 deletions cs/Markdown/Entities/Converters/IConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Markdown.Entities.Renderers
{
/// <summary>
/// Интерфейс для класса-конвертера который умеет конвертировать один язык разметки в другой, например конвертер из Markdown в HTML
/// <param name="text">Исходный текст с определенным языком разметки который хотим преобразовать</param>
/// </summary>
public interface IConverter
{
string Convert(string text);
}
}
24 changes: 24 additions & 0 deletions cs/Markdown/Entities/Tokenizers/ITokenizer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Markdown.Models;

namespace Markdown.Entities.Parsers
{
/// <summary>
/// Интерфейс для класса который будет заниматься преобразованием исходного текста в список токенов для дальнейшего построения синтаксического дерева.
/// Умеет преобразовывать как целый текст в набор токенов, так и обрабатывать коллекции отдельных строк превращая их в список токенов
/// </summary>
public interface ITokenizer
{
List<Token> Tokenize(string text);

List<string> TextToLines(string text);

List<Token> TokenizeLines(IEnumerable<string> lines);

List<Token> TokenizeLine(string line);
}
}
40 changes: 40 additions & 0 deletions cs/Markdown/Entities/Tokenizers/MarkdownTokenizer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Markdown.Models;

namespace Markdown.Entities.Parsers
{
/// <summary>
/// Tokenizer который работает с markdown текстом
/// </summary>
public class MarkdownTokenizer : ITokenizer
{
public List<Token> Tokenize(string text)
{
return TokenizeLines(TextToLines(text));
}

public List<string> TextToLines(string text)
{
return text.Split("\n").ToList();
}

public List<Token> TokenizeLines(IEnumerable<string> lines)
{
var tokens = new List<Token>();
foreach (var line in lines)
{
tokens.AddRange(TokenizeLine(line));
}
return tokens;
}

public List<Token> TokenizeLine(string line)
{
throw new NotImplementedException();
}
}
}
18 changes: 18 additions & 0 deletions cs/Markdown/Enums/NodeType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Markdown.Enums
{
public enum NodeType
{
Document,
Paragraph,
Header,
Bold,
Italic,
Text
}
}
22 changes: 22 additions & 0 deletions cs/Markdown/Enums/TokenType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Markdown.Enums
{
/// <summary>
/// <para>HeaderMarker = #</para>
/// <para>BoldMarker = __</para>
/// <para>ItalicsMarker = _</para>
/// </summary>
public enum TokenType
{
Text,
Newline,
HeaderMarker,
BoldMarker,
ItalicMarker
}
}
27 changes: 27 additions & 0 deletions cs/Markdown/Markdown.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Markdown.Entities.Builders;
using Markdown.Entities.Converters;
using Markdown.Entities.Parsers;
using Markdown.Models;

namespace markdown
{
/// <summary>
/// Преобразует Markdown-разметку в HTML-код.
/// Этот класс оставил, хотя в данный момент просто отдает строку преобразованную из Markdown в HTML, но тут можно развить реализацию дальше,
/// допустим если захотим выгружать текст куда-то или печатать на консоль то можем реализовывать логику обработки вывода здесь
/// </summary>
/// <remarks>
/// Принцип работы:
/// 1. Исходный текст разбивается на токены (лексемиы) с помощью <see cref="MarkdownTokenizer"/>
/// 2. Токены преобразуются в абстрактное синтаксическое дерево (AST) класса <see cref="SyntaxTree"/>
/// 3. Обходом графа AST полученное дерево превращается в текст с HTML с помощью <see cref="HtmlBuilder"/>
/// </remarks>
public class Markdown
{
public static string Render(string text)
{
var markdownConverter = new Converter(new HtmlBuilder(), new MarkdownTokenizer());
return markdownConverter.Convert(text);
}
}
}
14 changes: 14 additions & 0 deletions cs/Markdown/Markdown.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

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

<ItemGroup>
<Folder Include="MarkdownTests\" />
</ItemGroup>

</Project>
26 changes: 26 additions & 0 deletions cs/Markdown/Models/Node.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Markdown.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Markdown.Models
{
/// <summary>
/// Представляет узел абстрактного синтаксического дерева (AST)
/// </summary>
public class Node
{
public NodeType Type { get; }
public List<Node> ChildrenNodes { get; }
public string Value { get; }

public Node(NodeType type, List<Node> childrenNodes, string value)
{
Type = type;
ChildrenNodes = childrenNodes;
Value = value;
}
}
}
16 changes: 16 additions & 0 deletions cs/Markdown/Models/SyntaxTreeModels/ISyntaxTree.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Markdown.Models.SyntaxTreeModels
{
/// <summary>
/// Представляет абстрактное синтаксическое дерево (AST) документа
/// </summary>
public interface ISyntaxTree
{
public List<Node> Tree { get; }
}
}
28 changes: 28 additions & 0 deletions cs/Markdown/Models/SyntaxTreeModels/SyntaxTree.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Markdown.Models.SyntaxTreeModels;

namespace Markdown.Models.SyntaxTree
{
public class SyntaxTree : ISyntaxTree
{
/// <summary>
/// Коллекция корневых узлов абстрактного синтаксического дерева
/// </summary>
public List<Node> Tree { get; }

/// <summary>
/// Строит абстрактное синтаксическое дерево (AST) из потока токенов.
/// Анализирует последовательность токенов и создает иерархическую структуру узлов,
/// отражающую семантическую структуру исходного документа.
/// </summary>
/// <param name="tokens">Коллекция токенов, полученная от лексического анализатора</param>
public SyntaxTree(List<Token> tokens)
{
throw new NotImplementedException();
}
}
}
24 changes: 24 additions & 0 deletions cs/Markdown/Models/Token.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Markdown.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Markdown.Models
{
/// <summary>
/// Представляет лексему (токен), извлеченную в процессе лексического анализа
/// </summary>
public class Token
{
public TokenType Type { get; }
public string Value { get; }

public Token(TokenType type, string value = null)
{
Type = type;
Value = value;
}
}
}
Loading