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

Add support for 'preserve' rules. #479

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

za3k
Copy link

@za3k za3k commented Jul 29, 2024

'preserve' is a little like 'keep', but it converts descendents to markdown.

An element which looks like this:

<div id="preserve-me">
    <b>some bolded text</b>
</div>

And with this rule added:

turndownService.preserve('div')

Will convert into this markdown:

<div id="preserve-me" markdown="1">
    **some bolded text**
</div>

Note that the results are not standard markdown. They require the use of the extended markdown="1" syntax.

'preserve' is a little like 'keep', but it converts descendents to markdown.

An element which looks like this:

    <div id="preserve-me">
        <b>some bolded text</b>
    </div>

And with this rule added:

    turndownService.preserve('div')

Will convert into this markdown:

    <div id="preserve-me" markdown="1">
        **some bolded text**
    </div>

Note that the results are not standard markdown. They require the use of the extended `markdown="1"` syntax.
@za3k
Copy link
Author

za3k commented Jul 29, 2024

I wrote this to get lighter output than provided by #448, which converts entire elements to HTML.

@martincizek
Copy link
Collaborator

martincizek commented Aug 2, 2024

Hey @za3k , thank you for your contribution. I agree with you that this is needed. And in our project that uses turndown, we have implemented the same like below. The isBlock branch is consistent with the default keepReplacement (like in your code) and I think the solution with shallow variant of cloneNode() is just more elegant and probably more efficient.

What do you think? And can you please check that the implementation below also works for you?

/**
 * An alternative implementation of the default `keep` replacement.
 * Preserves current element, but uses the GFM-rendered subtree content.
 */

/**
 * Shallow keep replacement. Ignores the attributes atm.
 * The default outerHTML approach is chosen for block elements.
 */
function shallowKeepReplacement(content, node) {
  if (node.isBlock) {
    return `\n\n${node.outerHTML}\n\n`;
  }
  const clone = node.cloneNode(false);
  return clone.outerHTML.replace('><', `>${content}<`);
}

module.exports = shallowKeepReplacement;

@za3k
Copy link
Author

za3k commented Aug 2, 2024

That replacement code is cleaner, I agree. Maybe innerHTML would work better than outerHTML, even?

I unfortunately am no longer in place to verify this easily. I just completed my own markdown conversion, so I'm no longer working on turndown. If you're using it, I assume it works.

Feel free to fork my PR and add a test demonstrating it works. I can merge your change into my own PR, if you're okay keeping the separate fourth rule type.

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

Successfully merging this pull request may close these issues.

2 participants