This is how to use Markdown inside HTML blocks

Steps

Add any non-reserved character (including any HTML inline elements) before your HTML code (all following lines have to be indented to remain in scope)

Examples

A table

<br><table>
	<tr>
		<td>[*Italic Link*](https://example.com)</td>
		<td>[*Italic Link*](https://example.com)</td>
	</tr>
	
	<tr>
		<td colspan=2>
		Area of a circle: $\pi r^2$
		</td>
	</tr>
</table>

An ordered list

<br><ol>
	<li>**Bold Text**</li>
	<li>[==Highlighted Link==](https://example.com)</li>
</ol>

Preview

Examples

Notes and Limitations

  • Any following lines have to be indented to remain in scope
  • All markdown block elements become inline (new lines are converted to space + 2 tabs)
  • New lines are not ignored
1 Like

Cool! This is nice trick. The explanation is that the codes above are part of one paragraph in markdown. The indentation (4 or more spaces) prevents html blocks and then any html tags in indented lines are interpreted as inline html content. Intended code blocks from 4 or more spaces are not triggered because these spaces are interpreted as part of a paragraph. The empty line in the first code is interesting—I’m not sure why it doesn’t trigger new paragraph.

Similarly <table> doesn’t begin html block because it is preceded by > and <br> doesn’t begin html block because it is followed by <. And </table> should begin html block that must be ended but I tested that you can also intend that final line ····</table>. Something strange might happen with <table> because it looks like creating a html block where content is parsed as html. Apparently that is documented in GitHub Flavored Markdown Spec but it’s complex and difficult to understand.

1 Like

This was actually a mistake in the post, I didn’t add it in the code which is previewed, however adding it makes no difference as long as that line has at least one indent

Here’s is what happens if that line has no indents

Also, all new lines (including lines which contain parts of the table’s code and including the <br>) are converted to empty div elements that are all added before the div containing the table

HTML Structure

HTML Structure

Yes thanks. Nested <table> inside <p> is what I expected originally. The question I raised is that why intended empty line is not treated as blank line that should terminate a paragraph according to GFM Spec. The GFM Spec clearly states that blank line is allowed to contain spaces and tabs—and no other details are provided—which implies a line containing both tabs and spaces but nothing else is treated as blank line as well.

You’re correct, that code with new line containing tabs doesn’t work like that on GitHub

image

This however doesn’t apply if there was Markdown in-between after the first new line, here is an example:

<h1>


[*Italic Link*](https://example.com)


[*Another Italic Link*](https://example.com)
</h1>


Anyways, Obsidian doesn’t strictly follow GFM, here is an example

I tested this on Obsidian and reading view produces blank <h1> and two <p>. In live preview one <h1> is produced without inline formatting. Obviously your trick can be used to achieve markdown in html elements (in reading view):

<hello><h1>
	[*Italic Link*](https://example.com)
	[*Another Italic Link*](https://example.com)
	</h1>

Do you have any practical use for it? For example markdown tables in Obsidian already support nested markdown.

I don’t currently have something in mind except using LaTeX and Obsidian internal links which can’t be used otherwise

This trick generally allows to use the easy markdown syntax within the advanced HTML

Thanks. It was nice to have discussion with you! Maybe later in future we can find proper use for additional html. Currently it is useful in templates since you don’t have to type the html code manually every time. Templates could include also inline templates. In theory inline html templates could implement some useful inline features such as interactive text or pictures—although we already have syntax for one click show/hide content using foldable callouts. Other very common use case is underlining but this could be replaced by strikethrough ~~text~~ or highlight ==text== with some proper CSS code. The need for using <u> tags or any similar inline formatting tags is not very real since you can use ~~text~~ and apply CSS to achieve any visual inline text appearance.

1 Like

You’re welcome! I’ve never used templates before, but I got to try them one day

If you’re talking about using HTML in Markdown notes in general rather than what this trick adds, then here are few things that HTML allows you to do while GFM can’t

Doesn’t work, I pasted your code into a new note, the markdown is not rendered

Just tested, you’re right… An update has made this broken, but it wasn’t an intentional feature to begin with

I see, thanks for confirming. It’s sad we can’t combine HTML with Markdown, I really wanted to use the metabind plugin in an html table, but since HTML goes separately, that really limits the amount of customization we can have.

Yes, it’s a considerable limitation…

1 Like

I use meta bind in html by rendering it through dataviewjs code blocks with dv.span etc. You can wrap them in html structure that then allows css styling, so i’ve made some flex and grid layouts with them. It’s finicky, usually because there’s formatting code blocks aren’t compatible with, but it lets me do a lot more of what I want. You can even reuse the same codeblock in multiple notes via embedding the note with the codeblock using a meta bind embed, which makes any input you interact with become attached to the page it’s being viewed/used on rather than the original page you’re embedding. Since it’s a dataviewjs block, you can combine it with javascript as well. I made a multi-column tracker section for my daily notes this way.

I do wish it was possible to use markdown in html right in the note though.

Heya…
Would you mind sharing a snippet of your code where you render html with meta bing inputs inside it and output it from dataviewjs?

I have been struggling with this for days…
I’ve tried it all:

  • native tables: can’t span rows
  • obsidian tables plugin: won’t render input fields
  • callouts are best bet, but they don’t work in live preview; I mean they do but the minute you click on them to enter values, obsidian puts you int source mode for the callout
  • multi-column css - same problem; it is callout based
  • obsidian columns plugin - held most promise. I used the code blocks. It seemed to work…but only in live preview; in reading mode they unload.

This is such a major pain in the ass. I am trying to create a ‘person template’ page, with 2 columns. One column has image, the other column has meta bind fields. Below all this is a free area to enter additional notes, as I do not wan to store loads of text into frontmatter, even though there is the meta bind text area, etc.

I am hoping for a crack in the shell of this problem, but I am just about to give up, and I really rather not…Thanks!

No problem! I don’t exactly have a public release with instructions and plug-n-play snippet at the moment since I’ve done quite a number of different layouts with reusable classes shared between them and ways of doing things that can get really complicated and I didn’t want to just infodump all of those things at once, so I made this simple, basic, quick one to get you started with how it works. Hopefully it remotely resembles what you’re going for!

Here’s what it looks like in a note:


(art from the delightful movie Secret of Kells)

Here’s the code block:

```dataviewjs
dv.span(`<span class="wrapper"><span class="column col1"><span class="img">\`INPUT[imageSuggester(optionQuery("")):imgProperty]\`</span></span><span class="column col2"><span class="col-item">\`INPUT[inlineListSuggester(option(apple), option(banana), option(lemon)):listProperty]\`</span><span class="col-item">\`INPUT[number:numProperty]\`</span><span class="col-item">\`INPUT[toggle:togProperty]\`</span></span></span>`,{cls:"columns-test"});
```

and here’s the css:

.columns-test .wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 15px;
}

.columns-test .column {
    display: flex;
    flex-direction: column;
    row-gap: 15px;
}

Here it is with the dev inspect tools highlighting the grid and flex areas so you can see how that’s working within the code block.

A couple things to make note of are the escaped backticks for the metabind inputs and that there aren’t any linebreaks. Also you can’t use any “block elements” in any of the html in the codeblock or markdown things stop working, inline elements only.

As I mentioned, you can do really interesting and complicated things and there’s all sorts of ways to do things, like styling the entire code block itself to be a grid or flex box instead of a span within the code block so that you can use multiple dv.elements instead of a single one.

Also, because having to write html with no line breaks for things can get wearisome, you can write small bits of it as js variables and then do things like dv.span(var1 + var2 + var3); or use interpolation

dv.span(`<span>${variable}</span>`);

instead.

Oh! Here is how I do them with labels, because that was one of the first things I hit. This allows you to create flex or grid within your rows so you can have the labels all be of equal size and they look better with lots of input

```dataviewjs
dv.span(`<span class="wrapper"><span class="column col1"><span class="img">\`INPUT[imageSuggester(optionQuery("")):imgProperty]\`</span></span><span class="column col2"><span class="col-item"><span class="label"><span class="text">List</span><span class="colon">:</span></span><span class="input">\`INPUT[inlineListSuggester(option(apple), option(banana), option(lemon)):listProperty]\`</span></span><span class="col-item"><span class="label"><span class="text">Number</span><span class="colon">:</span></span><span class="input">\`INPUT[number:numProperty]\`</span></span><span class="col-item"><span class="label"><span class="text">Toggle</span><span class="colon">:</span></span><span class="input">\`INPUT[toggle:togProperty]\`<span></span></span></span>`,{cls:"columns-test"});
```

I did the colon and text part separate because I usually use icons as labels and want them all to be the same size, you can just have them be a single part in the label if that works better for you. Here’s a pic of my three column trackers I used this method for. All the icons are internal links that can be hovered for a page preview which has a description for what the tracker is.

Hopefully this is enough to give you a start, especially as I’m not sure how familiar you are with html or css. I do recommend using more uncommon class names and/or making sure you always put the .columns-test (pick a unique name here) in front of any class names like .wrapper .column etc. like i used to avoid conflicts with anything else obsidian or other plugins are doing. Let me know if you have questions or get stuck!

Thank you @Graywaren for taking so much time to post such a detail post.
That was very helpful.
I took this approach and ran with it and used AI and some of my knowledge to tailor it to my needs. And it worked…till I hit a serious snag. I wonder if you came across it?

So the snag is when you use any meta bind where you write…text, textArea, etc. The minute you write a single character, it gets saved to the frontmatter, which triggers dataviewjs refresh, and you lose being positioned within the input text box. This is unusable.
It works in your example because the bind controls you used are simple click with poup and selection…not typing actual text.

I tried many things…I tried dataviewjs in a .js file being called by templater to insert into a new file…and anything like that obsidian won’t recognize the markup. I suppose dataviewjs is the only way.

I know one can also bind the fields to memory, and that does not trigger the refresh, but then those values get lost and not saved.

So either I have to figure out how to disable dataviewjs refresh, or save the meta bind fields into memory, and then…using some event (dunno where) save it into frontmatter in the end.

If any one has some tips, it would be greatly appreciated; I have been breaking my head with this for well over a week.

Cheers

Hi @MountainMan
I’ve been sick the past couple days, but finally was able to come back to answer your previous questions. Unfortunately it seems you deleted them. Feel free to repost if you still need help though.

As for your current snag, I don’t have that issue actually. I did see the same issue mentioned in Datacards recently though. I do however, think I know the cause/solution… at least I hope so.

Can you go into the settings for Dataview and check what your refresh interval is set to? I have mine set to “5500” because I have some lag issues and so I slowed down the refresh interval because I don’t mind waiting a bit for it to update in exchange for less general lag.

I think this setting is why I’m not running into the issue you’re having, because dataview is waiting 5.5 seconds after I stop typing in the meta bind text box to refresh and therefore kick the text box out of focus. I would suggest increasing your refresh interval and see if that fixes the problem. Hopefully you can increase it to where you can comfortably type without getting kicked out.

Of course if you’re typing something where you need to stop typing for a while regularly and not have the textbox lose focus, another solution may be warranted. It is possible to create a meta bind button that could either pop up the system input modal or use a modal form to get text input from the user and then bind that to a front matter property, but hopefully the interval thing will solve the issue without resorting to that.

Let me know if you need help with anything else or if the interval thing isn’t actually the solution. It might take me a day or two to figure it out or write up something, but if it takes more than that you can always ping me again.