Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Themes
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian

Angle Guard

Yuriy VereshchaginYuriy Vereshchagin36 downloads

Captures and wraps HTML tags in pasted text so they don't break the note's formatting.

Add to Obsidian
  • Overview
  • Scorecard
  • Updates1

Captures and wraps HTML tags in pasted text so they don't break the note's formatting.

Paste a paragraph that contains <name> somewhere in the middle, and everything below it stops rendering. Headings go flat, lists lose their bullets, callouts unroll. The source still holds every character, but the note no longer displays it.

Why it happens

Markdown allows raw HTML, and a tag name can be any identifier — it does not have to be a real element. So <name> is read as an opening HTML tag. The renderer passes it to the browser, the browser opens an element that is never closed, and each sibling after it is pulled into that element.

This is not a fault in Obsidian. It is Markdown following its specification, applied to text that was never meant to be markup.

What it does

On paste, it finds tag-shaped text and moves it where the renderer will not read it as markup. The characters are left unchanged.

Situation Result
A tag inside a sentence Wrapped in a code span: `<name>`
A tag on its own line Placed in a code block
Several lines of HTML The whole run is placed in one code block
A full HTML document One code block, not one edit per tag

It leaves the following alone:

  • A bare < in prose, as in a < b.
  • Anything already inside a code span, code fence, or YAML frontmatter.
  • Autolinks such as <https://example.com> and <[email protected]>.
  • Inline and block math, and wikilinks.
  • Text already escaped by hand as \<name>.
  • Tags on the ignore list — br, img, hr, sup, sub, u, mark, kbd by default.

Where text is copied from

Where the text is copied from changes what lands on the clipboard.

Copying from a Markdown code block inside Obsidian puts the literal <name> on the clipboard as plain text, so it is caught before it is inserted. Copying from a rendered HTML preview — a web page, the reading view, a browser — does not. There, <name> renders as an empty element with no visible text, so the plain-text copy drops it and only the clipboard's HTML flavor still carries it. Obsidian then pastes its own conversion of that HTML, which puts <name> back into the note after the plugin has already looked at the paste.

The plugin handles this by recording the note at paste time and comparing against it once the paste settles, then protecting whatever was inserted. The check retries across a few frames, so it does not depend on the paste being synchronous.

Commands

Command What it does
Protect raw HTML in current note Repairs a note that is already broken
Protect raw HTML in selection The same, for a selection. Also in the right-click menu
Toggle protection on paste Turns protection on or off. Also the status bar icon

Settings

Protect on paste is the master switch, on after install. Ask first turns silent protection into a confirmation prompt. Tell me what was fixed shows a short note after each change. Status bar shortcut adds the </> icon, which is struck through when protection is off.

How much to catch sets the scope. Anything that looks like a tag is the default. Only unknown or unclosed tags leaves correctly paired HTML such as <b>bold</b> as written. Tags to leave alone is your own ignore list. Check pastes from the web covers the HTML-preview case above.

Tags in a sentence chooses between a code span and a backslash escape. Where a line already contains an unpaired backtick, the plugin escapes regardless, because a code span would not survive there. Blocks of HTML puts standalone or multi-line HTML in a code block. Code block label is the language written after the opening fence.

Building from source

npm install
npm run build     # type-checks, then writes main.js
npm run lint      # the official Obsidian plugin review rules
npm test          # 44 unit tests, plus a runtime smoke test
npm run dev       # rebuild on change

src/protect.ts holds the protection logic and has no Obsidian dependency, so it is tested on its own. The plugin bundles no third-party code at runtime; it uses only the Obsidian API.

Acknowledgements

  • Build setup, release workflow, and manifest.json / versions.json conventions follow the Obsidian sample plugin (MIT).
  • Code is checked against eslint-plugin-obsidianmd, the official plugin review rules.
  • The tag grammar in src/protect.ts implements the raw-HTML rules from the CommonMark specification.
  • This plugin was built using Claude Opus 5.0 and Opus 4.8. The problem was first worked through with the help of DeepSeek and Poolside, whose design discussions are recorded in the project notes. The angle-bracket rendering behaviour it addresses was identified in day-to-day use.

License

MIT.

HealthExcellent
ReviewSatisfactory
About
Prevent pasted HTML-like tags from breaking note rendering by wrapping them so the Markdown renderer won't treat them as markup. Convert inline tags to code spans and isolated or multi-line HTML to code blocks, while leaving code, math, autolinks, YAML and already-escaped or common safe tags untouched.
MarkdownEditingHTML
Details
Current version
1.2.0
Last updated
4 weeks ago
Created
4 weeks ago
Updates
1 release
Downloads
36
Compatible with
Obsidian 1.5.0+
Platforms
Desktop, Mobile
License
MIT
Report bugRequest featureReport plugin
Author
Yuriy VereshchaginYuriy Vereshchaginyuriy144
GitHubyuriy144
  1. Community
  2. Plugins
  3. Markdown
  4. Angle Guard

Related plugins

Outliner

Work with your lists like in Workflowy or Roam Research.

Various Complements

Complete words similar to auto-completion in an IDE.

Heading Shifter

Easily Shift and Change Markdown headings.

Shortcuts extender

Use shortcuts for input special symbols without language switching.

Chord Sheets

Work with chord sheets (chords over lyrics or inline) in Live Preview and reading mode: Chord diagrams for guitar, ukulele, mandolin and piano, transpose, autoscroll, and more.

Easy Copy

Easily copy the text within inline code, bold text (and many other formats), or quickly generate an elegant link to a heading or block.

Linter

Format and style your notes. Linter can be used to format YAML tags, aliases, arrays, and metadata; footnotes; headings; spacing; math blocks; regular Markdown contents like list, italics, and bold styles; and more with the use of custom rule options.

LanguageTool Integration

Advanced grammar and spell checking, powered by LanguageTool.

Meta Bind

Make your notes interactive with inline input fields, metadata displays, and buttons.

Advanced Tables

Improved table navigation, formatting, and manipulation.