2

On the surface, this question appears similar to How to add custom image tag to pagedown? However, in practice, I think the solution will take a very different form.

With PageDown, you can add an <img> tag to a text block two different ways:

![MY IMAGE](http://myurl.com/myimage.png)
<img src='myimage.png'>

Looking at the code, the first approach is handled in _DoImages in Markdown.Converter.js, creating an <img> tag with the appropriate information contained within it. The second approach is handled in sanitizeHtml (which calls sanitizeTag and uses img_white) in Markdown.Sanitizer.js.

All I want to add is that every single <img> tag that successfully passes through the Markdown has a CSS class added to it (e.g., "user-img").

So, for example, <img src='myimg.png' width='100' height'100'> would become <img src='myimg.png' width='100' height='100' class='user-img'>

Examining how Pagedown is structured, I think it would make the most sense to have this functionality added as a "plugin hook" operating at the "postConversion" stage, in my own code (i.e., i wouldn't have to change anything in Pagedown). In pseudo-code, I think the code changes to my code would look something like this:

init function:

this.converter = Markdown.getSanitizingConverter();
this.converter.hooks.chain("postConversion", userifyImages);

userifyImages(html_text):

// note: `html_text` is just a plain string
for every <img> tag that still exists (i.e., is valid) in html_text:
    add "class='user-img'" to the tag

I'm guessing that there is a relatively simple regex to be constructed based upon that rule, but I'm afraid that I've failed to deduce one.

So I have two questions:

(1) Do you think this approach makes sense, considering how Pagedown is structured?

(2) Do you know how I might create a regex that does the manipulation I'm requiring? (or, of course, solve the problem without the use of a regex.)

Thank you for your time.

Community
  • 1
  • 1
a.real.human.being
  • 878
  • 2
  • 6
  • 17

3 Answers3

1

Okay, basing my approach on Pagedown's existing code, this seems to work fine.

function identifyImages(html) {

    function sanitizeImageTag(tag) {
        // chops off the last char in the string ('>') and replaces it
        // with the class name we want to add
        if ( tag.match(/^<img.*>$/i) ) {
            return tag.slice(0,tag.length-1) + " class=\"user-img\">";
        }
        else {
            return tag;
        }
    }

    return html.replace(/<[^>]*>?/gi, sanitizeImageTag);
}

this.converter = Markdown.getSanitizingConverter();
this.converterhooks.chain("postConversion",identifyImages);

However, I'm not overly comfortable with the regular expression: /<[^>]*>?/gi. I'm not sure what exactly the ? is doing there. Nevertheless, this appears to work.

a.real.human.being
  • 878
  • 2
  • 6
  • 17
0

Assuming that html_text is an HTML DOM, this should work:

var ilist = html_text.images;

for(var i = 0; i < ilist.length; i++) {
    ilist[i].className += "user-img") 
}
Edward
  • 6,964
  • 2
  • 29
  • 55
  • Hi Edward. Unfortunately, no, it's just a plain ol' string (updated the question to reflect that). – a.real.human.being Jan 17 '14 at 16:59
  • Perhaps you can create a DOM using DOMParser() and then save it back. Admittedly, this may not be the most efficient method, but it's likely to require less code writing from you, and it should be fairly robust. See [this question](http://stackoverflow.com/questions/3103962/converting-html-string-into-dom-elements?lq=1) for details. – Edward Jan 17 '14 at 18:38
  • Yeah, I'd certainly prefer a solution that doesn't require me to convert a string to DOM elements and then back to a string again. I agree with you that such an approach is quite inefficient. – a.real.human.being Jan 17 '14 at 18:44
0

I wanted to add a class to individual images. This is how I did it:

  var converter = new Markdown.Converter();

  converter.hooks.chain('postSpanGamut', function (text) {
    var matches = text.match(/\{(\S*)\}/);
    if (matches) {
      text = text.replace(matches[0], '');
      text = text.replace(/\/>/, 'class="' + matches[1] + '" />');
    }
    return text;
  });

This allows for this syntax to work:

![{my-class}cute kitties!](http://placekitten.com/g/200/200)

which spits out

<img src="http://placekitten.com/g/200/200" alt="cute kittes!" class="my-class">

You could probably make the regex around { } more accurate.

devkaoru
  • 1,142
  • 9
  • 7