From e3124e2791cc84d22817fe2f67d4c92800739343 Mon Sep 17 00:00:00 2001 From: zufuliu Date: Sat, 2 Nov 2024 08:13:15 +0800 Subject: [PATCH] [Markdown] Highlight hard line breaks, issue #900. --- scintilla/include/SciLexer.h | 1 + scintilla/include/SciLexer.iface | 1 + scintilla/lexers/LexMarkdown.cxx | 26 +++++++++++++++++--------- src/EditLexers/EditStyle.h | 1 + src/EditLexers/EditStyleX.h | 1 + src/EditLexers/stlMarkdown.cpp | 1 + 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/scintilla/include/SciLexer.h b/scintilla/include/SciLexer.h index 70714e3511..ed21ba922b 100644 --- a/scintilla/include/SciLexer.h +++ b/scintilla/include/SciLexer.h @@ -1091,6 +1091,7 @@ #define SCE_MARKDOWN_DIFF_ADD_SQUARE 93 #define SCE_MARKDOWN_DIFF_DEL_CURLY 94 #define SCE_MARKDOWN_DIFF_DEL_SQUARE 95 +#define SCE_MARKDOWN_HARD_LINE_BREAK 96 #define SCE_AHK_DEFAULT 0 #define SCE_AHK_COMMENTLINE 1 #define SCE_AHK_SECTION_COMMENT 2 diff --git a/scintilla/include/SciLexer.iface b/scintilla/include/SciLexer.iface index 92505486b2..6b161e6eb9 100644 --- a/scintilla/include/SciLexer.iface +++ b/scintilla/include/SciLexer.iface @@ -2014,6 +2014,7 @@ val SCE_MARKDOWN_DIFF_ADD_CURLY= val SCE_MARKDOWN_DIFF_ADD_SQUARE= val SCE_MARKDOWN_DIFF_DEL_CURLY= val SCE_MARKDOWN_DIFF_DEL_SQUARE= +val SCE_MARKDOWN_HARD_LINE_BREAK= # Lexical state for SCLEX_TXT2TAGS #lex Txt2tags=SCLEX_TXT2TAGS SCE_TXT2TAGS_ #val SCE_TXT2TAGS_DEFAULT=0 diff --git a/scintilla/lexers/LexMarkdown.cxx b/scintilla/lexers/LexMarkdown.cxx index e6bfb785b7..c08b519905 100644 --- a/scintilla/lexers/LexMarkdown.cxx +++ b/scintilla/lexers/LexMarkdown.cxx @@ -297,7 +297,7 @@ struct MarkdownLexer { } int HighlightBlockText(uint32_t lineState); - void HighlightInlineText(); + void HighlightInlineText(int visibleChars = 0); HtmlTagType CheckHtmlBlockTag(Sci_PositionU pos, Sci_PositionU endPos, int chNext, bool paragraph) const noexcept; bool HandleHtmlTag(HtmlTagType tagType); @@ -310,7 +310,7 @@ struct MarkdownLexer { bool IsIndentedBlockEnd() const noexcept; int GetCurrentDelimiterRun(DelimiterRun &delimiterRun, bool ignoreCurrent = false) const noexcept; - SeekStatus HighlightEmphasis(uint32_t lineState); + SeekStatus HighlightEmphasis(uint32_t lineState, int visibleChars); SeekStatus HighlightCodeSpan(uint32_t lineState); SeekStatus HighlightLinkText(uint32_t lineState); @@ -739,7 +739,7 @@ constexpr uint8_t GetEmphasisDelimiter(int state) noexcept { } } -SeekStatus MarkdownLexer::HighlightEmphasis(uint32_t lineState) { +SeekStatus MarkdownLexer::HighlightEmphasis(uint32_t lineState, int visibleChars) { HighlightResult result = HighlightResult::None; const int current = sc.state; const int delimiter = GetEmphasisDelimiter(current); @@ -803,7 +803,7 @@ SeekStatus MarkdownLexer::HighlightEmphasis(uint32_t lineState) { return SeekStatus::Continue; } - HighlightInlineText(); + HighlightInlineText(visibleChars); return SeekStatus::None; } @@ -1597,7 +1597,7 @@ int MarkdownLexer::HighlightBlockText(uint32_t lineState) { return 0; } -void MarkdownLexer::HighlightInlineText() { +void MarkdownLexer::HighlightInlineText(int visibleChars) { bool handled = false; const int current = sc.state; switch (sc.ch) { @@ -1741,6 +1741,14 @@ void MarkdownLexer::HighlightInlineText() { } if (handled || current != sc.state) { SaveOuterStyle(current); + } else if (visibleChars != 0 + && (current == SCE_MARKDOWN_DEFAULT || (current >= SCE_MARKDOWN_EM_ASTERISK && current <= SCE_MARKDOWN_STRIKEOUT)) + && ((sc.ch == '\\' && IsEOLChar(sc.chNext)) || (sc.Match(' ', ' ') && IsEOLChar(sc.GetRelative(2))))) { + sc.SetState(SCE_MARKDOWN_HARD_LINE_BREAK); + if (sc.ch == ' ') { + sc.Forward(); + } + sc.ForwardSetState(current); } else if (bracketCount == 0) { DetectAutoLink(); } @@ -2071,7 +2079,7 @@ void ColouriseMarkdownDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int in case SCE_MARKDOWN_INLINE_MATH: { SeekStatus status; if (sc.state < SCE_MARKDOWN_LINK_TEXT) { - status = lexer.HighlightEmphasis(lineState); + status = lexer.HighlightEmphasis(lineState, visibleChars); } else if (sc.state == SCE_MARKDOWN_LINK_TEXT) { status = lexer.HighlightLinkText(lineState); } else if (sc.state < SCE_MARKDOWN_CODE_SPAN) { @@ -2363,8 +2371,8 @@ void ColouriseMarkdownDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int in } if (sc.state == SCE_MARKDOWN_DEFAULT) { - if (sc.ch > ' ') { - if (visibleBefore == 0) { + if (sc.ch >= ' ') { + if (sc.ch > ' ' && visibleBefore == 0) { if (indentCurrent != indentPrevious) { lexer.UpdateParentIndentCount(indentCurrent); } @@ -2382,7 +2390,7 @@ void ColouriseMarkdownDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int in } } if (sc.state == SCE_MARKDOWN_DEFAULT) { - lexer.HighlightInlineText(); + lexer.HighlightInlineText(visibleChars); } } } diff --git a/src/EditLexers/EditStyle.h b/src/EditLexers/EditStyle.h index 1473d3ddba..d84a8982f5 100644 --- a/src/EditLexers/EditStyle.h +++ b/src/EditLexers/EditStyle.h @@ -194,6 +194,7 @@ #define NP2STYLE_Parameter 63603 #define NP2STYLE_InlineExpansion 63604 #define NP2STYLE_Pragma 63605 +#define NP2STYLE_HardLineBreak 63606 #define NP2STYLE_Section 63611 #define NP2STYLE_Assignment 63612 diff --git a/src/EditLexers/EditStyleX.h b/src/EditLexers/EditStyleX.h index d219f699de..8780b5eed4 100644 --- a/src/EditLexers/EditStyleX.h +++ b/src/EditLexers/EditStyleX.h @@ -217,6 +217,7 @@ #define NP2StyleX_Parameter EDITSTYLE_HOLE(Parameter, L"Parameter") #define NP2StyleX_InlineExpansion EDITSTYLE_HOLE(InlineExpansion, L"Inline Expansion") #define NP2StyleX_Pragma EDITSTYLE_HOLE(Pragma, L"Pragma") +#define NP2StyleX_HardLineBreak EDITSTYLE_HOLE(HardLineBreak, L"Hard Line Break") #define NP2StyleX_Section EDITSTYLE_HOLE(Section, L"Section") #define NP2StyleX_Assignment EDITSTYLE_HOLE(Assignment, L"Assignment") diff --git a/src/EditLexers/stlMarkdown.cpp b/src/EditLexers/stlMarkdown.cpp index 84a1d94990..cd0570e951 100644 --- a/src/EditLexers/stlMarkdown.cpp +++ b/src/EditLexers/stlMarkdown.cpp @@ -43,6 +43,7 @@ static EDITSTYLE Styles_Markdown[] = { { SCE_MARKDOWN_DELIMITER, NP2StyleX_Delimiter, L"bold; fore:#0080C0" }, { SCE_MARKDOWN_EMOJI, NP2StyleX_Emoji, L"fore:#FF8000" }, { SCE_MARKDOWN_ESCAPECHAR, NP2StyleX_EscapeSequence, L"fore:#0080C0" }, + { SCE_MARKDOWN_HARD_LINE_BREAK, NP2StyleX_HardLineBreak, L"fore:#C80000; back:#FFFF80" }, { MULTI_STYLE(SCE_MARKDOWN_DIFF_ADD_CURLY, SCE_MARKDOWN_DIFF_ADD_SQUARE, 0, 0), NP2StyleX_LineAddition, L"back:#80FF80" }, { MULTI_STYLE(SCE_MARKDOWN_DIFF_DEL_CURLY, SCE_MARKDOWN_DIFF_DEL_SQUARE, 0, 0), NP2StyleX_LineRemoval, L"back:#FF8080" }, };