showdownjs / showdown

A bidirectional Markdown to HTML to Markdown converter written in Javascript
http://www.showdownjs.com/
MIT License
14.29k stars 1.57k forks source link

Auto-linking @mention from HTML to Markdown #910

Open brunoaugusto opened 2 years ago

brunoaugusto commented 2 years ago

I've created an editor in which the User can switch between a Rich Text version (Quill.js, if it matters) and Markdown and, in a Babel class, I've set up the Showdown like this:

this.showdown = new showdown.Converter({
  omitExtraWLInCodeBlocks: false,
  noHeaderId: true,
  simplifiedAutoLink: true,
  excludeTrailingPunctuationFromURLs: true,
  literalMidWordUnderscores: true,
  strikethrough: true,
  tables: false,
  ghCodeBlocks: true,
  tasklists: true,
  ghMentions: true,
  ghMentionsLink: '/perfil/?user={u}',
  smartIndentationFix: true,
  disableForced4SpacesIndentedSublists: true,
  simpleLineBreaks: false,
  requireSpaceBeforeHeadingText: true,
  encodeEmails: true
});

this.showdown.setFlavor( 'github' );

When conditions are met (i.e. the editor toggler is clicked) to parse the HTML from the Rich Text into the Markdown <textarea>, I have this:

return this.showdown.makeMarkdown( html );

And from Markdown to HTML, I have this:

return this.showdown.makeHtml( text );

text and html are method arguments to represent, as implied, Quill's HTML and Markdown Text

The problem I'm experiencing is that when converting to HTML it works perfectly, and I receive in my Quill Editor the <a> tag, but when going for Markdown I don't receive the (I suppose) [text](link) syntax.

I've isolated the code, out of my Quill implementation:

var showdown = new showdown.Converter({
  omitExtraWLInCodeBlocks: false,
  noHeaderId: true,
  simplifiedAutoLink: true,
  excludeTrailingPunctuationFromURLs: true,
  literalMidWordUnderscores: true,
  strikethrough: true,
  tables: false,
  ghCodeBlocks: true,
  tasklists: true,
  ghMentions: true,
  ghMentionsLink: '/perfil/?user={u}',
  smartIndentationFix: true,
  disableForced4SpacesIndentedSublists: true,
  simpleLineBreaks: false,
  requireSpaceBeforeHeadingText: true,
  encodeEmails: true
});

showdown.setFlavor( 'github' );

function toMarkdown( html ) {
  return showdown.makeMarkdown( html );
}

function toRichText( text ) {
  return showdown.makeHtml( text );
}

console.log( toRichText( '@brunoaugusto' ) );
console.log( toMarkdown( '@brunoaugusto' ) );

And the results were the same. That said, will Showdown not convert, for example, <p>@brunoaugusto</p> into [/perfil/?user=brunoaugusto](@brunoaugusto) or I've implemented the routine wrongly?

tivie commented 2 years ago

Hey. The option ghMentions, with the option ghMentionsLink /perfil/?user={u}, turns the markdown @some-user into html <a href="/perfil/?user=some-user">@some-user</a>.

So, the backconvertion should be turning html <a href="/perfil/?user=some-user">@some-user</a> back into @some-user (which is not implemented).

Right now, showdown will convert <a href="/perfil/?user=some-user">@some-user</a> into [@some-user](/perfil/?user=some-user), which it shouldn't.

You can check the behavior here: https://codepen.io/tivie/pen/zYpMWYq


I believe what you want is to convert html @some-user into md [@some-user](/perfil/?user=some-user) right?

brunoaugusto commented 2 years ago

I believe what you want is to convert html @some-user into md [@some-user](/perfil/?user=some-user) right?

Precisely! If I write a plain string in the Rich Text Editor prefixed with an @, I'd be passing down to Showdown something like <p>@brunoaugusto</p> and I'd like it to create the Markdown counterpart [/perfil/?user=brunoaugusto](@brunoaugusto) out of it so the flow between both editors would be seamless, back and forth I'd have the same results without losing data (especially because I send to the server the markdown, not the HTML).

It's would be really simple to workaround this with an auxiliary routine on my end, but I was really trying to avoid doing so, hehe.