How adam-p/markdown-here works
1. What this repository is
- Markdown Here is a client-side browser/email extension, not a server app.
- Its core job is to take Markdown typed in an email composer or other rich-text editor, render it to HTML, and later revert it back to Markdown if needed.
2. Top-level runtime boundaries
- The extension is built from src/manifest.json plus browser-specific code under src/chrome/.
- It targets multiple extension hosts: Chrome/Opera, Firefox, and Thunderbird.
- The architecture is split between a long-lived background page/script and an injected content script that runs inside the host page/editor.
3. Host-page integration layer
- src/chrome/contentscript.js is the bridge into Gmail/Hotmail/Yahoo/Google Groups/Thunderbird compose surfaces.
- This layer is responsible for detecting editable regions, reading the user’s selection, and applying conversion results back into the page DOM.
- src/common/content-permissions.js and related logic define which page contexts are eligible for conversion.
4. Extension-level orchestration
- src/chrome/backgroundscript.js coordinates extension-wide behavior such as command handling, menu/button actions, and interaction with the content script.
- background.html is the browser extension runtime container for that logic.
- The background layer is where the extension can manage cross-page state without being tied to one editor instance.
5. Markdown render / revert pipeline
- The main transformation logic lives in src/common/markdown-here.js and src/common/markdown-render.js.
- Input starts as user-authored Markdown in the compose DOM, then is converted to HTML, styled, and inserted back into the editor.
- Reversion is supported by keeping enough structure to map rendered blocks back to original Markdown, with HTML-to-text helpers in mdh-html-to-text.js and jsHtmlToText.js.
6. Parsing and formatting dependencies
- Markdown parsing uses vendored marked.js.
- Syntax highlighting uses vendored highlightjs/highlight.js plus a large set of theme CSS files in src/common/highlightjs/styles/.
- This means rendering is fully client-side and bundled into the extension, with no external rendering service.
7. Shared utility and configuration layer
- src/common/common-logic.js, utils.js, and options-store.js hold reusable logic shared by background, content, and options pages.
- src/common/default.css is the base styling applied to rendered output.
- options-store.js is the persistence boundary for user preferences such as styling, highlighting theme, TeX/math behavior, and hotkeys.
8. Options and user customization surfaces
- src/common/options.html, options.js, and options-iframe.* implement the preferences UI.
- The options surface is separate from the compose-page conversion flow and is used to configure rendering behavior, theme selection, and keyboard shortcuts.
- The README notes browser sync support for Chrome/Firefox, so preference state is designed to be portable across installations of the same browser.
9. UX helpers and secondary dialogs
- src/common/forgot-to-render-prompt.html provides a reminder flow when users try to send without converting.
- src/chrome/upgrade-notification-popup.html/js handles version upgrade messaging.
- These are auxiliary UI paths, not part of the main Markdown transformation pipeline, but they support adoption and error prevention.
10. Internationalization and packaging
- src/_locales/* contains localized strings and description/caption assets for multiple languages.
- utils/build.js packages the extension for release, and the README describes zipping manifest.json, common/, chrome/, and _locales/ for WebExtension distribution.
- store-assets/ holds marketplace graphics/text, which are deployment assets rather than runtime code.
11. Testing structure
- src/common/test/ contains unit tests for the rendering, Markdown conversion, options store, and utility logic.
- test/ is a higher-level test harness entry point.
- The tests focus on the shared conversion logic rather than browser-specific UI, which reflects the architecture: most correctness lives in the common rendering core.
12. Overall data flow
- User types Markdown in a rich editor → content script captures the selection or document region → shared rendering logic converts Markdown to HTML with styling/highlighting → DOM is updated in place → optional revert path converts the rendered block back to Markdown.
- The background script and options store sit beside that flow, providing commands, settings, and extension-wide coordination, but not doing the actual document transformation.
Main entry points: manifest.json Manifest · contentscript.js Content script · backgroundscript.js Background script · markdown-here.js Markdown Here
Components 21
Extension runtime
Browser extension entrypoints and page integration.
- Manifest · Declares extension entrypoints and permissions.
src/manifest.json - Background page · Extension host page for background logic.
src/chrome/background.html - Background script · Coordinates commands, menus, and cross-page state.
src/chrome/backgroundscript.js - Content script · Injects into compose surfaces and applies conversions in-page.
src/chrome/contentscript.js - Page rules · Determines which host pages and editors can be converted.
src/common/content-permissions.js
Markdown pipeline
Shared conversion, parsing, and revert logic.
- Markdown Here · Main conversion entrypoint used by the extension.
src/common/markdown-here.js - Render core · Transforms Markdown into styled HTML for insertion.
src/common/markdown-render.js - Markdown parser · Bundled Markdown parsing dependency.
src/common/marked.js - Syntax highlighter · Bundled code highlighting engine.
src/common/highlightjs/highlight.js - Theme styles · Highlight.js theme CSS collection used by rendered output.
src/common/highlightjs/styles/styles.json - HTML to text · Helpers for mapping rendered HTML back to Markdown text.
src/common/mdh-html-to-text.js - Text helpers · Generic HTML/text conversion helpers used in revert flows.
src/common/jsHtmlToText.js
Preferences and dialogs
Settings and auxiliary user-facing pages.
- Shared logic · Reusable logic shared by background, content, and options pages.
src/common/common-logic.js - Options store · Persists rendering, theme, TeX, and hotkey settings.
src/common/options-store.js - Options page · Main settings page for user customization.
src/common/options.html - Options logic · Drives the preferences interface and sync behavior.
src/common/options.js - Send prompt · Reminder flow for users who forget to render before sending.
src/common/forgot-to-render-prompt.html - Upgrade notice · Version upgrade notification popup.
src/chrome/upgrade-notification-popup.html
Packaging and assets
Locales, build tooling, and release assets.
- Locales · Localized strings and captions for supported languages.
src/_locales - Build tool · Packages the extension for release distribution.
utils/build.js - Test harness · Runs repository tests focused on shared logic.
test/index.html
Connections 24
- Manifest → Background page: loads · Manifest declares the background runtime container.
- Manifest → Content script: injects · Manifest installs the content script into eligible pages.
- Manifest → Options page: opens · Manifest exposes the options page entry.
- Manifest → Locales: localizes · Manifest references localized strings.
- Background page → Background script: hosts · Background page runs the extension orchestration script.
- Background script → Content script: commands · Background script coordinates actions with injected pages.
- Content script → Page rules: checks · Content logic filters eligible editor contexts.
- Content script → Markdown Here: converts · Bridge invokes the shared Markdown conversion flow.
- Markdown Here → Render core: calls · Coordinator delegates transformation work to render core.
- Render core → Markdown parser: parses · Render core uses the vendored Markdown parser.
- Render core → Syntax highlighter: highlights · Render core applies syntax highlighting.
- Syntax highlighter → Theme styles: themes · Highlighter is paired with theme CSS assets.
- Markdown Here → HTML to text: reverts · Rendered blocks can be mapped back to Markdown.
- HTML to text → Text helpers: uses · HTML/text conversion helpers support reversion.
- Options page → Options logic: drives · Options page UI is controlled by its script.
- Options logic → Options store: persists · Preferences are read from and written to storage.
- Options logic → Shared logic: shares · Options logic reuses shared application helpers.
- Content script → Shared logic: shares · Content script reuses shared application helpers.
- Background script → Shared logic: shares · Background script reuses shared application helpers.
- Send prompt → Markdown Here: warns · Reminder dialog steers users back to rendering.
- Upgrade notice → Background script: notifies · Upgrade popup is tied to extension-wide version handling.
- Build tool → Manifest: packages · Build tooling bundles the extension manifest and assets.
- Test harness → Render core: verifies · Test harness exercises shared rendering behavior.
- Test harness → Options store: verifies · Tests cover preference storage behavior.