Can anyone help me load obsidian.md files into the floating web view?

I've been trying for an hour but i'm getting nowhere.

Right now I'm using Zero-md but I can't get it to load the .md file at all.

What I'm trying to achieve is having a markdown file for each app I'm using and load my notes (tips, tricks, shortcuts I always forget) from obsidian for each one.

I've been trying to load

"/Users/james/Library/Mobile Documents/iCloud~md~obsidian/Documents/Obsidian Vault 2023/Keynote/QuickTips.md"

Ideally I'd be able to have part of the path name as a dynamically changing variable so I didn't have to make a separate script for each app.

If „floating“ is your main goal, you can also float the Obsidian window(s) with your notes.

Really? How? I'd want to float them rendered as html not as the markdown files though.

I have no idea what this means, but BTT can float almost any window with this predefined action. Maybe this also helps :slightly_smiling_face:

I'll post an example on how to load them in the webview later this weekend!
In general you can try to use localfile:///Users/james/Library/Mobile Documents/iCloud~md~obsidian/Documents/Obsidian Vault 2023/Keynote/QuickTips.md (instead of http or file://) but there might be some special things to consider - I need to check when I’m on my computer

Thanks SO much.

Thanks. What I want is to float the text without Obsidian being open.

Just fyi here's the code I'm trying that's not working.

<head>
<!-- Lightweight client-side loader that feature-detects and load polyfills only when necessary -->
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script>

<!-- Load the element definition -->
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script>

<body>
<zero-md src="localfile:///Users/james/Library/Mobile Documents/iCloud~md~obsidian/Documents/Obsidian Vault 2023/Apps/Keynote/Quick Tips.md">

</body>
</head>

I've also tried installing zero-md.min.js on my mac and also adding the script to the .js field in advanced

class t extends HTMLElement{get src(){return this.getAttribute("src")}set src(t){this.reflect("src",t)}get manualRender(){return this.hasAttribute("manual-render")}set manualRender(t){this.reflect("manual-render",t)}reflect(t,e){!1===e?this.removeAttribute(t):this.setAttribute(t,!0===e?"":e)}static get observedAttributes(){return["src"]}attributeChangedCallback(t,e,s){"src"===t&&this.connected&&!this.manualRender&&s!==e&&this.render()}constructor(t){super(),this.version="2.4.0",this.config={markedUrl:"https://cdn.jsdelivr.net/gh/markedjs/marked@4/marked.min.js",prismUrl:[["https://cdn.jsdelivr.net/gh/PrismJS/prism@1/prism.min.js","data-manual"],"https://cdn.jsdelivr.net/gh/PrismJS/prism@1/plugins/autoloader/prism-autoloader.min.js"],cssUrls:["https://cdn.jsdelivr.net/gh/sindresorhus/github-markdown-css@4/github-markdown.min.css","https://cdn.jsdelivr.net/gh/PrismJS/prism@1/themes/prism.min.css"],hostCss:":host{display:block;position:relative;contain:content;}:host([hidden]){display:none;}",...t,...window.ZeroMdConfig},this.cache={},this.root=this.hasAttribute("no-shadow")?this:this.attachShadow({mode:"open"}),this.constructor.ready||(this.constructor.ready=Promise.all([!!window.marked||this.loadScript(this.config.markedUrl),!!window.Prism||this.loadScript(this.config.prismUrl)])),this.clicked=this.clicked.bind(this),this.manualRender||this.render().then((()=>setTimeout((()=>this.goto(location.hash)),250))),this.observer=new MutationObserver((async()=>{this.observeChanges(),this.manualRender||await this.render()})),this.observeChanges()}connectedCallback(){this.connected=!0,this.fire("zero-md-connected",{},{bubbles:!1,composed:!1}),this.waitForReady().then((()=>{this.fire("zero-md-ready")})),this.shadowRoot&&this.shadowRoot.addEventListener("click",this.clicked)}disconnectedCallback(){this.connected=!1,this.shadowRoot&&this.shadowRoot.removeEventListener("click",this.clicked)}waitForReady(){const t=this.connected||new Promise((t=>{this.addEventListener("zero-md-connected",(function e(){this.removeEventListener("zero-md-connected",e),t()}))}));return Promise.all([this.constructor.ready,t])}fire(t,e={},s={bubbles:!0,composed:!0}){e.msg&&console.warn(e.msg),this.dispatchEvent(new CustomEvent(t,{detail:{node:this,...e},...s}))}tick(){return new Promise((t=>requestAnimationFrame(t)))}arrify(t){return t?Array.isArray(t)?t:[t]:[]}onload(t){return new Promise(((e,s)=>{t.onload=e,t.onerror=t=>s(t.path?t.path[0]:t.composedPath()[0])}))}loadScript(t){return Promise.all(this.arrify(t).map((t=>{const[e,...s]=this.arrify(t),r=document.createElement("script");return r.src=e,r.async=!1,s.forEach((t=>r.setAttribute(t,""))),this.onload(document.head.appendChild(r))})))}goto(t){if(t){const e=this.root.getElementById(t.substring(1));e&&e.scrollIntoView()}}clicked(t){if(t.metaKey||t.ctrlKey||t.altKey||t.shiftKey||t.defaultPrevented)return;const e=t.target.closest("a");e&&e.hash&&e.host===location.host&&e.pathname===location.pathname&&this.goto(e.hash)}dedent(t){const e=(t=t.replace(/^\n/,"")).match(/^\s+/);return e?t.replace(new RegExp(`^${e[0]}`,"gm"),""):t}getBaseUrl(t){const e=document.createElement("a");return e.href=t,e.href.substring(0,e.href.lastIndexOf("/")+1)}highlight(t){return new Promise((e=>{t.querySelectorAll('pre>code:not([class*="language-"])').forEach((t=>{const e=t.innerText.match(/^\s*</)?"markup":t.innerText.match(/^\s*(\$|#)/)?"bash":"js";t.classList.add(`language-${e}`)}));try{window.Prism.highlightAllUnder(t,!0,e())}catch{window.Prism.highlightAllUnder(t),e()}}))}makeNode(t){const e=document.createElement("template");return e.innerHTML=t,e.content.firstElementChild}buildStyles(){const t=t=>{const e=this.querySelector(t);return e?e.innerHTML||" ":""},e=this.arrify(this.config.cssUrls);return`<div class="markdown-styles"><style>${this.config.hostCss}</style>${t('template[data-merge="prepend"]')}${t("template:not([data-merge])")||e.reduce(((t,e)=>`${t}<link rel="stylesheet" href="${e}">`),"")}${t('template[data-merge="append"]')}</div>`}async buildMd(t={}){return`<div class="markdown-body${t.classes?this.arrify(t.classes).reduce(((t,e)=>`${t} ${e}`)," "):""}">${await(async()=>{if(!this.src)return"";const e=await fetch(this.src);if(e.ok){const s=await e.text();return window.marked.parse(s,{baseUrl:this.getBaseUrl(this.src),...t})}return this.fire("zero-md-error",{msg:`[zero-md] HTTP error ${e.status} while fetching src`,status:e.status,src:this.src}),""})()||(()=>{const e=this.querySelector('script[type="text/markdown"]');if(!e)return"";const s=e.hasAttribute("data-dedent")?this.dedent(e.text):e.text;return window.marked.parse(s,t)})()}</div>`}async stampStyles(t){const e=this.makeNode(t),s=[...e.querySelectorAll('link[rel="stylesheet"]')],r=[...this.root.children].find((t=>t.classList.contains("markdown-styles")));r?r.replaceWith(e):this.root.prepend(e),await Promise.all(s.map((t=>this.onload(t)))).catch((t=>{this.fire("zero-md-error",{msg:"[zero-md] An external stylesheet failed to load",status:void 0,src:t.href})}))}stampBody(t){const e=this.makeNode(t),s=[...this.root.children].find((t=>t.classList.contains("markdown-body")));return s?s.replaceWith(e):this.root.append(e),e}observeChanges(){this.observer.observe(this,{childList:!0}),this.querySelectorAll('template,script[type="text/markdown"]').forEach((t=>{this.observer.observe(t.content||t,{childList:!0,subtree:!0,attributes:!0,characterData:!0})}))}async render(t={}){await this.waitForReady();const e={},s=this.buildMd(t),r=this.buildStyles();r!==this.cache.styles&&(this.cache.styles=r,await this.stampStyles(r),e.styles=!0,await this.tick());const i=await s;if(i!==this.cache.body){this.cache.body=i;const t=this.stampBody(i);e.body=!0,await this.highlight(t)}this.fire("zero-md-rendered",{stamped:e})}}customElements.define("zero-md",t);export{t as ZeroMd};
//# sourceMappingURL=zero-md.min.js.map

Ohh I didn't set a proper http status code when loading a local file. However zero-md expects a "ok" code and explicitly checks for it.

This is fixed in 4.028 alpha, your code should now work.

Working now :slight_smile:

I can't seem to get it to pick up my style sheet.
When I do it inline it works.


<head>

<!-- Lightweight client-side loader that feature-detects and load polyfills only when necessary -->

<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script>

<!-- Load the element definition -->

<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script>

</head>


<zero-md src="localfile:///Users/james/Library/Mobile Documents/iCloud~md~obsidian/Documents/Obsidian Vault 2023/Apps/Keynote/Quick Tips.md">
   <template>
    <!-- The CSS load order is respected -->
    <link rel="stylesheet" href="markdown-styles.css" />
    <style>
      h1 {
        color: blue;
      }
    </style>
    <link rel="stylesheet" href="localfile://Users/james/Desktop/teststyle.css" />
  </template>
</zero-md>

But when I link to a local style sheet it loads it but doesn't use the css.

<head>

<!-- Lightweight client-side loader that feature-detects and load polyfills only when necessary -->

<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script>

<!-- Load the element definition -->

<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script>

</head>

<zero-md src="localfile:///Users/james/Library/Mobile Documents/iCloud~md~obsidian/Documents/Obsidian Vault 2023/Apps/Keynote/Quick Tips.md">
   <template>

    <link rel="stylesheet" href="localfile://Users/james/Desktop/teststyle.css" />
  </template>
</zero-md>

I've tried localfile:/// and localfile:// and also using presetfile:// and putting it in that folder.

The html does seem to be reading it though; just discovering nothing there.

Perhaps I'm putting it in the wrong place but I've tried a lot of different things.

The problem is, you are (maybe accidentally) using zero-md v1 (through jsdeliver), however the template stuff was only added in v2.

In v1 you'd load custom css like this:

<head>

<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script>

<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script>

<body>
<zero-md src="localfile:///Users/andi/Desktop/test.md"  
 css-urls='["localfile:///Users/andi/Desktop/test.css"]'
>

</zero-md>

</body>
</head>

AMAZING!

If I put the css file in /Users/james/Library/Application Support/BetterTouchTool/PresetBundles/MyPresetBundle/

will it be safe? i.e remains there if BTT is updated and be a part of backups I make?

One other thing; any idea how I change the background of the window? I can switch between transparent and white but I can't seem to find the right CSS to style it somewhere in between. I want to round the corners etc which are square when there's no titlebar.

you can just style the body or html element e.g.

body {
background: red;
}

However I don't think it's possible to add rounded corners without some sort of container element. So probably you'd need to put the zero md in a div and then style that div.

No problem.
How often does BTT check the html for updates? I've had to keep restarting BTT to get the updates. Right clicking and then "reload" leaves me with a blank screen. Not sure whether this is BTT or the script though.

I switched to using v2 of zero-md btw.

Thanks.

in the advanced settings you can choose „do not cache“ then it will always reload :slight_smile:

Genius!

Andreas, I've realised I have a problem in that the script doesn't work if I'm not connected to the internet.

I installed the packages onto my mac.
"https://cdn.jsdelivr.net/gh/markedjs/marked@4/marked.min.js" calls lots of other URLs so I'm guessing it's not as simple as simple as putting the JS into the user script in the advanced box?

This is getting complicated; I may need to work out another way around this as it's bound to break in the future and I'll forget how I jury-rigged it.

You can store the JS files locally, especially with v2 that is quite simple. You just need the "dist" folder from zerodevx/zero-md: Ridiculously simple zero-config markdown displayer (github.com)

Here an example how it works for me.

NOTE: You need BTT v4.036 for this. I'm glad you brought up this topic, because it showed me some things I missed when implementing the web view.

<head>
<script type="module" src="file:///Users/andi/Downloads/zero-md-main/dist/zero-md.min.js"></script>
</head>
<body>
<zero-md src="localfile:///Users/andi/Desktop/test.md"  
></zero-md>
</body>
</head>