Skip to content
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

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

Open
Cyanss opened this issue Dec 12, 2023 · 0 comments

Comments

@Cyanss
Copy link

Cyanss commented Dec 12, 2023

测试 如下:

:::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;

        ……
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant