Custom javascript not work in markdown

I tried to use my custom javascript to wrap all img in markdown with a figure tag… but it seems the Javascript is not used…

  1. set javascript

  2. javascript

// function to wrap all img tags in a figure tag if the img is not already wrapped in a figure tag
function wrapImages() {
    imgs = $('img');
    for (var i = 0; i < imgs.length; i++) {
        if ($(imgs[i]).parent().is('figure')) {
            // do nothing
        } else {
            $(imgs[i]).wrap('<figure></figure>');
        }
    }
}

document.addEventListener('DOMContentLoaded', function () {
    var script = document.createElement('script');
    script.type = "text/javascript";
    script.src = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js";
    // Add the script element to the DOM's <head> element
    document.head.insertAdjacentElement('beforeend', script);
    wrapImages();
})

You might want to convert your MD to HTML in DT, open the resulting HTML in your favorite browser and check what the browser’s developer console tells you about it.

Why are you even bothering with jQuery for this simplistic task? The following untested code doesn’t rely on this behemoth of olden times, should (well, it is untested) do what you want and does not require loading a huge amount of useless data every time it is executed. In addition, it gets rid of the useless empty if clause: The less code there is, the less can go awry.

document.addEventListener('DOMContentLoaded', function() {
  const imgs = document.querySelectorAll('img');
  for (let i = 0; i < imgs.length; i++) {
    const img = imgs[i];
    if (img.parentNode.tagName != 'FIGURE') {
       const figure = document.createElement('figure');
       figure.appendChild(img.cloneNode(true));
       img.replaceWith(figure);
    }
  }

Also, you might want to make sure your variables are declared with var, let or const depending on the needs. Your imgs not being declared at all pollutes the global namespace. var i in the for loop pollutes the namespace of wrapImages (let would be better here since it limits the scope of i to the loop). Also, there’s no need to declare var script since you do not change this value – const script would be better. That point is mute if you refrain from using JQuery.

  1. after convert MD to HTML in DT, there nothing happens. (jquery not introduced)
<link type="text/css" rel="stylesheet" href="file:///Users/xxx/markdown-theme/theme.css"/>
<script type="text/javascript" src="x-devonthink-item://FED3C98C-E1DB-48A8-9E45-1864131A7FED"></script>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>

and img tag not wrapped.

<img src="x-devonthink-item://971CB99F-4134-4625-A9AA-8133C2D0B6A0" alt="1" />
<img src="x-devonthink-item://2D2DD4D5-D719-4A3C-810B-D7A194B642C2" alt="2" />
  1. why I use jquery: I need to implement some complex function further.

Note: the .css file correctly loaded.

WFM (at least the inclusion of jQuery):


<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
...
<meta charset="utf-8">
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js"></script>

Frankly, there’s no point in posting isolated lines of HTML stuff here. You do not provide any useful context, you do not divulge if the developer console of your browser barfs about any errors.

If your code were correct, it would work (in the browser!). Since you claim that it does not work, you have to provide a lot more information than you do. I still believe that this has nothing to do at all with DT.

At least in other apps/browsers this can’t work as x-devonthink-item links work only inside DEVONthink in this case.

Sure. But the OP mentioned explicitly that they’re using that inside DT.

And what I proposed was to convert to HTML in DT and then open this HTML in the browser. It wouldn’t contain any x-devonthink-item reference anymore since that’s only used by DT to insert the Javascript verbatim into the HTML.

1 Like

Solved.
This is caused by incorrect jQuery position. (jQuery imported as the first script…)

But, there still some questions…

  1. It seems js file won’t work before we convert it to webAchieve (It not Convenient to preview the result.)

Nope. Although I must admit that I do not really understand what you’re saying here. In any case, a JavaScript script included in a MD file by DT works – if it is correct code. And it does work in pure HTML, having nothing todo with a WebArchive.

I don’t think that this is the reason of anything. In my case, I didn’t import jQuery as the first script.

If you really want go get help on that, you must provide more information. A complete (complete!) description of what you’re doing is one part of that.

In case that English is not your native language, you could use DeepL to translate from your language to it. That’s what other people do here, too.

Sorry for the confusing questions earlier. The following are steps to reproduce my problem:

  1. custom.js:
function addJQuery() {
    var head = document.getElementsByTagName('head')[0];
    var scriptjQuery = document.createElement( 'script' );
	scriptjQuery.type = 'text/javascript';
	scriptjQuery.id = 'jQuery'
	scriptjQuery.src = 'https://code.jquery.com/jquery-3.4.1.min.js';
	var script = document.getElementsByTagName( 'script' )[0];
	head.insertBefore(scriptjQuery, script);
}

addJQuery();
document.addEventListener('DOMContentLoaded', function () {
    wrapImages();
})


// function to wrap all img tags in a figure tag if the img is not already wrapped in a figure tag
function wrapImages() {
    let imgs = $('img');
    for (let i = 0; i < imgs.length; i++) {
        if ($(imgs[i]).parent().is('figure')) {
            // do nothing
        } else {
            var figcaption = document.createElement('figcaption');
            figcaption.textContent = $(imgs[i]).attr('alt');
            $(imgs[i]).wrap('<figure></figure>').parent().append(figcaption);
        }
    }
}
  1. test.md:
This is a note

![cccc]()
![cccc]()

What I get:

  1. MD in DT (Preview Not correct):

  2. Convert to HTML in DT (Not correct):

  3. Open the HTML in browser (Correct):

That is actually the interesting fact. Everything should (!) work fine in a real browser. That the source view of DT shows something different is irrelevant: That is not a developer console showing the live DOM. It’s just a source view of the document, the same as you get when looking at the source in the browser (not in the developer console).

You’re dynamically modifying the DOM. That’s fine, but you can’t expect these modifications to be visible anywhere but in a browser’s developer console.

And again: I would not use jQuery. There’s really no need for it anymore with current browsers. I doubt that there’s anything it does that you can’t do in plain JavaScript nowadays.

Thanks!
So how should I make operations on the DOM in js show up in markdown? (Why I need this: img is without a title, but figure is with a title. With js we can create custom class and then define new styles in css)

Converting to html every time and then opening it in the browser is very annoying.

I also know that some external Markdown editors can support js plugins, such as Typora, joplin, but they don’t work with x-devonthink-item links

I’m confused… Adding images to Markdown puts them in a figure already.

Are you just typing the image links?

1 Like

:+1 : :+1: :+1:

Indeed. Goodness. What a waste of time.

Not actually…. When you put two images in two line without a whitespace line(as shown in test.md)…then the img wont wrapped with figure tag…

Well, then put a line in between. What’s the problem with that?

Then it just avoid this problem, but not solve this problem. And add a white line destroys the document structure… two figures need the same parent. Then with css they can be shown in same line

You want to bend markdown to your display needs. You are of course at liberty to do as you wish, but that has nothing to do with DT, so it’s off-topic here.

DT is simply using the MultiMarkdown engine to produce HTML. That’s documented as is the behavior of this engine. So you have to minded off live with it or go with another markdown dialect and processor.

The JavaScript is smoke and mirrors for the rendering, i.e., it’s not inserting a figure element to the source of the document.

While many people will call this bad form, I say you can use the tools in ways that suit the need. So if you’re insistent on having a figure no matter what, MultiMarkdown supports using raw HTML provided there is a space before the enclosed Markdown elements as seen here.

And yes, my styling here is in-document. I do many one-off files and styling in the document is a quick and easy way to test (and learn) while iterating. Don’t judge me :stuck_out_tongue: