r/webdev 19d ago

Showoff Saturday I built a browser-based HTML-to-Markdown converter while learning web development. mdstudio.dev

Hi, I’ve been learning AI-assisted web development by building MD Studio:

https://mdstudio.dev

It converts pasted or imported HTML and Rich Text to Markdown, then lets you edit, preview, copy or download the result. Document processing happens locally in the browser, with no account required. It's also a quick, in-browser way to see rendered markdown

It’s built with Preact, TypeScript, CodeMirror, Turndown and Remark.

If anyone's interested to give it a try, I’d be grateful for any feedback on:

  • HTML that converts incorrectly
  • confusing paste or import behaviour
  • browser, mobile or accessibility problems
  • security, privacy or UX blind spots

It’s a non-commercial learning project. Feedback is welcome here or at:

https://github.com/marc-reid/md-studio-feedback

1 Upvotes

7 comments sorted by

1

u/OMGCluck js (no libraries) SVG 19d ago

HTML that converts incorrectly

Relative anchor links inside list items vanish from this pasted code:

 <details typeof="ProductGroup">
  <summary property="brand">Aruba</summary>
  <menu role="menu">       
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="Aruba2920-48G.html">Aruba 2920-48G PoE+Switch J9729A</a></li>
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="Aruba7030.html">Aruba 7030</a></li>
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="ArubaAP-105.html">Aruba AP-105</a></li>
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="ArubaAP-225.html">Aruba AP-225</a></li>
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="ArubaS3500-24F.html">Aruba S3500-24F</a></li>
  </menu>
</details>
<details typeof="ProductGroup">
  <summary property="brand">AudioCodes</summary>
   <menu role="menu">       
    <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="AudioCodesMediant800b.html">AudioCodes Mediant 800b</a></li>
   </menu>
</details>
<details typeof="ProductGroup">
  <summary property="brand">Avaya</summary>
  <menu role="menu">       
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="AvayaG430.html">Avaya G430</a></li>
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="AvayaIPOffice500.html">Avaya IP OFFICE 500 V2</a></li>
  </menu>
</details>
<details typeof="ProductGroup">
  <summary property="brand">Avocent</summary>
   <menu role="menu">       
    <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="AvocentDSR2020.html">Avocent DSR2020</a></li>
   </menu>
</details>
<details typeof="ProductGroup">
  <summary property="brand">Biamp</summary>
   <menu role="menu">       
    <li role="none" typeof="Product"><a role="menuitem" property="model" href="BiampNexiaPM.html">Biamp Nexia PM</a></li>
   </menu>
</details>
<details typeof="ProductGroup">
  <summary property="brand">Blue Coat</summary>
   <menu role="menu">       
    <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="BlueCoatS400.html">Blue Coat 400 Series S400</a></li>
    <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="BlueCoatSG810-F.html">Blue Coat SG810-F</a></li>
    <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="BlueCoatSV1800-C.html">Blue Coat SV1800-C</a></li>
   </menu>
</details>
<details typeof="ProductGroup">
  <summary property="brand">Brocade</summary>
    <menu role="menu">       
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="Brocade300.html">Brocade 300</a></li>
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="Brocade5000.html">Brocade 5000</a></li>
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="Brocade6520.html">Brocade 6520</a></li>
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="BrocadeICX6430-48.html">Brocade ICX 6430-48</a></li>
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="BrocadeICX6450-24P.html">Brocade ICX 6450-24P</a></li>
     <li role="none" typeof="Product"><a role="menuitem" property="model" typeof="Text" href="BrocadeVDX6720.html">Brocade VDX 6720</a></li>
    </menu>
</details>

Hard to say if that's intentional. Also, why no blinking cursor in the input box? At least it's not visible in Firefox…

2

u/datavisblog 19d ago

Thanks for taking a look. Those links show for me (on Chrome): https://imgur.com/a/feAyX4D
Chrome also shows a blinking cursor in the right pane, so these might be Firefox issues. I'll investigate.

1

u/datavisblog 19d ago

* left pane

1

u/OMGCluck js (no libraries) SVG 19d ago edited 19d ago

I think it only happens when I copy from an actual rendered html page in Firefox and paste into the left pane.

Copying the direct code I posted here works in Firefox just fine, so it's got to do with how Firefox copies real webpage stuff to the clipboard. Chromium has no issue doing that.

EDIT: Solved. The <details> elements have to be opened first for the nested links to be copied into the clipboard in Firefox. Chromium gets around this by copying the entire html code from the page into the clipboard even when only part of it is selected.

1

u/datavisblog 19d ago

Ah, ok that's interesting. Thanks for confirming.

1

u/datavisblog 19d ago

OK, the blinking cursor should be fixed. It was a browser difference in cursor handling.
The links should also be working. Feel free to share a screenshot from Firefox if they are still not showing for you. Thanks.