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

Regarding the issue of conflicts caused by the simultaneous use of markdown-it-container and markdown-it-attrs #153

Open
Cyanss opened this issue Dec 12, 2023 · 1 comment

Comments

@Cyanss
Copy link

Cyanss commented Dec 12, 2023

Example input:

:::column {.column-container}

column test1 {.column-1}

:::

Current output:

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

Expected output:

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

When not using 'markdown-it-container' output:

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

After testing, it was found that it was due to the nesting of container_column_closewill be set -1 When the markdown-it-container adding the div container for column-container

markdown-it-container index.mjs#L123

    ……

    state.lineMax = nextLine

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

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

123 >   const token_c  = state.push('container_' + name + '_close', 'div', -1)
    token_c.markup = state.src.slice(start, pos)
    token_c.block  = true

    ……

According to the official documentation of markdown-it, there is no problem with this setting

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

But when using both markdown-it-container and markdown-it-attrs at the same time,markdown-it-attrs traverses to find the container_div_close node, due to the newly added container of container_column_close node also satisfies the condition that nesting === -1, which will result in the style column-1 that should have been added to column test1 being added to the parent container of column container.

markdown-it-attrs patterns.js#L327

    ……

    {
      /**
       * 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' && t !== 'math_inline'
            }
          ]
        }
      ],
      transform: (tokens, i, j) => {
        const token = tokens[i].children[j];
        const content = token.content;
        const attrs = utils.getAttrs(content, content.lastIndexOf(options.leftDelimiter), options);
        let ii = i + 1;
327 >        while (tokens[ii + 1] && tokens[ii + 1].nesting === -1) { ii++; }
        const openingToken = utils.getMatchingOpeningToken(tokens, ii);
        utils.addAttrs(attrs, openingToken);
        const trimmed = content.slice(0, content.lastIndexOf(options.leftDelimiter));
        token.content = last(trimmed) !== ' ' ?
          trimmed : trimmed.slice(0, -1);
      }
    }
      
    ……

Other related issues:

# 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]

Possible issues caused by this reason:

# 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.]

The temporary solution to this problem is to modify the code. As I am currently using the locally installed from NPM, I can modify the code in const token_c = state.push('container_' + name + '_close', 'div', -1) to temporarily use const token_c = state.push('container_' + name + '_close', 'div', -2). However, this may cause unknown and unpredictable bugs in the markdown-it-container. Here are the reasons for the problem and temporary solutions, hoping for a more professional solution.

Temporary solution:

modify the markdown-it-container index.mjs#L123 code

    ……

    state.lineMax = nextLine

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

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

123 >   const token_c  = state.push('container_' + name + '_close', 'div', -2)
    token_c.markup = state.src.slice(start, pos)
    token_c.block  = true

    ……

The above is what I wrote using translation tools, hoping to understand it,

This problem was discovered during my use of nodeppt, hope it can be helpful.

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

@arve0
Copy link
Owner

arve0 commented Dec 12, 2023

Thanks for the detailed report 👍 I don’t have the bandwidth to look into this right now, but might sometime later.

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

2 participants