Vim Markdown 高亮(列表项和代码块冲突)

发布于 2024-07-06 00:44:00 字数 2093 浏览 13 评论 0原文

我决定更多地了解 vim 及其语法突出显示。 使用其他人的示例,我正在为 Markdown 创建自己的语法文件。 我见过 mkd.vim 也有这个问题。 我的问题是列表项和代码块突出显示之间。

代码块定义

  • 第一行是空白
  • 第二行以至少4个空格或1个制表符开头
  • 块以空行结束

示例:

Regular text

    this is code, monospaced and left untouched by markdown
    another line of code

Regular Text

代码块的我的 Vim 语法:

syn match mkdCodeBlock   /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock  

hi link mkdCodeBlock  comment

Unorder List item definition

  • 第一行是空白
  • 第二行以 [-+*] 开头,后跟一个空格
  • 一个普通(非列表)行
  • 列表以空行结束,然后在行项目之间添加
  • 可以 添加任意数量的空行子列表是通过在列表项之后缩进(4 个空格或 1 个制表符)
  • 一行普通文本来指定的,作为该列表项的延续

示例:

Regular text

- item 1

    - sub item 1
    - sub item 2
- item 2
this is part of item 2
so is this


- item 3, still in the same list
    - sub item 1
    - sub item 2

Regular text, list ends above

我的无序列表项定义的 Vim 语法(我只突出显示 [- +*]):

syn region  mkdListItem start=/\s*[-*+]\s\+/ matchgroup=pdcListText end=".*" contained nextgroup=mkdListItem,mkdListSkipNL contains=@Spell skipnl 
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL skipnl

hi link mkdListItem  operator

我无法突出显示与列表的最后两条规则和代码块一起使用。

这是一个破坏我的语法突出显示的示例:

Regular text

- Item 1
- Item 2
part of item 2

    - these 2 line should be highlighted as a list item
    - but they are highlighted as a code block

我目前无法弄清楚如何让突出显示按照我想要的方式工作


忘记添加下面列出的两个规则中使用的“全局”语法规则。 这是为了确保它们以空行开头。

syn match mkdBlankLine   /^\s*\n/    nextgroup=mkdCodeBlock,mkdListItem transparent

另一个注释:我应该更清楚。 在我的语法文件中,列表规则出现在块引用规则之前


I decide to learn more about vim and its syntax highlighting.
Using examples for others, I am creating my own syntax file for Markdown. I have seen mkd.vim and it has this problem too.
My issue is between list items and code block highlighting.

Code Block definition:

  • first line is blank
  • second line begins with at least 4 spaces or 1 tab
  • block is finished with a blank line

Example:

Regular text

    this is code, monospaced and left untouched by markdown
    another line of code

Regular Text

My Vim syntax for code block:

syn match mkdCodeBlock   /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock  

hi link mkdCodeBlock  comment

Unorder List item definition:

  • first line is blank
  • second line begins with a [-+*] followed by a space
  • the list is finished with a blank line then a normal (non-list) line
  • in between line items any number of blank lines can be added
  • a sub list is specified by indenting (4 space or 1 tab)
  • a line of normal text after a list item is include as a continuation of that list item

Example:

Regular text

- item 1

    - sub item 1
    - sub item 2
- item 2
this is part of item 2
so is this


- item 3, still in the same list
    - sub item 1
    - sub item 2

Regular text, list ends above

My Vim syntax for unorder list item definition (I only highlight [-+*]):

syn region  mkdListItem start=/\s*[-*+]\s\+/ matchgroup=pdcListText end=".*" contained nextgroup=mkdListItem,mkdListSkipNL contains=@Spell skipnl 
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL skipnl

hi link mkdListItem  operator

I cannot get the highlighting to work with the last two rule for list and with a code block.

This is an example that breaks my syntax highlighting:

Regular text

- Item 1
- Item 2
part of item 2

    - these 2 line should be highlighted as a list item
    - but they are highlighted as a code block

I currently cannot figure out how to get the highlighting to work the way I want it too


Forgot to add a "global" syntax rule used in both rules listed below. It is to ensure a that they start with a blank line.

syn match mkdBlankLine   /^\s*\n/    nextgroup=mkdCodeBlock,mkdListItem transparent

Another Note: I should have been more clear. In my syntax file, the List rules appear before the Blockquote Rules


如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

堇年纸鸢 2024-07-13 00:44:00

Tai Zhyn,这可能涵盖了您的用例,但不涵盖 Markdown 语法。 在 Markdown 中,列表项可以包含代码块。 您可以在此处查看我的解决方案

TL;DR; 问题是 vim 不允许你说这样的话:一个与其容器具有相同缩进的块 + 4 个空格。 我找到的唯一解决方案是为每种缩进级别的列表项中包含的每种块生成规则(实际上我支持 42 级缩进,但它是任意数字)

所以我有 markdownCodeBlockInListItemAtLevel1 ,必须 包含在 markdownListItemAtLevel1 中并且需要至少有 8 个前导空格,然后 必须 包含在 markdownListItemAtLevel2 中的 markdownCodeBlockInListItemAtLevel2 必须至少包含在 markdownListItemAtLevel1 中10 个前导空格,ecc...

我知道几年过去了,但也许有人会认为这个答案很有帮助,因为所有基于缩进的语法都遇到同样的问题

Tao Zhyn, that maybe covers your use cases but it doesn't cover the Markdown syntax. In Markdown a list item could contain a code block. You could take a look at my solution here

TL;DR; the problem is that vim doesn't let you say something like: a block that have the same indentation as its container + 4 spaces. The only solution I found is to generate rules for each kind of blocks that could be contained in a list items for each level of indentation (actually I support 42 level of indentation but it's an arbitrary number)

So I have markdownCodeBlockInListItemAtLevel1 that must be contained in a markdownListItemAtLevel1 and it needs to have at least 8 leading spaces, an then markdownCodeBlockInListItemAtLevel2 that must be contained in a markdownListItemAtLevel2 that must be contained in a markdownListItemAtLevel1 ant needs to have at least 10 leading spaces, ecc...

I know that a few years have passed but maybe someone would consider this answer helpful since all syntax based on indentation suffers of the same problem

寂寞美少年 2024-07-13 00:44:00

hcs42 是正确的。 我确实记得现在读过该部分,但我忘记了,直到 hcs24 提醒我。

这是我更新的有效语法(其他一些调整):

"""""""""""""""""""""""""""""""""""""""
" Code Blocks:

"   Indent with at least 4 space or 1 tab
"   This rule must appear for mkdListItem, or highlighting gets messed up
syn match mkdCodeBlock   /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock  

"""""""""""""""""""""""""""""""""""""""
" Lists:

"   These first two rules need to be first or the highlighting will be
"   incorrect

"   Continue a list on the current line or next line
syn match mkdListCont /\s*[^-+*].*/ contained nextgroup=mkdListCont,mkdListItem,mkdListSkipNL contains=@Spell skipnl transparent

"   Skip empty lines
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL 

"   Unorder list
syn match  mkdListItem /\s*[-*+]\s\+/ contained nextgroup=mkdListSkipNL,mkdListCont  skipnl 

hcs42 was correct. I do remember reading that section now, but I forgot about it until hcs24 reminded me about it.

Here is my updated syntax (few other tweaks) that works:

"""""""""""""""""""""""""""""""""""""""
" Code Blocks:

"   Indent with at least 4 space or 1 tab
"   This rule must appear for mkdListItem, or highlighting gets messed up
syn match mkdCodeBlock   /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock  

"""""""""""""""""""""""""""""""""""""""
" Lists:

"   These first two rules need to be first or the highlighting will be
"   incorrect

"   Continue a list on the current line or next line
syn match mkdListCont /\s*[^-+*].*/ contained nextgroup=mkdListCont,mkdListItem,mkdListSkipNL contains=@Spell skipnl transparent

"   Skip empty lines
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL 

"   Unorder list
syn match  mkdListItem /\s*[-*+]\s\+/ contained nextgroup=mkdListSkipNL,mkdListCont  skipnl 
策马西风 2024-07-13 00:44:00

只需确保 mkdListItem 的定义位于 mkdCodeBlock 的定义之后,如下所示:

syn match mkdCodeBlock   /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock  
hi link mkdCodeBlock  comment

syn region  mkdListItem start=/\s*[-*+]\s\+/ matchgroup=pdcListText end=".*" contained nextgroup=mkdListItem,mkdListSkipNL contains=@Spell skipnl 
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL skipnl
hi link mkdListItem  operator

syn match mkdBlankLine   /^\s*\n/    nextgroup=mkdCodeBlock,mkdListItem transparent

Vim 文档在 :help :syn-define 中说道:

“如果多个项目在同一位置匹配,则一个是
定义了最后的胜利。 因此,您可以通过以下方式覆盖先前定义的语法项
使用与相同文本匹配的项目。 但关键字总是出现在
匹配或区域。 并且大小写匹配的关键字总是出现在
关键字忽略大小写。”

Just make sure that the definition of mkdListItem is after the definition of mkdCodeBlock, like this:

syn match mkdCodeBlock   /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock  
hi link mkdCodeBlock  comment

syn region  mkdListItem start=/\s*[-*+]\s\+/ matchgroup=pdcListText end=".*" contained nextgroup=mkdListItem,mkdListSkipNL contains=@Spell skipnl 
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL skipnl
hi link mkdListItem  operator

syn match mkdBlankLine   /^\s*\n/    nextgroup=mkdCodeBlock,mkdListItem transparent

Vim documentation says in :help :syn-define:

"In case more than one item matches at the same position, the one that was
defined LAST wins. Thus you can override previously defined syntax items by
using an item that matches the same text. But a keyword always goes before a
match or region. And a keyword with matching case always goes before a
keyword with ignoring case."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文