Notes about Markdown issues and solutions

Last updated on 5 Mar. 2026

Summary

Markdown Code Blocks: Horizontal Scroll Issue on GitHub

The Problem: Code blocks in Markdown don't wrap text—they preserve exact formatting, which is essential for executable code. However, on GitHub's responsive design, long lines in code blocks force horizontal scrolling even on desktop. On mobile, this severely impacts readability. Note that for this case, VSCode Markdown preview may wrap the text and not show horizontal scrollbar.

The Issue with Using Code Blocks for Everything: A common mistake is using code blocks for all code-like content, including example output, markup demonstrations, and non-executable examples. While code blocks provide syntax highlighting, they sacrifice user experience on narrower viewports or even wide viewports if the content has long lines exceeding viewport width.

The Solution: Choose Based on Semantic Intent

Use code blocks when:
  • Displaying executable code that requires exact formatting and indentation
  • Syntax highlighting improves clarity (e.g., python, javascript, html)
  • Readers will copy and execute the code
Use blockquotes for:
  • Example output or pasted text results
  • Markup demonstrations (not meant to execute)
  • Reference content readers will read, not run
  • Content that benefits from natural text wrapping
Implementation Tip

When displaying HTML markup as an example (not executable code), use HTML entities (&lt; for < and &gt; for >) inside blockquotes to escape special characters:

> Next I used my &lt;a href="url"&gt;link text&lt;/a&gt; in the HTML.

This renders cleanly on all platforms—desktop, mobile, and GitHub—without horizontal scrolling.

This horizontal scrollbar problem was faced and then solved in this README file in my bookmarklets GitHub repo (public).

Markdown-viewer Chrome extension

VSCode shows only one markdown file in preview mode. Opening another markdown file (in same VSCode instance) results in the open preview window to show the currently opened markdown file preview. 

Markdown-viewer Chrome extension can be used to view multiple markdown files in separate Chrome tabs.

As per ChatGPT, Markdown-viewer Chrome extension being given access to file URLs is a "small, well-understood risk". The extension's practical reach is:
  • Limited to the files you explicitly open
  • Limited to Markdown files rendered through Chrome
  • Not capable of arbitrary filesystem traversal on its own
For dark mode in Markdown Viewer: Extension Options -> Content Theme -> GITHUB-DARK

Auto-converting plain text sections to markdown

In Gemini, the copy button for user messages seems to only put plain text (not markdown) on the clipboard. There may be other cases when plain text sections have to be converted as markdown.

The clipboard2markdown utility can be used to do this auto-conversion. It seems to parse the content to correctly identify paragraph breaks, escapes special characters that might be misinterpreted as Markdown directives, and provides a clean Markdown output. 

==================================================================
==================================================================

Details

12 Feb 2026
Given below are parts of an exchange today between me and Claude AI (Cl) via GitHub CoPilot. The context for the discussion is this README file in my bookmarklets GitHub repo (public).

Me: The selected portion of the README [which had a code block] renders well in VSCode preview without a horizontal scrollbar. But in GitHub, a horizontal scrollbar is shown for it with only one line of display which the user has to horizontally scroll. Pl. comment and any solutions are welcome.

Cl: Good observation! The issue is that code blocks in Markdown don't wrap text—they preserve exact formatting, which includes very long lines. ...

Me: ...  Just curious why does VSCode preview not show me such a horizontal scrollbar and single line display for this section?

[I am not convinced Cl's answer was right and so am skipping it.]

[Cl suggested dropping code block (and using blockquote).]

Me: I have dropped the code block. Now see the selected text. This was an HTML code block earlier. I need(ed) to escape the <a> and </a> tags individually using \. VSCode preview renders it correctly. Will GitHub handle this correctly? Is \ the right escape character for this purpose?

Cl: Good question! Actually, backslash is NOT the ideal escape character for HTML tags in this context. Here's why:

The issue:
  • In Markdown, \ escapes Markdown special characters (like *, _, [, etc.), not HTML
  • Backslashes before HTML tags like \<a> may render inconsistently across different renderers
  • VSCode preview might strip the backslash and display the tag, but GitHub might render it literally or differently
The correct approach: HTML entities

Use &lt; for < and &gt; for >:

> Next I wanted to generate a TOC for the anchor linked sections created above. For that I used my &lt;a href="https://raviswdev.blogspot.com/2025/09/vscode-extension-to-auto-add-id.html"&gt;auto-header-ids-toc VSCode extension&lt;/a&gt;. I had to add h3 to the extension's settings: auto-header-ids-toc.headersToProcess.

Why this is better:
  • HTML entities are universally recognized across all Markdown renderers (VSCode, GitHub, others)
  • They render consistently as literal < and > characters everywhere
  • This is the semantic HTML standard for displaying literal HTML code
...

Me: That fixed it on GitHub. Even for mobile width window all content is readable without need for horizontal scrolling. Hmm. Quite a significant UI improvement. But I am disappointed that such code blocks are not handled properly on GitHub. I expected them to be handled. Pl. comment and feel free to be critical of my views.

Cl: Your frustration is valid, but I'd also defend GitHub's approach—with caveats:

Why code blocks don't wrap on GitHub:

  • Intentional design decision: Code needs to preserve exact formatting. Indentation, spacing, and line alignment are semantic in code. Wrapping breaks that.
  • It's standard behavior: Most code editors and platforms (VS Code, GitHub, Stack Overflow, etc.) follow this principle because code must be read exactly as written.
But your point is fair:
  • The problem: GitHub doesn't distinguish between actual code and text output shown as code
  • When you display example command output or pasted text, the non-wrapping constraint is overly restrictive
  • A middle ground would be helpful: maybe a text or output code fence that wraps, separate from code fences that don't
Reality check:
  • For your use case (showing what pasted output looks like), code blocks were never the right semantic choice anyway
  • Blockquotes are actually MORE correct—they represent quoted/example content, which is exactly what your output is
  • So the "fix" wasn't just a workaround; it's semantically better Markdown
My take:
GitHub could be more flexible with code block rendering (optional wrapping toggle), but their conservative approach prevents accidentally breaking code display. Your solution using blockquotes is genuinely better—it solves both the GitHub UX problem and uses more appropriate Markdown semantics. Sometimes constraints push us toward better solutions.

Me: Oh! Good point. So the learning for me is that for this case I should have used HTML entities to escape HTML instead of using an HTML code block for it - which BTW was provided by another AI tool. Did I understand you correctly.

Cl: Not quite—let me clarify the nuance:

The learning is more specific:

When you want to show HTML markup as example/reference content (not actual code to execute), you have two approaches:
  1. HTML code block – Will preserve formatting perfectly but causes GitHub's scrolling issue
  2. HTML entities in blockquotes – Displays the markup as readable text, wraps naturally, and is semantically correct for "example content"
The key distinction:
  • Use code blocks for actual executable code that needs exact formatting preserved
  • Use HTML entities + blockquotes/regular text when you're showing markup as an example or reference—the user will read it, not run it
Why the other AI tool suggested a code block:
They probably categorized it as "code" rather than "example markup to display." That's a reasonable assumption, but contextually, since you're demonstrating what HTML looks like rather than providing code to use, blockquotes are more appropriate.

So the real learning:
Choose your Markdown format based on semantic intent, not just "this is HTML so it goes in a code block." If you're showing an example for readers to understand, blockquotes + entities work great. If you're sharing executable code, code blocks are essential.

This applies beyond HTML—same principle for JSON examples, configuration file snippets, etc.

Me: Got it. code block is suitable for executable code.
BTW what does html in ```html do? Why not simply use ``` 

Cl: Great question! The html part enables syntax highlighting.
...

Me: Hmm. so the other AI tool may have chosen to use a code block for the HTML markup in my README due to the syntax highlighting feature it provides. Am I on right track?

Cl: Yes, you're on the right track! The other AI tool probably reasoned:
  • "This is HTML markup" → should go in a code block
  • "HTML code block with syntax highlighting" → easier to read the markup structure
  • Result: colored tags, attributes, proper formatting
That logic is sound, but it missed the trade-off:

What they optimized for:
  • Syntax highlighting and visual structure clarity
What they didn't account for:
  • GitHub's narrow viewport causing horizontal scrolling on mobile/responsive views
  • That this was "example output" not "executable code"
  • The user experience degradation
The lesson:
When choosing Markdown formats, consider the complete user experience, not just one feature. Syntax highlighting is nice, but if it breaks readability on mobile or other contexts, it's not worth it.

In this case, blockquotes sacrificed highlighting but gained:
  • Proper wrapping on all devices
  • Semantic clarity (this is example content, not code to run)
  • Better mobile experience
So the other tool made a reasonable but incomplete decision. You caught the problem and chose the better solution. This kind of iterative improvement based on real-world feedback (like testing on GitHub) is exactly how documentation gets better.

Me: Please give me a short note explaining the issue we discussed above (code block causing horizontal scroll) and the solution. Also include your advice given earlier in this context. I will share this note on my blog post for future reference for myself (and perhaps may be useful to others too).

Cl: 

Markdown Code Blocks vs. Blockquotes: When to Use Each

The Problem

Code blocks in Markdown don't wrap text—they preserve exact formatting, which is essential for executable code. However, on GitHub's responsive design, long lines in code blocks force horizontal scrolling even on desktop. On mobile, this severely impacts readability.

The Issue with Using Code Blocks for Everything

A common mistake is using code blocks for all code-like content, including example output, markup demonstrations, and non-executable examples. While code blocks provide syntax highlighting, they sacrifice user experience on narrower viewports.

The Solution: Choose Based on Semantic Intent

Use code blocks when:
  • Displaying executable code that requires exact formatting and indentation
  • Syntax highlighting improves clarity (e.g., python, javascript, html)
  • Readers will copy and execute the code
Use blockquotes for:
  • Example output or pasted text results
  • Markup demonstrations (not meant to execute)
  • Reference content readers will read, not run
  • Content that benefits from natural text wrapping
Implementation Tip

When displaying HTML markup as an example (not executable code), use HTML entities (&lt; for < and &gt; for >) inside blockquotes:

> Next I used my &lt;a href="url"&gt;link text&lt;/a&gt; in the HTML.

This renders cleanly on all platforms—desktop, mobile, and GitHub—without horizontal scrolling.

Key Learning

Choose your Markdown format based on semantic purpose, not just the type of content. This ensures better user experience across all viewing contexts

...
[For the below session, CoPilot changed the AI tool to GPT (5 mini) (GP).]
Me: An advantage of code block is that one does not need to escape special characters associated with that type of code block. So for HTML code block, we don't need to escape < or >. Am I right?

GP: Yes — within a fenced code block (html ...  or just ```) you do not need to escape < or >; the fence makes the contents literal (shown as code, not parsed as HTML), so tags are displayed, not interpreted.

Caveats:
  • Fenced code blocks preserve formatting and typically do not wrap (hence GitHub’s horizontal scrollbar behavior).
  • Outside code blocks (plain paragraphs, blockquotes, or inline text), raw </> may be treated as HTML by the renderer — use &lt;/&gt; there to show literal tags.
  • Inline code (`...`) also shows </> literally without escaping.or just ```) you do not need to escape < or >; the fence makes the contents literal (shown as code, not parsed as HTML), so tags are displayed, not interpreted.
Me: Hmm. I thought ... was used to hightlight words and phrases as that's how at least one AI tool uses it for generated Markdown content.

GP: You're right that some AI tools use backticks like inline "highlights," but technically:
  • Single backticks (`...`) create an inline code span — monospace, code semantics, and typically a gray background. Use it for code, filenames, commands, or literal tokens (e.g., run(), README.md).
  • Triple backticks (  ) create fenced code blocks — use for multi-line code with optional syntax highlighting (html, js).
  • For emphasis/visual highlighting of ordinary text use *italic* or **bold**, not backticks.
Notes:
  • Inline code is rendered differently (semantically and visually) from emphasis; using it for non-code is misleading to readers.
  • To include a backtick inside inline code, wrap with a longer fence, e.g.   text   [in earlier words, looks like some special characters were omitted] or use <code>...</code>.
Example:
  • Good: npm install (command), src/index.js (filename)
  • Emphasis: Important or note (not Important)) create fenced code blocks — use for multi-line code with optional syntax highlighting (html, js).
  • For emphasis/visual highlighting of ordinary text use *italic* or **bold**, not backticks.
Me: Oh! I need to correct myself. I thought a filename is not code. So I used such examples to say that some AI tools use inline code for highlighting.

GP: Yes — that's fine and common. Inline code spans (...) are appropriate for filenames, commands, flags, short code tokens, and literal values.

Quick guidance:
  • Use inline code for: README.md, npm install, --help, run().
  • Use bold/italic for emphasis or prose (not inline code).
  • Don’t overuse inline code for long sentences or non-literal phrasing — it signals "literal/technical" to readers.
=======================================
15 Feb. 2026

[About Markdown-viewer Chrome extension being given access to file URLs]
Me: https://chromewebstore.google.com/detail/markdown-viewer/ckkdlimhmcjmikdlpkmbgfkaikojcbjk - I find this to be useful to view MARKDOWN files. I need to give it access to file URLs (for markdown files on my PC). Is that OK?

ChatGPT (CG): Short answer: Yes, it’s generally OK — with a small, well-understood risk.

Here’s a precise, security-focused explanation so you can decide comfortably.


What “access to file URLs” actually means

When you enable “Allow access to file URLs” for a Chrome extension, you are allowing that extension to:

  • Read only the local files you open through it (e.g., .md files you double-click or open in Chrome)

  • Process the contents of those files inside the browser

It does not mean:

  • Blanket access to all files on your disk

  • Background scanning of your filesystem

  • Arbitrary uploads of files without user action

Chrome’s security model still applies.


About Markdown Viewer specifically

Markdown Viewer is a long-standing, widely used extension whose sole purpose is:

  • Rendering Markdown to HTML

  • Locally, in the browser

Key points that reduce risk:

  • The functionality is purely client-side

  • No account, login, or cloud sync is involved

  • The extension only activates when you open a Markdown file

For viewing local Markdown notes or documentation, this is a very common and accepted setup.


Realistic risk assessment

Low risk if:

  • You are opening your own Markdown files

  • The files contain documentation, notes, or blog drafts

  • You trust the Chrome Web Store vetting process

Slight risk if:

  • You open highly sensitive Markdown files (passwords, private keys, secrets)

  • The extension were to become compromised in a future update (rare, but not impossible)

This risk exists for any file-handling extension, not just this one.


Best-practice recommendation (simple)

  • ✅ It’s fine to enable file URL access

  • ❌ Don’t open files containing secrets (API keys, passwords)

  • 🔁 If you stop using it, disable or remove the extension

  • 🛡️ For ultra-sensitive content, use a local Markdown viewer/editor instead


Bottom line

Yes — enabling file URL access for this Markdown Viewer extension is reasonable and safe for normal Markdown usage.
You are making a conscious, limited permission grant, not opening up your entire system.

If you want, I can also suggest:

  • A zero-extension workflow for Markdown preview, or

  • A comparison with VS Code’s built-in Markdown preview from a security perspective.

Me: I will be using it to view non-sensitive MD files (no secrets).
What you said:
It does not mean:
Blanket access to all files on your disk
Background scanning of your filesystem
Arbitrary uploads of files without user action
-------------
That is what I was looking for. With the above, even if the extension becomes malicious in future, it cannot be beyond the Markdown files on my PC that I choose to open in Chrome. Am I on right track here?

CG: Yes — you are on exactly the right track, with one small but important clarification.

Your understanding is essentially correct

Given that:

  • You will open only non-sensitive Markdown files

  • You open them explicitly in Chrome

  • You granted “Allow access to file URLs” only for this purpose

Then even if the extension were to become malicious in the future, its practical reach would be:

  • Limited to the files you explicitly open

  • Limited to Markdown files rendered through Chrome

  • Not capable of arbitrary filesystem traversal on its own

So your core conclusion is sound.


The small but important nuance (for completeness)

Chrome extensions cannot independently crawl your disk.

However, technically:

  • Once a file is opened, the extension can read that file’s contents

  • From that file, it could follow links you click (e.g., relative links to other local .md files)

But this still requires your interaction:

  • You must open or click the file/link

  • It cannot silently expand scope in the background

So this does not change your risk model in any meaningful way for non-sensitive files.


Why Chrome’s model protects you here

Chrome enforces:

  • User-initiated file access

  • Origin isolation for file:// URLs

  • Permission-scoped extension access

An extension does not get:

  • A list of your files

  • Directory enumeration privileges

  • Background file read permissions


Bottom line (very clearly)

Yes. Your understanding is correct.
Even in a worst-case scenario where the extension later becomes malicious, it can only act on the Markdown files you intentionally open in Chrome, and cannot go beyond that scope without further user action or additional permissions.

For your stated use case — non-sensitive Markdown viewing — this is a reasonable and low-risk choice.

If you ever want to tighten it further:

  • Disable the extension when not in use, or

  • Use a local viewer/editor instead

But based on what you described, you’re making a well-informed decision.

Me: One issue I faced with VSCode for a project with multiple markdown files that I wanted to preview simultaneously, is that preview always showed only one file.

CG: Yes — that observation is accurate, and it comes from how Visual Studio Code is designed.

Let me explain why this happens and what your real options are.


Why VS Code shows only one Markdown preview (by default)

VS Code’s Markdown preview is editor-bound, not document-bound.

By default:

  • Open Preview / Open Preview to the Side reuses the same preview editor

  • When you switch to another .md file and open preview again:

    • The existing preview tab is replaced

    • You don’t get a second independent preview

This is intentional behavior, not a bug.

VS Code treats Markdown preview like:

  • “a rendered view of the active editor

  • not like separate browser tabs


What does work (but feels limited)

You can:

  • Open one file

  • Open Preview to the Side

  • Split the editor layout

But the moment you preview another Markdown file, the preview pane gets reused.

So your experience of “preview always showed only one file” is exactly correct.


Why this matters for your use case

Your use case is:

  • Multiple Markdown files

  • Wanting to see them rendered simultaneously

  • Likely for documentation or note comparison

VS Code is optimized for editing, not multi-document rendered viewing.

That’s why it feels constraining here.


Why your Chrome Markdown Viewer workaround makes sense

A browser-based Markdown viewer:

  • Treats each .md file as a separate document

  • Allows:

    • Multiple tabs

    • Side-by-side windows

    • Independent scroll positions

This aligns much better with:

  • Reading

  • Comparing

  • Reviewing multiple Markdown files at once

So your choice is not just convenient — it’s architecturally appropriate.


Are there workarounds in VS Code?

Yes, but they’re clunky:

  • Extensions that force separate preview instances

  • Manually duplicating preview editors (unstable)

  • Using static-site generators just to preview content

None are as simple or reliable as browser tabs.


Bottom line

Your issue is real, expected, and rooted in VS Code’s design.
VS Code prioritizes editing workflows; browsers (with Markdown viewers) are better for multi-file rendered viewing.

Given your non-sensitive Markdown use case, your current approach is technically justified and practical.

If you want, I can also:

  • Suggest a zero-extension VS Code workflow that partially mitigates this, or

  • Compare VS Code vs browser Markdown viewing purely from a productivity angle.

=================

For dark mode in Markdown Viewer: Extension Options -> Content Theme -> GITHUB-DARK
  • By default the Content Theme was GITHUB which was showing markdown file content in light mode, despite Windows (OS) and Chrome being in dark mode and even while Dark Reader extension was On. Neither did chrome://flags -> Enable Force Dark Mode for Web Contents, change the content to dark mode.
==================================================
5 Mar 2026

Gemini (Gem) chat: Copying User Messages as Markdown

Me: I am converting parts of one of our previous chats into a .md (markdown) file in VSCode. Your responses through Copy button get converted properly to markdown. But Copy button for my messages gives me plain text and not markdown. I want to get markdown for my messages too. Is there some way for that

[I had a long exchange and tried lot of stuff including some of Gem's suggestions. Essentially I needed line breaks in my messages in the chat to be recognized and converted as line separators in markdown. Dashed line to be separated from earlier line content so that it is not interpreted as a markdown directive and so on. I wanted all that to be done automatically. That would save me time from doing it manually which is what I had been doing for adding my messages in a Gemini chat to a markdown file (in VSCode).

Finally I got a solution. Given below is Gemini's summary of these exchanges slightly edited by me.]

The Quest for Clean Markdown: Converting Chat Logs

Moving conversation logs from a web chat interface into a local development environment like VS Code can be surprisingly difficult. While AI responses often have a "Copy" button that preserves Markdown formatting, user-sent messages are frequently treated as raw, plain text. This results in collapsed line breaks and broken formatting when pasted directly into a .md file.

The Trials

To solve this, I experimented with several "automatic" solutions within VS Code:

  • Markdown All in One: A powerful suite for general editing, but it doesn't automatically "intercept" and reformat plain text during a standard paste.
  • Paste as Markdown Extensions: I tested several extensions designed to convert clipboard data on the fly. While promising, they often required complex configurations, relied on specific metadata from the browser that wasn't always present, or had inconsistent "Paste As" UI behaviors that were prone to breaking after setting changes.
  • VS Code Native "Paste As": While VS Code has built-in support for selecting paste formats, it often fails to recognize the intended structure of a plain-text block copied from a chat bubble.
  • At times the 'VS Code Paste Widget' (blue icon with boxes and arrow) occasionally appeared to offer formatting choices. But it would not regularly appear for user messages copy. 
I also tried some online utils:
  • StackEdit is a great tool, but it doesn't "auto-convert" plain text into Markdown structure (like adding headings or bolding) because it's primarily an editor, not a parser.
  • https://sitegpt.ai/tools/convert-paste-to-markdown adds some (possibly AI generated) stuff over and above the basic content I tried to convert. I did not want that.
  • Then I got the solution given below.

The Solution: A Dedicated Parser

The most reliable and "cleanest" solution proved to be a dedicated web-based utility: clipboard2markdown.

By using this as a "cleaning station," the raw text is forced through a parser that correctly identifies carriage returns (CR), escapes special characters, and preserves the intended paragraph structure. This eliminates the manual labor of re-formatting lines and ensures that the final document in VS Code is clean, professional, and ready for publishing.

Comments

Archive

Show more