-
Notifications
You must be signed in to change notification settings - Fork 300
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
Рыбин Леонид #236
base: master
Are you sure you want to change the base?
Рыбин Леонид #236
Conversation
cs/Markdown/Tokenizer.cs
Outdated
public class Tokenizer | ||
{ | ||
private Stack<BoldToken> boldTokens; | ||
private Stack<ItalicToken> italicTokens; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Представь, что у нас в будущем появиться ещё больше стилей - получается под каждый стиль нужно будет свою коллекцию заводить...
А хотелось бы, чтобы ты просто создавал новый класс токена, что-то в нём описал и передавал этот класс в парсер, а оно более-менее автоматически заводилось.
cs/Markdown/Tokens/PairToken.cs
Outdated
|
||
public bool IsClosed { get; set; } | ||
public int Position { get; set; } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Как мне кажется, у тебя перемешалась логика токена и тэга:
Класс тэга должен содержать в себе символ тэга, тип, открывающий/закрывающий элемент html.
Класс токена должен содержать в себе исходную строку, преобразованную строку, возможно, позицию.
Идея такая - ты создаешь парсер со списком тэгов, которые он должен обрабатывать/искать, а потом вызываешь метод, в котором передаешь текст, а он тебе возвращает найденные токены. В найденных токенах нас интересует уже готовый "преобразованный" текст.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Я специально не разделял тэг и токен, потому что я вижу работу парсера так:
Парсер идёт по строке, парсер увидел что символ или группа символов подходят под какой-то тип токена (заголовок, курсив и так далее), после этого он добавляет этот токен в общий список токенов(метод Tokenizer), а после при генерации HTML(метод GenerateHtml) токены будут заменяться на тэги, при этом каждый токен уже сам знает на что его заменить и где его заменить. Если же разделить тэги и токены, то процесс замены токена на тэг усложниться, так как появиться дополнительная логика в методе генерации HTML.
cs/Markdown/Md.cs
Outdated
|
||
private string RenderCurrentString(string line) | ||
{ | ||
var tokenizer = new Tokenizer(line); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
У тебя пока не написана логика, поэтому можешь сказать своё видение, какие токены вернуться для этой строки:
# Hello _world,_ Leo!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В начале строки мы видим "# " поэтому добавляется HeaderToken(HtmlView = <h1>), потом "_" добавляет ItalicToken(HtmlView = <em>), после мы видим "_", но уже закрывающий, благодаря стэкам мы понимаем какой это тип(закрывающий или открывающий), поэтому добавиться ItalicToken(HtmlView = </em>) и наконец мы дойдём до конца строки, поскольку в стэке будет открывающий HeaderToken, то необходимо добавить HeaderToken(HtmlView = </h1>).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Так-с, т.е. в этой строке нам придет список токенов, условно говоря, "какой тэг и в какой позиции".
Я вижу тут 2 проблемы:
- Если вдруг понадобиться поддержать тэг <h2> (у него признак окончания тоже конец строки) - такой алгоритм позволит это сделать?
- Могут возникнуть сложности при сборке итоговой html-строки из-за смещения позиций: т.е. ты запомнил, что в позиции 9 должен начаться курсив, а в итоговой строке это уже не позиция 9, т.к. "# " мы заменили на "<h1>".
cs/Markdown/Tags/TagType.cs
Outdated
@@ -0,0 +1,9 @@ | |||
namespace Markdown.Tags; | |||
|
|||
public enum TagType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Кажется этот enum-чик лишним, т.к. у тебя уже есть разные реализации ITag
- они и отражают тип тэга.
cs/Markdown/Md.cs
Outdated
|
||
public class Md | ||
{ | ||
private readonly List<ITag> availableTags = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Можно всё это статическим сделать - и класс, и этот список.
cs/Markdown/TagParser.cs
Outdated
|
||
public class TagParser | ||
{ | ||
private readonly List<(Stack<ITag>, TagType)> TagsOrder; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Чёт пока сложно как-то тут и непонятно, как это использовать: вроде это должен быть список List<ITag> tags
, который наш парсер будет уметь распознавать и уметь конвертировать.
Т.е. чтобы тебе до конца понять, как это ты будешь использовать - необходим какой-то псевдокод, набросочек public List<IToken> GetTokens(string text)
.
|
||
namespace Markdown.Token; | ||
|
||
public interface IToken |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Почему интерфейс? Какие реализации будут?
public string Render(string text) | ||
{ | ||
var parser = new TagParser(availableTags); | ||
return GenerateHtml(text, parser.GetTokens(text)); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ну если про GetTokens говорить, то он возращает, что-то такое:
"# ", <h1>, position = 0
"_", <em>, position = 8
А GenerateHtml пробегает по тексту и меняет в нужной позиции символы на HTML тэги, при этом у него может быть глобальный сдвиг, чтобы позиции символов оставались актуальными
yield return new TestCaseData("_\\a_", "<em>\\a</em>").SetName("does not escape the letter"); | ||
yield return new TestCaseData("_a\\_", "_a_").SetName("shielded closing tag"); | ||
yield return new TestCaseData("\\__a_", "_<em>a</em>").SetName("shields the bold turning into italic"); | ||
yield return new TestCaseData("__test \\_ _markdown_ text__ another text", "<strong>test _ <em>markdown</em> text</strong> another text") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Если убрать слэши, то тест вроде как всё равно должен проходить, но не проходит, почему?
|
||
private EscapeRule escapeRule = new(); | ||
|
||
public bool TryGoNextSymbol(int textPointer, string text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Статический метод
new H1Rule() | ||
]; | ||
|
||
private EscapeRule escapeRule = new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
readonly
|
||
public class TagParser | ||
{ | ||
private List<IRule> Rules = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
readonly
@@ -0,0 +1,15 @@ | |||
namespace Markdown; | |||
|
|||
public enum SymbolStatus |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
По код-стайлу обычно enum-чики с большой буквы именуются
Даже в каких-нить системных майкрософтовских либах так сделано
No description provided.