Skip to content
This repository was archived by the owner on Feb 20, 2025. It is now read-only.
This repository was archived by the owner on Feb 20, 2025. It is now read-only.

关于同时使用markdown-it-container和markdown-it-attrs导致冲突的问题 #311

@Cyanss

Description

@Cyanss

测试 如下:

:::column {.column-container}

column test1 {.column-1}

---

column test2 {.column-2}

:::

输出:

<div class="column-container column-2 grid">
<div class="column column-1">
<p>column test1 </p>
</div>
<div class="column">
<p>column test2 </p>
</div>
</div>

预期输出:

<div class="column-container grid">
<div class="column column-1">
<p>column test1 </p>
</div>
<div class="column column-2">
<p>column test2 </p>
</div>
</div>

不使用markdown-it-container时:

<p class="column-container">::::::column </p>
<p class="column-1">column test1 </p>
<hr />
<p class="column-2">column test2 </p>
<p>::::::</p>

经过测试发现是由于markdown-it-container在添加column-container父容器Token时,默认会将container_column _closenesting设置为-1.

container.js#147

        ……

        state.lineMax = nextLine;

        token = state.push('container_' + name + '_open', 'div', 1);
        token.markup = markup;
        token.block = true;
        token.info = params;
        token.map = [startLine, nextLine];

        // 修正
        let len = state.tokens.length - startLine;

        state.md.block.tokenize(state, startLine + 1, nextLine);

147 >   token = state.push('container_' + name + '_close', 'div', -1);
        token.markup = state.src.slice(start, pos);
        token.block = true;
        token.info = params;

        ……

这是按照markdown-it的官方文档设置的,原本是没有问题的。

markdown-it token nesting

  /**
   * Token#nesting -> Number
   *
   * Level change (number in {-1, 0, 1} set), where:
   *
   * -  `1` means the tag is opening
   * -  `0` means the tag is self-closing
   * - `-1` means the tag is closing
   **/
  this.nesting  = nesting

当同时使用markdown-it-containermarkdown-it-attrs时,markdown-it-attrs在遍历寻找container_div _close时由于新添加的容器的container_column _close节点同样满足条件nesting等于-1的条件,这就会导致本来应该添加到column test2上的样式column-2会添加到column-container的父容器上。

patterns.js#475

         ……

         {
            /**
             * end of {.block}
             */
            name: 'end of block',
            tests: [
                {
                    shift: 0,
                    type: 'inline',
                    children: [
                        {
                            position: -1,
                            content: utils.hasDelimiters('end', options),
                            type: t => t !== 'code_inline'
                        }
                    ]
                }
            ],
            transform: (tokens, i, j) => {
                let token = tokens[i].children[j];
                let content = token.content;
                let attrs = utils.getAttrs(content, content.lastIndexOf(options.leftDelimiter), options);
                let ii = i + 1;
475 >           while (tokens[ii + 1] && tokens[ii + 1].nesting === -1) {
                    ii++;
                }
>               let openingToken = utils.getMatchingOpeningToken(tokens, ii);
                utils.addAttrs(attrs, openingToken);
                let trimmed = content.slice(0, content.lastIndexOf(options.leftDelimiter));
                token.content = last(trimmed) !== ' ' ? trimmed : trimmed.slice(0, -1);
            }
        }
      
       ……

经过对markdown-it-containermarkdown-it-attrs两个组件的Issue查询,发现二者官方也没有对这个问题进行有效的解决。

# markdown-it-container issue#39 [Incompatibility with markdown-it-attrs]

# markdown-it-attrs issue#111 [Propagation of Attributes in Markdown-it-container]

# markdown-it-attrs issue#72 [Conflict with markdown-it-container]

可能因为这个原因导致的问题:

# markdown-it-attrs issue#150 [Unable to apply attributes to the last column of tables.]

# markdown-it-attrs issue#142 [Last column attribute setting results unexpectedly.]

对于这个问题的临时解决方法, 由于我目前是使用的NPM本地安装的Nodeppt,可以修改container.js#147中的代码,将 token = state.push('container_' + name + '_close', 'div', -1);修改为 token = state.push('container_' + name + '_close', 'div', -2);暂时使用,但是可能会对markdown-it-containernodeppt产生未知无法预测的BUG,由于nodeppt项目更新时间久远,不知道作者是否还在维护这个项目,这里提供了问题的原因以及临时解决方法,希望能有更专业的解决方案。

临时解决方法:

修改container.js#147代码

        ……

        state.lineMax = nextLine;

        token = state.push('container_' + name + '_open', 'div', 1);
        token.markup = markup;
        token.block = true;
        token.info = params;
        token.map = [startLine, nextLine];

        // 修正
        let len = state.tokens.length - startLine;

        state.md.block.tokenize(state, startLine + 1, nextLine);

147 >   token = state.push('container_' + name + '_close', 'div', -2);
        token.markup = state.src.slice(start, pos);
        token.block = true;
        token.info = params;

        ……

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions